Browse Source

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

yonge 4 years ago
parent
commit
04570f5046
100 changed files with 5148 additions and 1403 deletions
  1. 22 21
      mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/config/ResourceServerConfig.java
  2. 111 92
      mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/dal/dao/SysUserDao.java
  3. 110 90
      mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/service/SysUserService.java
  4. 176 142
      mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/service/impl/SysUserServiceImpl.java
  5. 12 0
      mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/web/controller/UserController.java
  6. 13 0
      mec-auth/mec-auth-server/src/main/resources/config/mybatis/SysUserMapper.xml
  7. 2 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CloudCoachPaymentProgramDao.java
  8. 28 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/ImLiveBroadcastRoomDao.java
  9. 23 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/ImLiveBroadcastRoomDataDao.java
  10. 26 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/ImLiveBroadcastRoomMemberDao.java
  11. 20 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/ImLiveRoomVideoDao.java
  12. 28 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/MusicGroupDao.java
  13. 14 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/MusicGroupPaymentStudentCourseDetailDao.java
  14. 7 4
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/QuestionnaireUserResultDao.java
  15. 11 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentCloudCoachPaymentDetailsDao.java
  16. 4 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TenantPreJoinDao.java
  17. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/ClassGroup4MixDto.java
  18. 116 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/HasFreeCourseTimesDto.java
  19. 165 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/ImLiveBroadcastRoomDto.java
  20. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/MusicGroupPaymentBaseCalender.java
  21. 13 4
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/TenantPreJoinDto.java
  22. 90 3
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/CloudCoachPaymentProgram.java
  23. 217 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/ImLiveBroadcastRoom.java
  24. 119 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/ImLiveBroadcastRoomData.java
  25. 97 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/ImLiveBroadcastRoomMember.java
  26. 121 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/ImLiveRoomVideo.java
  27. 42 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/QuestionnaireTopic.java
  28. 13 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/TenantPreJoin.java
  29. 1 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/ExportEnum.java
  30. 2 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/IndexErrorType.java
  31. 1 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/MessageTypeEnum.java
  32. 19 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/CloudCoachPaymentProgramQueryInfo.java
  33. 3 4
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/MusicGroupQueryInfo.java
  34. 101 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/vo/ImLiveBroadcastRoomDetailVo.java
  35. 102 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/vo/ImLiveBroadcastRoomMemberVo.java
  36. 249 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/vo/ImLiveBroadcastRoomVo.java
  37. 100 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/vo/RoomUserInfoVo.java
  38. 18 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/vo/TenantPreJoinVo.java
  39. 7 0
      mec-biz/src/main/java/com/ym/mec/biz/service/CloudCoachPaymentProgramService.java
  40. 18 0
      mec-biz/src/main/java/com/ym/mec/biz/service/ImLiveBroadcastRoomDataService.java
  41. 33 0
      mec-biz/src/main/java/com/ym/mec/biz/service/ImLiveBroadcastRoomMemberService.java
  42. 67 0
      mec-biz/src/main/java/com/ym/mec/biz/service/ImLiveBroadcastRoomService.java
  43. 21 0
      mec-biz/src/main/java/com/ym/mec/biz/service/ImLiveRoomVideoService.java
  44. 3 20
      mec-biz/src/main/java/com/ym/mec/biz/service/MusicGroupPaymentCalenderDetailService.java
  45. 22 17
      mec-biz/src/main/java/com/ym/mec/biz/service/MusicGroupPaymentCalenderService.java
  46. 2 0
      mec-biz/src/main/java/com/ym/mec/biz/service/OrganizationService.java
  47. 10 40
      mec-biz/src/main/java/com/ym/mec/biz/service/QuestionnaireUserResultService.java
  48. 2 1
      mec-biz/src/main/java/com/ym/mec/biz/service/TenantPreJoinService.java
  49. 20 7
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ClassGroupServiceImpl.java
  50. 79 5
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/CloudCoachPaymentProgramServiceImpl.java
  51. 2 25
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ExportServiceImpl.java
  52. 28 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ImLiveBroadcastRoomDataServiceImpl.java
  53. 62 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ImLiveBroadcastRoomMemberServiceImpl.java
  54. 980 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ImLiveBroadcastRoomServiceImpl.java
  55. 44 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ImLiveRoomVideoServiceImpl.java
  56. 27 2
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/IndexBaseMonthDataServiceImpl.java
  57. 3 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/MemberRankSettingServiceImpl.java
  58. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/MusicGroupPaymentCalenderCourseSettingsServiceImpl.java
  59. 23 297
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/MusicGroupPaymentCalenderDetailServiceImpl.java
  60. 52 105
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/MusicGroupPaymentCalenderServiceImpl.java
  61. 8 2
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/MusicGroupQuestionnaireServiceImpl.java
  62. 19 6
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/MusicGroupServiceImpl.java
  63. 25 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/OrganizationServiceImpl.java
  64. 5 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/QuestionnaireTopicServiceImpl.java
  65. 80 154
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/QuestionnaireUserResultServiceImpl.java
  66. 6 1
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ReplacementInstrumentActivityServiceImpl.java
  67. 0 4
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentAttendanceServiceImpl.java
  68. 5 17
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/TenantPreJoinServiceImpl.java
  69. 50 15
      mec-biz/src/main/resources/config/mybatis/CloudCoachPaymentProgramMapper.xml
  70. 45 0
      mec-biz/src/main/resources/config/mybatis/ImLiveBroadcastRoomDataMapper.xml
  71. 92 0
      mec-biz/src/main/resources/config/mybatis/ImLiveBroadcastRoomMapper.xml
  72. 50 0
      mec-biz/src/main/resources/config/mybatis/ImLiveBroadcastRoomMemberMapper.xml
  73. 31 0
      mec-biz/src/main/resources/config/mybatis/ImLiveRoomVideoMapper.xml
  74. 64 0
      mec-biz/src/main/resources/config/mybatis/MusicGroupMapper.xml
  75. 1 1
      mec-biz/src/main/resources/config/mybatis/MusicGroupPaymentCalenderDetailMapper.xml
  76. 14 0
      mec-biz/src/main/resources/config/mybatis/MusicGroupPaymentStudentCourseDetailMapper.xml
  77. 0 2
      mec-biz/src/main/resources/config/mybatis/OrganizationCourseUnitPriceSettingsMapper.xml
  78. 22 3
      mec-biz/src/main/resources/config/mybatis/QuestionnaireTopicMapper.xml
  79. 39 14
      mec-biz/src/main/resources/config/mybatis/QuestionnaireUserResultMapper.xml
  80. 9 2
      mec-biz/src/main/resources/config/mybatis/StudentCloudCoachPaymentDetailsMapper.xml
  81. 2 2
      mec-biz/src/main/resources/config/mybatis/StudentPaymentRouteOrderMapper.xml
  82. 55 0
      mec-biz/src/main/resources/config/mybatis/TenantPreJoinMapper.xml
  83. 160 109
      mec-client-api/src/main/java/com/ym/mec/im/ImFeignService.java
  84. 26 5
      mec-client-api/src/main/java/com/ym/mec/im/fallback/ImFeignServiceFallback.java
  85. 15 4
      mec-client-api/src/main/java/com/ym/mec/task/TaskRemoteService.java
  86. 10 0
      mec-client-api/src/main/java/com/ym/mec/task/fallback/TaskRemoteServiceFallback.java
  87. 1 1
      mec-common/common-core/src/main/java/com/ym/mec/common/entity/BaseMessage.java
  88. 67 0
      mec-common/common-core/src/main/java/com/ym/mec/common/entity/ImRoomMessage.java
  89. 70 0
      mec-common/common-core/src/main/java/com/ym/mec/common/entity/ImUserState.java
  90. 117 115
      mec-im/pom.xml
  91. 1 0
      mec-im/src/main/java/com/ym/config/IMProperties.java
  92. 6 4
      mec-im/src/main/java/com/ym/config/ResourceServerConfig.java
  93. 1 1
      mec-im/src/main/java/com/ym/config/WebMvcConfig.java
  94. 65 0
      mec-im/src/main/java/com/ym/controller/LiveRoomController.java
  95. 26 6
      mec-im/src/main/java/com/ym/controller/UserController.java
  96. 1 1
      mec-im/src/main/java/com/ym/enums/ActionEnum.java
  97. 1 1
      mec-im/src/main/java/com/ym/enums/DeviceTypeEnum.java
  98. 1 1
      mec-im/src/main/java/com/ym/enums/RoleEnum.java
  99. 93 33
      mec-im/src/main/java/com/ym/http/HttpHelper.java
  100. 131 17
      mec-im/src/main/java/com/ym/mec/im/IMHelper.java

+ 22 - 21
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/config/ResourceServerConfig.java

@@ -1,5 +1,7 @@
 package com.ym.mec.auth.config;
 
+import com.ym.mec.common.security.BaseAccessDeniedHandler;
+import com.ym.mec.common.security.BaseAuthenticationEntryPoint;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
@@ -7,9 +9,6 @@ import org.springframework.security.oauth2.config.annotation.web.configuration.E
 import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
 import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
 
-import com.ym.mec.common.security.BaseAccessDeniedHandler;
-import com.ym.mec.common.security.BaseAuthenticationEntryPoint;
-
 /**
  * 资源服务器配置
  */
@@ -17,23 +16,25 @@ import com.ym.mec.common.security.BaseAuthenticationEntryPoint;
 @EnableResourceServer
 public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
 
-	@Autowired
-	private BaseAccessDeniedHandler baseAccessDeniedHandler;
-
-	@Autowired
-	private BaseAuthenticationEntryPoint baseAuthenticationEntryPoint;
-
-	@Override
-	public void configure(HttpSecurity http) throws Exception {
-		http.csrf().disable().exceptionHandling().accessDeniedHandler(baseAccessDeniedHandler).authenticationEntryPoint(baseAuthenticationEntryPoint).and()
-				.authorizeRequests().antMatchers("/task/**", "/user/updatePassword", "/user/noAuth/queryUserByPhone",
-				"/user/queryUserByPhone", "/user/add", "/user/queryUserById/*","/queryUserInfo").hasIpAddress("0.0.0.0/0")
-				.anyRequest().authenticated().and().httpBasic();
-	}
-
-	@Override
-	public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
-		resources.authenticationEntryPoint(baseAuthenticationEntryPoint).accessDeniedHandler(baseAccessDeniedHandler);
-	}
+    @Autowired
+    private BaseAccessDeniedHandler baseAccessDeniedHandler;
+
+    @Autowired
+    private BaseAuthenticationEntryPoint baseAuthenticationEntryPoint;
+
+    @Override
+    public void configure(HttpSecurity http) throws Exception {
+        http.csrf().disable().exceptionHandling().accessDeniedHandler(baseAccessDeniedHandler).authenticationEntryPoint(baseAuthenticationEntryPoint).and()
+                .authorizeRequests().antMatchers(
+                        "/task/**", "/user/updatePassword", "/user/noAuth/queryUserByPhone",
+                        "/user/queryUserByPhone", "/user/queryClient", "/user/add", "/user/queryUserById/*",
+                        "/queryUserInfo").hasIpAddress("0.0.0.0/0")
+                .anyRequest().authenticated().and().httpBasic();
+    }
+
+    @Override
+    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
+        resources.authenticationEntryPoint(baseAuthenticationEntryPoint).accessDeniedHandler(baseAccessDeniedHandler);
+    }
 
 }

+ 111 - 92
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/dal/dao/SysUserDao.java

@@ -1,104 +1,123 @@
 package com.ym.mec.auth.dal.dao;
 
-import java.util.List;
-
-import org.apache.ibatis.annotations.Param;
-
 import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.auth.api.enums.UserLockFlag;
 import com.ym.mec.common.dal.BaseDAO;
 import com.ym.mec.common.entity.ImUserModel;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 public interface SysUserDao extends BaseDAO<Integer, SysUser> {
 
-	/**
-	 * 根据用户名查询对象
-	 * @param username
-	 * @return
-	 */
-	SysUser queryByUsername(String username);
-
-	/**
-	 * 根据手机号查询对象
-	 * @param phone
-	 * @return
-	 */
-	SysUser queryByPhone(String phone);
-
-	/**
-	 * 根据手机号查询对象
-	 * @param phone
-	 * @return
-	 */
-	SysUser queryLockByPhone(String phone);
-
-	/**
-	 * 根据手机号查询对象
-	 * @param phone
-	 * @return
-	 */
-	SysUser queryByPhoneAndClient(@Param("phone") String phone, @Param("client") String client);
-
-	/**
-	 * 修改密码
-	 * @param mobile
-	 * @param password
-	 */
-	void updatePassword(@Param("mobile") String mobile, @Param("password") String password);
-
-	/**
-	 * 获取用户基本信息
-	 * @param userId
-	 * @return
-	 */
-	ImUserModel getBasic(Integer userId);
-
-	/**
-	 * 根据状态查询
-	 * @param status
-	 * @return
-	 */
-	List<SysUser> queryByStatus(UserLockFlag status);
-
-	/**
-	 * 获取随机盐不为null的一条数据
-	 * @param userType
-	 * @return
-	 */
-	SysUser findUserBySalt(String userType);
-
-	/**
-	 * 创建teacher表
-	 * @param userId
-	 * @param lesseeOrganId
-	 */
-	void insertTeacher(@Param("userId") Integer userId,
-					   @Param("lesseeOrganId") Integer lesseeOrganId,
-					   @Param("tenantId") Integer tenantId);
-
-	/**
-	 * 获取教师分部编号
-	 * @param userId
-	 * @return
-	 */
-	Integer getTeacherOrganId(Integer userId);
-
-	/**
-	 * 创建租户账户表
-	 * @param userId
-	 */
+    /**
+     * 根据用户名查询对象
+     *
+     * @param username
+     * @return
+     */
+    SysUser queryByUsername(String username);
+
+    /**
+     * 根据手机号查询对象
+     *
+     * @param phone
+     * @return
+     */
+    SysUser queryByPhone(String phone);
+
+    /**
+     * 根据手机号查询对象
+     *
+     * @param phone
+     * @return
+     */
+    SysUser queryLockByPhone(String phone);
+
+    /**
+     * 根据手机号查询对象
+     *
+     * @param phone
+     * @return
+     */
+    SysUser queryByPhoneAndClient(@Param("phone") String phone, @Param("client") String client);
+
+    /**
+     * 修改密码
+     *
+     * @param mobile
+     * @param password
+     */
+    void updatePassword(@Param("mobile") String mobile, @Param("password") String password);
+
+    /**
+     * 获取用户基本信息
+     *
+     * @param userId
+     * @return
+     */
+    ImUserModel getBasic(Integer userId);
+
+    /**
+     * 根据状态查询
+     *
+     * @param status
+     * @return
+     */
+    List<SysUser> queryByStatus(UserLockFlag status);
+
+    /**
+     * 获取随机盐不为null的一条数据
+     *
+     * @param userType
+     * @return
+     */
+    SysUser findUserBySalt(String userType);
+
+    /**
+     * 创建teacher表
+     *
+     * @param userId
+     * @param lesseeOrganId
+     */
+    void insertTeacher(@Param("userId") Integer userId,
+                       @Param("lesseeOrganId") Integer lesseeOrganId,
+                       @Param("tenantId") Integer tenantId);
+
+    /**
+     * 获取教师分部编号
+     *
+     * @param userId
+     * @return
+     */
+    Integer getTeacherOrganId(Integer userId);
+
+    /**
+     * 创建租户账户表
+     *
+     * @param userId
+     */
     void insertSysTenantAccount(Integer userId);
 
-	/**
-	 * 刷新用户token
-	 * @param userId
-	 * @param imToken
-	 */
-	void refreshImToken(@Param("userId") Integer userId, @Param("imToken") String imToken);
-
-	/**
-	 * 保存student
-	 * @param userId
-	 */
-    void saveStudent(@Param("userId") Integer userId,@Param("tenantId") Integer tenantId);
+    /**
+     * 刷新用户token
+     *
+     * @param userId
+     * @param imToken
+     */
+    void refreshImToken(@Param("userId") Integer userId, @Param("imToken") String imToken);
+
+    /**
+     * 保存student
+     *
+     * @param userId
+     */
+    void saveStudent(@Param("userId") Integer userId, @Param("tenantId") Integer tenantId);
+
+    /**
+     * 通过手机号及姓名进行模糊查询
+     *
+     * @param search 关键字
+     */
+    List<SysUser> queryLikeByPhoneOrName(@Param("search") String search,@Param("tenantId") Integer tenantId);
 }

+ 110 - 90
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/service/SysUserService.java

@@ -5,102 +5,122 @@ import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.common.entity.ImUserModel;
 import com.ym.mec.common.service.BaseService;
 
+import java.util.List;
+
 public interface SysUserService extends BaseService<Integer, SysUser> {
 
-	/**
-	 * 根据用户名查询对象
-	 * @param username
-	 * @return
-	 */
-	SysUser queryByUsername(String username);
-
-	/**
-	 * 根据手机号查询对象
-	 * @param phone
-	 * @return
-	 */
-	SysUser queryByPhone(String phone);
-
-	/**
-	 * 根据手机号查询对象
-	 * @param phone
-	 * @return
-	 */
-	SysUser queryLockByPhone(String phone);
-
-	/**
-	 * 根据手机号查询对象
-	 * @param phone
-	 * @return
-	 */
-	SysUser queryByPhoneAndClient(String phone,String client);
-
-	/**
-	 * 根据用户名获取系统用户详细信息
-	 * @param username
-	 * @return
-	 */
-	SysUserInfo queryUserInfoByUsername(String username);
-
-	/**
-	 * 根据手机号获取系统用户详细信息
-	 * @param phone
-	 * @return
-	 */
-	SysUserInfo queryUserInfoByPhone(String phone);
-
-	/**
-	 * 新增用户
-	 * @param sysUser
-	 * @return
-	 */
+    /**
+     * 根据用户名查询对象
+     *
+     * @param username
+     * @return
+     */
+    SysUser queryByUsername(String username);
+
+    /**
+     * 根据手机号查询对象
+     *
+     * @param phone
+     * @return
+     */
+    SysUser queryByPhone(String phone);
+
+    /**
+     * 根据手机号查询对象
+     *
+     * @param phone
+     * @return
+     */
+    SysUser queryLockByPhone(String phone);
+
+    /**
+     * 根据手机号查询对象
+     *
+     * @param phone
+     * @return
+     */
+    SysUser queryByPhoneAndClient(String phone, String client);
+
+    /**
+     * 根据用户名获取系统用户详细信息
+     *
+     * @param username
+     * @return
+     */
+    SysUserInfo queryUserInfoByUsername(String username);
+
+    /**
+     * 根据手机号获取系统用户详细信息
+     *
+     * @param phone
+     * @return
+     */
+    SysUserInfo queryUserInfoByPhone(String phone);
+
+    /**
+     * 新增用户
+     *
+     * @param sysUser
+     * @return
+     */
     Integer add(SysUser sysUser);
 
-	/**
-	 * 获取用户基本信息
-	 * @param userId
-	 * @return
-	 */
-	ImUserModel getBasic(Integer userId);
-
-	/**
-	 * 修改用户基本信息
-	 * @param sysUser
-	 */
+    /**
+     * 获取用户基本信息
+     *
+     * @param userId
+     * @return
+     */
+    ImUserModel getBasic(Integer userId);
+
+    /**
+     * 修改用户基本信息
+     *
+     * @param sysUser
+     */
     void updateBaseInfo(SysUser sysUser);
 
-	/**
-	 * 获取用户基本信息
-	 * @param userId
-	 * @return
-	 */
-	SysUser queryUserInfo(Integer userId);
-
-	/**
-	 * 上线时初始化用户数据
-	 * @param phone
-	 * @param clientId
-	 * @return
-	 */
-	SysUserInfo initUser(Integer tenantId, String organId, String phone,String clientId);
-
-	/**
-	 * 刷新token
-	 * @param sysUser
-	 */
+    /**
+     * 获取用户基本信息
+     *
+     * @param userId
+     * @return
+     */
+    SysUser queryUserInfo(Integer userId);
+
+    /**
+     * 上线时初始化用户数据
+     *
+     * @param phone
+     * @param clientId
+     * @return
+     */
+    SysUserInfo initUser(Integer tenantId, String organId, String phone, String clientId);
+
+    /**
+     * 刷新token
+     *
+     * @param sysUser
+     */
     void refreshImToken(SysUser sysUser);
 
-	/**
-	 * 保存student数据
-	 * @param userId
-	 */
-	void saveStudent(Integer userId,Integer tenantId);
-	
-	/**
-	 * 保存teacher数据
-	 * @param userId
-	 */
-	void saveTeacher(Integer userId,Integer tenantId);
-	
-	Integer getLesseeOrganId();
+    /**
+     * 保存student数据
+     *
+     * @param userId
+     */
+    void saveStudent(Integer userId, Integer tenantId);
+
+    /**
+     * 保存teacher数据
+     *
+     * @param userId
+     */
+    void saveTeacher(Integer userId, Integer tenantId);
+
+    Integer getLesseeOrganId();
+
+    List<SysUser> queryLikeByPhoneOrName(String search);
+
+    String queryClientByPhone(String phone);
 }

+ 176 - 142
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/service/impl/SysUserServiceImpl.java

@@ -9,160 +9,194 @@ import com.ym.mec.common.dal.BaseDAO;
 import com.ym.mec.common.entity.ImResult;
 import com.ym.mec.common.entity.ImUserModel;
 import com.ym.mec.common.service.impl.BaseServiceImpl;
+import com.ym.mec.common.tenant.TenantContextHolder;
 import com.ym.mec.im.ImFeignService;
 import com.ym.mec.web.WebFeignService;
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
 
 @Service
 public class SysUserServiceImpl extends BaseServiceImpl<Integer, SysUser> implements SysUserService {
 
-	@Autowired
-	private SysUserDao sysUserDao;
-	@Autowired
-	private SysRoleMenuService sysRoleMenuService;
-	@Autowired
-	private ImFeignService imFeignService;
-	@Autowired
-	private WebFeignService userFeignService;
-	@Autowired
-	private SysUserService sysUserService;
-
-	@Value("${auth.sysconfig.tenantId}")
-	private Integer lesseeOrganId;
-
-	@Override
-	public BaseDAO<Integer, SysUser> getDAO() {
-		return sysUserDao;
-	}
-
-	@Override
-	public SysUser queryByUsername(String username) {
-		return sysUserDao.queryByUsername(username);
-	}
-
-	@Override
-	public SysUser queryByPhone(String phone) {
-		return sysUserDao.queryByPhone(phone);
-	}
-	@Override
-	public SysUser queryLockByPhone(String phone) {
-		return sysUserDao.queryLockByPhone(phone);
-	}
-
-	@Override
-	public SysUser queryByPhoneAndClient(String phone,String client) {
-		return sysUserDao.queryByPhoneAndClient(phone,client);
-	}
-
-	@Override
-	public SysUserInfo queryUserInfoByUsername(String username) {
-		return getSysUserInfo(queryByUsername(username));
-	}
-
-	@Override
-	public SysUserInfo queryUserInfoByPhone(String phone) {
-		return getSysUserInfo(queryLockByPhone(phone));
-	}
-
-	private SysUserInfo getSysUserInfo(SysUser sysUser) {
-		if (sysUser == null) {
-			return null;
-		}
-		SysUserInfo userInfo = new SysUserInfo();
-		userInfo.setSysUser(sysUser);
-		List<String> permissionList = sysRoleMenuService.queryPermissionsByRoleIdList(sysUser.getId());
-		String[] strArray = permissionList.toArray(new String[permissionList.size()]);
-		userInfo.setPermissions(strArray);
-		return userInfo;
-	}
-
-	@Override
-	public Integer add(SysUser sysUser) {
-		sysUserDao.insert(sysUser);
-		ImResult imResult = imFeignService.register(new ImUserModel(sysUser.getId().toString(), sysUser.getUsername(), sysUser.getAvatar()));
-		sysUser.setImToken(imResult.getToken());
-		sysUserDao.update(sysUser);
-		return sysUser.getId();
-	}
-
-	@Override
-	public ImUserModel getBasic(Integer userId) {
-		return sysUserDao.getBasic(userId);
-	}
-
-	@Override
-	public void updateBaseInfo(SysUser sysUser) {
-		sysUserDao.update(sysUser);
-		imFeignService.update(new ImUserModel(sysUser.getId().toString(),sysUser.getRealName()==null?sysUser.getUsername():sysUser.getRealName(),sysUser.getAvatar()));
-	}
-
-	@Override
-	public SysUser queryUserInfo(Integer userId) {
-		return sysUserDao.get(userId);
-	}
-
-	@Override
-	@Transactional(rollbackFor = Exception.class)
-	public SysUserInfo initUser(Integer tenantId, String organId, String phone,String clientId) {
-		if(StringUtils.equalsIgnoreCase(clientId,"TEACHER")){
-			SysUser sysUser = new SysUser();
-			sysUser.setPhone(phone);
-			sysUser.setUserType("TEACHER");
-			sysUser.setTenantId(tenantId);
-			sysUserDao.insert(sysUser);
-			//添加用户现金账户
-			imFeignService.register(new ImUserModel(sysUser.getId().toString(),phone,null));
-			userFeignService.createCashAccount(sysUser.getId(),tenantId);
-			//sysTenantAccount
-			sysUserDao.insertSysTenantAccount(sysUser.getId());
-			//创建teacher表
-			sysUserDao.insertTeacher(sysUser.getId(),lesseeOrganId,tenantId);
-			return queryUserInfoByPhone(phone);
-		}else if(StringUtils.equalsIgnoreCase(clientId,"STUDENT")){
-			SysUser sysUser = new SysUser();
-			sysUser.setPhone(phone);
-			sysUser.setUserType("STUDENT");
-			if(StringUtils.isBlank(organId)){
-				sysUser.setOrganId(lesseeOrganId);
-			}else{
-				sysUser.setOrganId(Integer.parseInt(organId));
-			}
-			sysUser.setTenantId(tenantId);
-			sysUserDao.insert(sysUser);
-			sysUserService.saveStudent(sysUser.getId(),tenantId);
-			//添加用户现金账户
-			imFeignService.register(new ImUserModel(sysUser.getId().toString(),phone,null));
-			userFeignService.createCashAccount(sysUser.getId(),tenantId);
-			return queryUserInfoByPhone(phone);
-		}
-		return null;
-	}
-
-	@Override
-	@Transactional(rollbackFor = Exception.class)
-	public void refreshImToken(SysUser sysUser) {
-		sysUserDao.refreshImToken(sysUser.getId(),sysUser.getImToken());
-	}
-
-	@Override
-	public void saveStudent(Integer userId,Integer tenantId) {
-		sysUserDao.saveStudent(userId,tenantId);
-	}
-
-	@Override
-	public void saveTeacher(Integer userId,Integer tenantId) {
-		sysUserDao.insertTeacher(userId, lesseeOrganId,tenantId);
-	}
-
-	@Override
-	public Integer getLesseeOrganId() {
-		return lesseeOrganId;
-	}
+    @Autowired
+    private SysUserDao sysUserDao;
+    @Autowired
+    private SysRoleMenuService sysRoleMenuService;
+    @Autowired
+    private ImFeignService imFeignService;
+    @Autowired
+    private WebFeignService userFeignService;
+    @Autowired
+    private SysUserService sysUserService;
+
+    @Value("${auth.sysconfig.tenantId}")
+    private Integer lesseeOrganId;
+
+    @Override
+    public BaseDAO<Integer, SysUser> getDAO() {
+        return sysUserDao;
+    }
+
+    @Override
+    public SysUser queryByUsername(String username) {
+        return sysUserDao.queryByUsername(username);
+    }
+
+    @Override
+    public SysUser queryByPhone(String phone) {
+        return sysUserDao.queryByPhone(phone);
+    }
+
+    @Override
+    public SysUser queryLockByPhone(String phone) {
+        return sysUserDao.queryLockByPhone(phone);
+    }
+
+    @Override
+    public SysUser queryByPhoneAndClient(String phone, String client) {
+        return sysUserDao.queryByPhoneAndClient(phone, client);
+    }
+
+    @Override
+    public SysUserInfo queryUserInfoByUsername(String username) {
+        return getSysUserInfo(queryByUsername(username));
+    }
+
+    @Override
+    public SysUserInfo queryUserInfoByPhone(String phone) {
+        return getSysUserInfo(queryLockByPhone(phone));
+    }
+
+    private SysUserInfo getSysUserInfo(SysUser sysUser) {
+        if (sysUser == null) {
+            return null;
+        }
+        SysUserInfo userInfo = new SysUserInfo();
+        userInfo.setSysUser(sysUser);
+        List<String> permissionList = sysRoleMenuService.queryPermissionsByRoleIdList(sysUser.getId());
+        String[] strArray = permissionList.toArray(new String[permissionList.size()]);
+        userInfo.setPermissions(strArray);
+        return userInfo;
+    }
+
+    @Override
+    public Integer add(SysUser sysUser) {
+        sysUserDao.insert(sysUser);
+        ImResult imResult = imFeignService.register(new ImUserModel(sysUser.getId().toString(), sysUser.getUsername(), sysUser.getAvatar()));
+        sysUser.setImToken(imResult.getToken());
+        sysUserDao.update(sysUser);
+        return sysUser.getId();
+    }
+
+    @Override
+    public ImUserModel getBasic(Integer userId) {
+        return sysUserDao.getBasic(userId);
+    }
+
+    @Override
+    public void updateBaseInfo(SysUser sysUser) {
+        sysUserDao.update(sysUser);
+        imFeignService.update(new ImUserModel(sysUser.getId().toString(), sysUser.getRealName() == null ? sysUser.getUsername() : sysUser.getRealName(), sysUser.getAvatar()));
+    }
+
+    @Override
+    public SysUser queryUserInfo(Integer userId) {
+        return sysUserDao.get(userId);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public SysUserInfo initUser(Integer tenantId, String organId, String phone, String clientId) {
+        if (StringUtils.equalsIgnoreCase(clientId, "TEACHER")) {
+            SysUser sysUser = new SysUser();
+            sysUser.setPhone(phone);
+            sysUser.setUserType("TEACHER");
+            sysUser.setTenantId(tenantId);
+            sysUserDao.insert(sysUser);
+            //添加用户现金账户
+            imFeignService.register(new ImUserModel(sysUser.getId().toString(), phone, null));
+            userFeignService.createCashAccount(sysUser.getId(), tenantId);
+            //sysTenantAccount
+            sysUserDao.insertSysTenantAccount(sysUser.getId());
+            //创建teacher表
+            sysUserDao.insertTeacher(sysUser.getId(), lesseeOrganId, tenantId);
+            return queryUserInfoByPhone(phone);
+        } else if (StringUtils.equalsIgnoreCase(clientId, "STUDENT")) {
+            SysUser sysUser = new SysUser();
+            sysUser.setPhone(phone);
+            sysUser.setUserType("STUDENT");
+            if (StringUtils.isBlank(organId)) {
+                sysUser.setOrganId(lesseeOrganId);
+            } else {
+                sysUser.setOrganId(Integer.parseInt(organId));
+            }
+            sysUser.setTenantId(tenantId);
+            sysUserDao.insert(sysUser);
+            sysUserService.saveStudent(sysUser.getId(), tenantId);
+            //添加用户现金账户
+            imFeignService.register(new ImUserModel(sysUser.getId().toString(), phone, null));
+            userFeignService.createCashAccount(sysUser.getId(), tenantId);
+            return queryUserInfoByPhone(phone);
+        }
+        return null;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void refreshImToken(SysUser sysUser) {
+        sysUserDao.refreshImToken(sysUser.getId(), sysUser.getImToken());
+    }
+
+    @Override
+    public void saveStudent(Integer userId, Integer tenantId) {
+        sysUserDao.saveStudent(userId, tenantId);
+    }
+
+    @Override
+    public void saveTeacher(Integer userId, Integer tenantId) {
+        sysUserDao.insertTeacher(userId, lesseeOrganId, tenantId);
+    }
+
+    @Override
+    public Integer getLesseeOrganId() {
+        return lesseeOrganId;
+    }
+
+    /**
+     * 通过手机号及姓名进行模糊查询
+     *
+     * @param search 关键字
+     */
+    @Override
+    public List<SysUser> queryLikeByPhoneOrName(String search) {
+        if (StringUtils.isBlank(search.trim())) {
+            return new ArrayList<>();
+        }
+        List<SysUser> sysUsers = sysUserDao.queryLikeByPhoneOrName(search, TenantContextHolder.getTenantId());
+        if (CollectionUtils.isEmpty(sysUsers)) {
+            return new ArrayList<>();
+        }
+        //只查询管理及老师
+        return sysUsers.stream()
+                .filter(u -> u.getUserType().contains("SYSTEM") || u.getUserType().contains("TEACHER"))
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public String queryClientByPhone(String phone) {
+        SysUser sysUser = queryByPhone(phone);
+        if (sysUser == null) {
+            return null;
+        }
+        return sysUser.getUserType();
+    }
 
 }

+ 12 - 0
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/web/controller/UserController.java

@@ -357,4 +357,16 @@ public class UserController extends BaseController {
 		sysUserRoleService.batchDel(Integer.parseInt(userId), roleIds);
 		return succeed();
 	}
+
+    @ApiOperation(value = "通过手机号及姓名进行模糊查询")
+    @GetMapping(value = "/queryLike")
+    public Object queryLikeByPhoneOrName(String search) {
+        return succeed(sysUserService.queryLikeByPhoneOrName(search));
+    }
+
+    @ApiOperation(value = "通过手机号查询client")
+    @GetMapping(value = "/queryClient")
+    public Object queryClientByPhone(String phone) {
+        return succeed(sysUserService.queryClientByPhone(phone));
+    }
 }

+ 13 - 0
mec-auth/mec-auth-server/src/main/resources/config/mybatis/SysUserMapper.xml

@@ -225,4 +225,17 @@
     <select id="queryByPhoneAndClient" resultMap="SysUser">
         select * from sys_user where (phone_ = #{phone} OR username_ = #{phone}) AND user_type_ LIKE CONCAT('%',#{client},'%') LIMIT 1 FOR UPDATE
     </select>
+
+    <select id="queryLikeByPhoneOrName" resultMap="SysUser">
+        select *
+        from sys_user
+        where tenant_id_ = #{tenantId}
+          and lock_flag_ = 0
+          and del_flag_ = 0
+          and (
+                    phone_ like CONCAT('%', #{search}, '%')
+                or real_name_ like CONCAT('%', #{search}, '%')
+            )
+    </select>
+
 </mapper>

+ 2 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CloudCoachPaymentProgramDao.java

@@ -5,5 +5,6 @@ import com.ym.mec.biz.dal.entity.CloudCoachPaymentProgram;
 
 public interface CloudCoachPaymentProgramDao extends BaseDAO<Long, CloudCoachPaymentProgram> {
 
-	
+
+    CloudCoachPaymentProgram getLock(Long id);
 }

+ 28 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/ImLiveBroadcastRoomDao.java

@@ -0,0 +1,28 @@
+package com.ym.mec.biz.dal.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ym.mec.biz.dal.entity.ImLiveBroadcastRoom;
+import com.ym.mec.biz.dal.vo.ImLiveBroadcastRoomVo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 直播房间管理表(ImLiveBroadcastRoom)表数据库访问层
+ *
+ * @author hgw
+ * @since 2022-02-17 20:52:05
+ */
+public interface ImLiveBroadcastRoomDao extends BaseMapper<ImLiveBroadcastRoom> {
+
+    IPage<ImLiveBroadcastRoomVo> queryPage(Page<ImLiveBroadcastRoomVo> page, @Param("param") Map<String, Object> param);
+
+    List<ImLiveBroadcastRoomVo> queryPage(@Param("param") Map<String, Object> param);
+
+    int insertBatch(@Param("entities") List<ImLiveBroadcastRoom> entities);
+
+}
+

+ 23 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/ImLiveBroadcastRoomDataDao.java

@@ -0,0 +1,23 @@
+package com.ym.mec.biz.dal.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ym.mec.biz.dal.entity.ImLiveBroadcastRoomData;
+import com.ym.mec.biz.dal.vo.ImLiveBroadcastRoomDetailVo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 直播房间数据表(ImLiveBroadcastRoomData)表数据库访问层
+ *
+ * @author hgw
+ * @since 2022-02-21 14:26:58
+ */
+public interface ImLiveBroadcastRoomDataDao extends BaseMapper<ImLiveBroadcastRoomData> {
+
+    int insertBatch(@Param("entities") List<ImLiveBroadcastRoomData> entities);
+
+    ImLiveBroadcastRoomDetailVo queryByRoomUid(@Param("roomUid") String roomUid);
+
+}
+

+ 26 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/ImLiveBroadcastRoomMemberDao.java

@@ -0,0 +1,26 @@
+package com.ym.mec.biz.dal.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ym.mec.biz.dal.entity.ImLiveBroadcastRoomMember;
+import com.ym.mec.biz.dal.vo.ImLiveBroadcastRoomMemberVo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 直播间人员关系表(ImLiveBroadcastRoomMember)表数据库访问层
+ *
+ * @author hgw
+ * @since 2022-02-21 14:26:58
+ */
+public interface ImLiveBroadcastRoomMemberDao extends BaseMapper<ImLiveBroadcastRoomMember> {
+
+    int insertBatch(@Param("entities") List<ImLiveBroadcastRoomMember> entities);
+
+    IPage<ImLiveBroadcastRoomMemberVo> queryMemberPage(Page<ImLiveBroadcastRoomMemberVo> page, @Param("param") Map<String, Object> param);
+
+}
+

+ 20 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/ImLiveRoomVideoDao.java

@@ -0,0 +1,20 @@
+package com.ym.mec.biz.dal.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ym.mec.biz.dal.entity.ImLiveRoomVideo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 直播视频记录(ImLiveRoomVideo)表数据库访问层
+ *
+ * @author hgw
+ * @since 2022-03-07 19:06:54
+ */
+public interface ImLiveRoomVideoDao extends BaseMapper<ImLiveRoomVideo> {
+
+    int insertBatch(@Param("entities") List<ImLiveRoomVideo> entities);
+
+}
+

+ 28 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/MusicGroupDao.java

@@ -467,4 +467,32 @@ public interface MusicGroupDao extends BaseDAO<String, MusicGroup> {
      * @return
      */
     List<Map<Integer, String>> queryNormalGroupName(@Param("studentIds") List<Integer> studentIds);
+
+    /**
+    * @description: 乐团剩余时长未排课
+     * @param organIds
+     * @param tenantId
+    * @return java.util.List<java.lang.String>
+    * @author zx
+    * @date 2022/3/3 15:15 
+    */
+    List<String> queryHasSubCourseTimes(@Param("organIds") String organIds, @Param("tenantId") Integer tenantId);
+
+    /**
+    * @description: 获取课程时间消耗异常的学员数
+     * @param params
+    * @return int
+    * @author zx
+    * @date 2022/3/4 11:22
+    */
+    Integer countHasFreeCourseTimes(Map<String, Object> params);
+
+    /**
+    * @description: 获取课程时间消耗异常的学员
+     * @param params
+    * @return java.util.List<com.ym.mec.biz.dal.dto.HasFreeCourseTimesDto>
+    * @author zx
+    * @date 2022/3/4 11:40
+    */
+    List<HasFreeCourseTimesDto> queryHasFreeCourseTimes(Map<String, Object> params);
 }

+ 14 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/MusicGroupPaymentStudentCourseDetailDao.java

@@ -113,4 +113,18 @@ public interface MusicGroupPaymentStudentCourseDetailDao extends BaseDAO<Long, M
     void updateByCourseType(@Param("courseType") String courseType,
                             @Param("musicGroupPaymentCalenderIds") String musicGroupPaymentCalenderIds,
                             @Param("courseCurrentPrice") BigDecimal courseCurrentPrice);
+
+    /**
+     * @description: 校验学员排课时长是否一致
+     * @param musicGroupId
+     * @param courseTypes
+     * @param studentIds
+     * @return void
+     * @author zx
+     * @date 2022/3/3 19:04
+     */
+    Integer checkCourseTimes(@Param("musicGroupId") String musicGroupId,
+                          @Param("courseTypes") List<CourseSchedule.CourseScheduleType> courseTypes,
+                          @Param("studentIds") List<Integer> studentIds);
+
 }

+ 7 - 4
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/QuestionnaireUserResultDao.java

@@ -2,10 +2,13 @@ package com.ym.mec.biz.dal.dao;
 
 import com.ym.mec.biz.dal.dto.QuestionnaireResultDto;
 import com.ym.mec.biz.dal.dto.QuestionnaireUserResultDto;
+import com.ym.mec.biz.dal.enums.QuestionnaireActiveTypeEnum;
 import com.ym.mec.common.dal.BaseDAO;
 import com.ym.mec.biz.dal.entity.QuestionnaireUserResult;
+import io.swagger.models.auth.In;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -19,9 +22,7 @@ public interface QuestionnaireUserResultDao extends BaseDAO<Long, QuestionnaireU
      */
     int countByTopicId(Integer topicId);
 
-    void delByActiveIdAndUserId(@Param("activityId") Integer activityId,
-                                @Param("userId") Integer userId,
-                                @Param("activeType") String activeType);
+    void delByActiveIdAndUserId(HashMap<String, Object> paramMap);
 
     void batchInsert1(@Param("questionnaireUserResultList") List<QuestionnaireUserResult> questionnaireUserResultList);
 
@@ -37,9 +38,11 @@ public interface QuestionnaireUserResultDao extends BaseDAO<Long, QuestionnaireU
      */
     List<QuestionnaireResultDto> getQuestionResult(@Param("activeId") Integer activeId, @Param("activeType") String activeType);
 
-    List<Map<Integer, String>> queryUserName(String activeType);
+    List<Map<Integer, String>> queryUserName(Integer topicId);
 
     List<QuestionnaireUserResultDto> findResultCount(Map<String, Object> params);
 
     int countResultCount(Map<String, Object> params);
+
+    QuestionnaireUserResultDto queryUserResult(@Param("topicId") Integer topicId, @Param("userId") Integer userId);
 }

+ 11 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentCloudCoachPaymentDetailsDao.java

@@ -10,9 +10,19 @@ public interface StudentCloudCoachPaymentDetailsDao extends BaseDAO<Long, Studen
 
 
     void batchInsert(@Param("cloudCoachPaymentProgramId") Long cloudCoachPaymentProgramId,
-                     @Param("paymentStatus") Integer paymentStatus,
                      @Param("userIds") List<Integer> userIds,
                      @Param("tenantId") Integer tenantId);
 
     StudentCloudCoachPaymentDetails findByUserId(@Param("paymentId") Long paymentId, @Param("userId") Integer userId);
+
+    /**
+    * @description: 修改学员为已缴费
+     * @param cloudCoachPaymentProgramId
+    * @return void
+    * @author zx
+    * @date 2022/3/2 19:35
+    */
+    void updatePaymentStatus(Long cloudCoachPaymentProgramId);
+
+    List<Integer> findUserByProgramId(Long programId);
 }

+ 4 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TenantPreJoinDao.java

@@ -1,10 +1,13 @@
 package com.ym.mec.biz.dal.dao;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ym.mec.biz.dal.entity.TenantPreJoin;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * 机构入驻表(预加入)(TenantPreJoin)表数据库访问层
@@ -16,5 +19,6 @@ public interface TenantPreJoinDao extends BaseMapper<TenantPreJoin> {
 
     int insertBatch(@Param("entities") List<TenantPreJoin> entities);
 
+    <T> IPage<T> queryPage(Page<T> page, @Param("param") Map<String, Object> param);
 }
 

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/ClassGroup4MixDto.java

@@ -25,6 +25,9 @@ public class ClassGroup4MixDto implements Cloneable{
     @ApiModelProperty(value = "是否只生成班级")
     private Boolean onlyCreateClassGroup;
 
+    @ApiModelProperty(value = "是否继续提交")
+    private Boolean checkCourseTimesFlag = false;
+
     @ApiModelProperty(value = "学生ids", required = true)
     private List<Integer> students;
 
@@ -79,6 +82,14 @@ public class ClassGroup4MixDto implements Cloneable{
     @ApiModelProperty(value = "预排课学期编号")
     private Integer musicGroupSchoolTermCourseDetailId;
 
+    public Boolean getCheckCourseTimesFlag() {
+        return checkCourseTimesFlag;
+    }
+
+    public void setCheckCourseTimesFlag(Boolean checkCourseTimesFlag) {
+        this.checkCourseTimesFlag = checkCourseTimesFlag;
+    }
+
     public Integer getMusicGroupSchoolTermCourseDetailId() {
         return musicGroupSchoolTermCourseDetailId;
     }

+ 116 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/HasFreeCourseTimesDto.java

@@ -0,0 +1,116 @@
+package com.ym.mec.biz.dal.dto;
+
+
+import com.ym.mec.biz.dal.entity.CourseSchedule;
+import io.swagger.annotations.ApiModelProperty;
+
+public class HasFreeCourseTimesDto {
+
+    @ApiModelProperty(value = "乐团编号")
+    private String musicGroupId;
+
+    @ApiModelProperty(value = "乐团名称")
+    private String musicGroupName;
+
+    @ApiModelProperty(value = "学员编号")
+    private Integer userId;
+
+    @ApiModelProperty(value = "学员姓名")
+    private String username;
+
+    @ApiModelProperty(value = "总时长")
+    private Integer totalCourseMinutes;
+
+    @ApiModelProperty(value = "消耗时长")
+    private Integer usedCourseMinutes;
+
+    @ApiModelProperty(value = "未消耗时长")
+    private Integer freeCourseMinutes;
+
+    @ApiModelProperty(value = "课程类型")
+    private CourseSchedule.CourseScheduleType courseType;
+
+    private String organName;
+
+    private Integer organId;
+
+    public String getOrganName() {
+        return organName;
+    }
+
+    public void setOrganName(String organName) {
+        this.organName = organName;
+    }
+
+    public Integer getOrganId() {
+        return organId;
+    }
+
+    public void setOrganId(Integer organId) {
+        this.organId = organId;
+    }
+
+    public String getMusicGroupId() {
+        return musicGroupId;
+    }
+
+    public void setMusicGroupId(String musicGroupId) {
+        this.musicGroupId = musicGroupId;
+    }
+
+    public String getMusicGroupName() {
+        return musicGroupName;
+    }
+
+    public void setMusicGroupName(String musicGroupName) {
+        this.musicGroupName = musicGroupName;
+    }
+
+    public Integer getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Integer userId) {
+        this.userId = userId;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public Integer getTotalCourseMinutes() {
+        return totalCourseMinutes;
+    }
+
+    public void setTotalCourseMinutes(Integer totalCourseMinutes) {
+        this.totalCourseMinutes = totalCourseMinutes;
+    }
+
+    public Integer getUsedCourseMinutes() {
+        return usedCourseMinutes;
+    }
+
+    public void setUsedCourseMinutes(Integer usedCourseMinutes) {
+        this.usedCourseMinutes = usedCourseMinutes;
+    }
+
+    public Integer getFreeCourseMinutes() {
+        return freeCourseMinutes;
+    }
+
+    public void setFreeCourseMinutes(Integer freeCourseMinutes) {
+        this.freeCourseMinutes = freeCourseMinutes;
+    }
+
+    public CourseSchedule.CourseScheduleType getCourseType() {
+        return courseType;
+    }
+
+    public void setCourseType(CourseSchedule.CourseScheduleType courseType) {
+        this.courseType = courseType;
+    }
+}

+ 165 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/ImLiveBroadcastRoomDto.java

@@ -0,0 +1,165 @@
+package com.ym.mec.biz.dal.dto;
+
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 直播房间管理表(ImLiveBroadcastRoom)表实体类
+ *
+ * @author hgw
+ * @since 2022-02-17 20:52:05
+ */
+@ApiModel(value = "直播房间管理")
+public class ImLiveBroadcastRoomDto implements Serializable {
+    @ApiModelProperty(value = "主键")
+    private Integer id;
+
+    @ApiModelProperty(value = "机构id")
+    private Integer tenantId;
+
+    @NotNull(message = "主讲人不能为空!")
+    @ApiModelProperty(value = "主讲人id/老师id")
+    private Integer speakerId;
+
+    @Size(max = 12, message = "房间标题最多12个字!")
+    @NotBlank(message = "房间标题不能为空")
+    @ApiModelProperty(value = "房间标题/最多12个字")
+    private String roomTitle;
+
+    @NotNull(message = "直播开始时间不能为空!")
+    @ApiModelProperty(value = "直播开始时间")
+    private Date liveStartTime;
+
+    @Size(max = 200, message = "直播内容最多200个字!")
+    @NotBlank(message = "直播内容不能为空")
+    @ApiModelProperty(value = "直播内容/最多200个字")
+    private String liveRemark;
+
+    @NotBlank(message = "预热模版不能为空")
+    @ApiModelProperty(value = "预热模版")
+    private String preTemplate;
+
+    @ApiModelProperty(value = "房间配置")
+    private RoomConfig roomConfig;
+
+    @ApiModel(value = "房间配置")
+    public static class RoomConfig implements Serializable {
+
+        @ApiModelProperty(value = "是否允许点赞 0允许 1不允许")
+        private Integer whether_like = 0;
+
+        @ApiModelProperty(value = "是否允许聊天互动  0允许 1不允许")
+        private Integer whether_chat = 0;
+
+        @ApiModelProperty(value = "是否允许保存直播回放 0允许 1不允许")
+        private Integer whether_video = 1;
+
+        @ApiModelProperty(value = "是否允许连麦 0允许 1不允许")
+        private Integer whether_mic = 0;
+
+        public Integer getWhether_like() {
+            return whether_like;
+        }
+
+        public void setWhether_like(Integer whether_like) {
+            this.whether_like = whether_like;
+        }
+
+        public Integer getWhether_chat() {
+            return whether_chat;
+        }
+
+        public void setWhether_chat(Integer whether_chat) {
+            this.whether_chat = whether_chat;
+        }
+
+        public Integer getWhether_video() {
+            return whether_video;
+        }
+
+        public void setWhether_video(Integer whether_video) {
+            this.whether_video = whether_video;
+        }
+
+        public Integer getWhether_mic() {
+            return whether_mic;
+        }
+
+        public void setWhether_mic(Integer whether_mic) {
+            this.whether_mic = whether_mic;
+        }
+    }
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Integer getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(Integer tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public Integer getSpeakerId() {
+        return speakerId;
+    }
+
+    public void setSpeakerId(Integer speakerId) {
+        this.speakerId = speakerId;
+    }
+
+    public String getRoomTitle() {
+        return roomTitle;
+    }
+
+    public void setRoomTitle(String roomTitle) {
+        this.roomTitle = roomTitle;
+    }
+
+    public Date getLiveStartTime() {
+        return liveStartTime;
+    }
+
+    public void setLiveStartTime(Date liveStartTime) {
+        this.liveStartTime = liveStartTime;
+    }
+
+    public String getLiveRemark() {
+        return liveRemark;
+    }
+
+    public void setLiveRemark(String liveRemark) {
+        this.liveRemark = liveRemark;
+    }
+
+    public String getPreTemplate() {
+        return preTemplate;
+    }
+
+    public void setPreTemplate(String preTemplate) {
+        this.preTemplate = preTemplate;
+    }
+
+    public RoomConfig getRoomConfig() {
+        return roomConfig;
+    }
+
+    public void setRoomConfig(RoomConfig roomConfig) {
+        this.roomConfig = roomConfig;
+    }
+
+}
+

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/MusicGroupPaymentBaseCalender.java

@@ -9,6 +9,9 @@ import java.util.Date;
 import java.util.List;
 
 public class MusicGroupPaymentBaseCalender {
+	@ApiModelProperty(value = "是否继续操作", required = true)
+	private Boolean confirmCreate = false;
+
 	private Long calenderId;
 
 	@ApiModelProperty(value = "乐团编号", required = true)
@@ -51,6 +54,14 @@ public class MusicGroupPaymentBaseCalender {
 	@ApiModelProperty(value = "进行中加学员拓展信息", required = false)
 	private CalenderAddStudent calenderAddStudent;
 
+	public Boolean getConfirmCreate() {
+		return confirmCreate;
+	}
+
+	public void setConfirmCreate(Boolean confirmCreate) {
+		this.confirmCreate = confirmCreate;
+	}
+
 	public Long getCalenderId() {
 		return calenderId;
 	}

+ 13 - 4
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/TenantPreJoinDto.java

@@ -2,10 +2,7 @@ package com.ym.mec.biz.dal.dto;
 
 import io.swagger.annotations.ApiModelProperty;
 
-import javax.validation.constraints.Email;
-import javax.validation.constraints.NotBlank;
-import javax.validation.constraints.Pattern;
-import javax.validation.constraints.Size;
+import javax.validation.constraints.*;
 import java.io.Serializable;
 
 /**
@@ -20,6 +17,10 @@ public class TenantPreJoinDto implements Serializable {
     @ApiModelProperty(value = "公司全称")
     private String tsignName;
 
+    @NotNull(message = "推荐人不能为空")
+    @ApiModelProperty(value = "推荐人")
+    private Integer recommender;
+
     @NotBlank(message = "公司简称不能为空")
     @ApiModelProperty(value = "机构名称/公司简称")
     private String name;
@@ -102,6 +103,14 @@ public class TenantPreJoinDto implements Serializable {
     @ApiModelProperty(value = "企业财务公章图片地址")
     private String corporateFinanceChops;
 
+    public Integer getRecommender() {
+        return recommender;
+    }
+
+    public void setRecommender(Integer recommender) {
+        this.recommender = recommender;
+    }
+
     private static final long serialVersionUID = 1L;
 
     public Integer getId() {

+ 90 - 3
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/CloudCoachPaymentProgram.java

@@ -2,9 +2,12 @@ package com.ym.mec.biz.dal.entity;
 
 import com.ym.mec.biz.dal.enums.PeriodEnum;
 import com.ym.mec.common.entity.BaseEntity;
+import com.ym.mec.common.enums.BaseEnum;
+import io.swagger.annotations.ApiModelProperty;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 
 import java.math.BigDecimal;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -14,7 +17,7 @@ public class CloudCoachPaymentProgram extends BaseEntity {
 
 	/**  */
 	private Long id;
-	
+
 	/** 会员名称 */
 	private String name;
 	
@@ -22,13 +25,13 @@ public class CloudCoachPaymentProgram extends BaseEntity {
 	private String remark;
 	
 	/** 会员数量 */
-	private BigDecimal memberNum = BigDecimal.ZERO;
+	private BigDecimal memberNum;
 
 	/** 云教练描述 */
 	private String memberIntro;
 	
 	/** 缴费项目总人数 */
-	private Integer userNum = 0;
+	private Integer userNum;
 	
 	/** 已缴费人数 */
 	private Integer paymentUserNum = 0;
@@ -61,8 +64,92 @@ public class CloudCoachPaymentProgram extends BaseEntity {
 
 	private Integer organId;
 
+	private String organName;
+
 	private List<Integer> userIds;
 
+	@ApiModelProperty(value = "审核备注", required = false)
+	private String memo;
+
+	@ApiModelProperty(value = "状态", required = false)
+	private CloudCoachPaymentProgram.StatusEnum status;
+
+	@ApiModelProperty(value = "审核人", required = false)
+	private Integer audit;
+
+	@ApiModelProperty(value = "审核人", required = false)
+	private String auditName;
+
+	@ApiModelProperty(value = "审核时间", required = false)
+	private Date auditTime;
+
+	public enum StatusEnum implements BaseEnum<String, CloudCoachPaymentProgram.StatusEnum> {
+		AUDITING("审核中"), REJECT("审核拒绝"), OPEN("审核通过");
+
+		private String desc;
+
+		StatusEnum(String desc) {
+			this.desc = desc;
+		}
+
+		@Override
+		public String getCode() {
+			return this.name();
+		}
+
+		public String getDesc() {
+			return desc;
+		}
+	}
+
+	public String getOrganName() {
+		return organName;
+	}
+
+	public void setOrganName(String organName) {
+		this.organName = organName;
+	}
+
+	public Integer getAudit() {
+		return audit;
+	}
+
+	public void setAudit(Integer audit) {
+		this.audit = audit;
+	}
+
+	public String getAuditName() {
+		return auditName;
+	}
+
+	public void setAuditName(String auditName) {
+		this.auditName = auditName;
+	}
+
+	public Date getAuditTime() {
+		return auditTime;
+	}
+
+	public void setAuditTime(Date auditTime) {
+		this.auditTime = auditTime;
+	}
+
+	public StatusEnum getStatus() {
+		return status;
+	}
+
+	public void setStatus(StatusEnum status) {
+		this.status = status;
+	}
+
+	public String getMemo() {
+		return memo;
+	}
+
+	public void setMemo(String memo) {
+		this.memo = memo;
+	}
+
 	public String getMemberIntro() {
 		return memberIntro;
 	}

+ 217 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/ImLiveBroadcastRoom.java

@@ -0,0 +1,217 @@
+package com.ym.mec.biz.dal.entity;
+
+
+import java.util.Date;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.TableId;
+
+import java.io.Serializable;
+
+/**
+ * 直播房间管理表(ImLiveBroadcastRoom)表实体类
+ *
+ * @author hgw
+ * @since 2022-02-17 20:52:05
+ */
+@ApiModel(value = "im_live_broadcast_room-直播房间管理表")
+public class ImLiveBroadcastRoom implements Serializable {
+    @TableId(value = "id_", type = IdType.AUTO)
+    @ApiModelProperty(value = "主键")
+    private Integer id;
+
+    @TableField("tenant_id_")
+    @ApiModelProperty(value = "机构id")
+    private Integer tenantId;
+
+    @TableField("speaker_id_")
+    @ApiModelProperty(value = "主讲人id/老师id")
+    private Integer speakerId;
+
+    @TableField("room_uid_")
+    @ApiModelProperty(value = "房间编号")
+    private String roomUid;
+
+    @TableField("room_title_")
+    @ApiModelProperty(value = "房间标题/最多12个字")
+    private String roomTitle;
+
+    @TableField("live_start_time_")
+    @ApiModelProperty(value = "直播开始时间")
+    private Date liveStartTime;
+
+    @TableField("live_end_time_")
+    @ApiModelProperty(value = "直播结束时间")
+    private Date liveEndTime;
+
+    @TableField("live_remark_")
+    @ApiModelProperty(value = "直播内容/最多200个字")
+    private String liveRemark;
+
+    @TableField("pre_template_")
+    @ApiModelProperty(value = "预热模版")
+    private String preTemplate;
+
+    @TableField("room_config_")
+    @ApiModelProperty(value = "房间配置json格式-是否允许点赞-是否允许聊天互动-是否允许保存直播回放")
+    private String roomConfig;
+
+    @TableField("live_state_")
+    @ApiModelProperty(value = "直播状态 0未开始 1开始 2已结束")
+    private Integer liveState;
+
+    @TableField("room_state_")
+    @ApiModelProperty(value = "房间状态 0正常 1已删除 2销毁")
+    private Integer roomState;
+
+    @TableField("created_by_")
+    @ApiModelProperty(value = "创建人")
+    private Integer createdBy;
+
+    @TableField("created_time_")
+    @ApiModelProperty(value = "创建时间")
+    private Date createdTime;
+
+    @TableField("updated_by_")
+    @ApiModelProperty(value = "更新人")
+    private Integer updatedBy;
+
+    @TableField("updated_time_")
+    @ApiModelProperty(value = "更新时间")
+    private Date updatedTime;
+
+    private static final long serialVersionUID = 1L;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Integer getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(Integer tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public Integer getSpeakerId() {
+        return speakerId;
+    }
+
+    public void setSpeakerId(Integer speakerId) {
+        this.speakerId = speakerId;
+    }
+
+    public String getRoomUid() {
+        return roomUid;
+    }
+
+    public void setRoomUid(String roomUid) {
+        this.roomUid = roomUid;
+    }
+
+    public String getRoomTitle() {
+        return roomTitle;
+    }
+
+    public void setRoomTitle(String roomTitle) {
+        this.roomTitle = roomTitle;
+    }
+
+    public Date getLiveStartTime() {
+        return liveStartTime;
+    }
+
+    public void setLiveStartTime(Date liveStartTime) {
+        this.liveStartTime = liveStartTime;
+    }
+
+    public Date getLiveEndTime() {
+        return liveEndTime;
+    }
+
+    public void setLiveEndTime(Date liveEndTime) {
+        this.liveEndTime = liveEndTime;
+    }
+
+    public String getLiveRemark() {
+        return liveRemark;
+    }
+
+    public void setLiveRemark(String liveRemark) {
+        this.liveRemark = liveRemark;
+    }
+
+    public String getPreTemplate() {
+        return preTemplate;
+    }
+
+    public void setPreTemplate(String preTemplate) {
+        this.preTemplate = preTemplate;
+    }
+
+    public String getRoomConfig() {
+        return roomConfig;
+    }
+
+    public void setRoomConfig(String roomConfig) {
+        this.roomConfig = roomConfig;
+    }
+
+    public Integer getLiveState() {
+        return liveState;
+    }
+
+    public void setLiveState(Integer liveState) {
+        this.liveState = liveState;
+    }
+
+    public Integer getRoomState() {
+        return roomState;
+    }
+
+    public void setRoomState(Integer roomState) {
+        this.roomState = roomState;
+    }
+
+    public Integer getCreatedBy() {
+        return createdBy;
+    }
+
+    public void setCreatedBy(Integer createdBy) {
+        this.createdBy = createdBy;
+    }
+
+    public Date getCreatedTime() {
+        return createdTime;
+    }
+
+    public void setCreatedTime(Date createdTime) {
+        this.createdTime = createdTime;
+    }
+
+    public Integer getUpdatedBy() {
+        return updatedBy;
+    }
+
+    public void setUpdatedBy(Integer updatedBy) {
+        this.updatedBy = updatedBy;
+    }
+
+    public Date getUpdatedTime() {
+        return updatedTime;
+    }
+
+    public void setUpdatedTime(Date updatedTime) {
+        this.updatedTime = updatedTime;
+    }
+
+}
+

+ 119 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/ImLiveBroadcastRoomData.java

@@ -0,0 +1,119 @@
+package com.ym.mec.biz.dal.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 直播房间数据表(ImLiveBroadcastRoomData)表实体类
+ *
+ * @author hgw
+ * @since 2022-02-21 14:26:58
+ */
+@ApiModel(value = "im_live_broadcast_room_data-直播房间数据表")
+public class ImLiveBroadcastRoomData implements Serializable {
+    @TableId(value = "id_", type = IdType.AUTO)
+    @ApiModelProperty(value = "主键")
+    private Integer id;
+
+    @TableField("tenant_id_")
+    @ApiModelProperty(value = "机构id")
+    private Integer tenantId;
+
+    @TableField("room_uid_")
+    @ApiModelProperty(value = "房间uid")
+    private String roomUid;
+
+    @TableField("like_num_")
+    @ApiModelProperty(value = "累计点赞数")
+    private Integer likeNum;
+
+    @TableField("look_user_num_")
+    @ApiModelProperty(value = "即时观看人员数")
+    private Integer lookUserNum;
+
+    @TableField("total_user_num_")
+    @ApiModelProperty(value = "累计观看总人员数")
+    private Integer totalUserNum;
+
+    @TableField("updated_time_")
+    @ApiModelProperty(value = "更新时间")
+    private Date updatedTime;
+
+    @TableField("live_time_")
+    @ApiModelProperty(value = "直播时长")
+    private Integer liveTime;
+
+    private static final long serialVersionUID = 1L;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Integer getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(Integer tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public String getRoomUid() {
+        return roomUid;
+    }
+
+    public void setRoomUid(String roomUid) {
+        this.roomUid = roomUid;
+    }
+
+    public Integer getLikeNum() {
+        return likeNum;
+    }
+
+    public void setLikeNum(Integer likeNum) {
+        this.likeNum = likeNum;
+    }
+
+    public Integer getLookUserNum() {
+        return lookUserNum;
+    }
+
+    public void setLookUserNum(Integer lookUserNum) {
+        this.lookUserNum = lookUserNum;
+    }
+
+    public Integer getTotalUserNum() {
+        return totalUserNum;
+    }
+
+    public void setTotalUserNum(Integer totalUserNum) {
+        this.totalUserNum = totalUserNum;
+    }
+
+    public Date getUpdatedTime() {
+        return updatedTime;
+    }
+
+    public void setUpdatedTime(Date updatedTime) {
+        this.updatedTime = updatedTime;
+    }
+
+    public Integer getLiveTime() {
+        return liveTime;
+    }
+
+    public void setLiveTime(Integer liveTime) {
+        this.liveTime = liveTime;
+    }
+
+}
+

+ 97 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/ImLiveBroadcastRoomMember.java

@@ -0,0 +1,97 @@
+package com.ym.mec.biz.dal.entity;
+
+
+import java.util.Date;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.TableId;
+
+import java.io.Serializable;
+
+/**
+ * 直播间人员关系表(ImLiveBroadcastRoomMember)表实体类
+ *
+ * @author hgw
+ * @since 2022-02-21 14:26:58
+ */
+@ApiModel(value = "im_live_broadcast_room_member-直播间人员关系表")
+public class ImLiveBroadcastRoomMember implements Serializable {
+    @TableId(value = "id_", type = IdType.AUTO)
+    @ApiModelProperty(value = "主键")
+    private Integer id;
+
+    @TableField("tenant_id_")
+    @ApiModelProperty(value = "机构id")
+    private Integer tenantId;
+
+    @TableField("room_uid_")
+    @ApiModelProperty(value = "房间编号")
+    private String roomUid;
+
+    @TableField("user_id_")
+    @ApiModelProperty(value = "进入房间的人员id/学生id")
+    private Integer userId;
+
+    @TableField("join_time_")
+    @ApiModelProperty(value = "进入房间时间")
+    private Date joinTime;
+
+    @TableField("total_time_")
+    @ApiModelProperty(value = "累计观看时间/以分钟为单位")
+    private Integer totalTime;
+
+    private static final long serialVersionUID = 1L;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Integer getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(Integer tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public String getRoomUid() {
+        return roomUid;
+    }
+
+    public void setRoomUid(String roomUid) {
+        this.roomUid = roomUid;
+    }
+
+    public Integer getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Integer userId) {
+        this.userId = userId;
+    }
+
+    public Date getJoinTime() {
+        return joinTime;
+    }
+
+    public void setJoinTime(Date joinTime) {
+        this.joinTime = joinTime;
+    }
+
+    public Integer getTotalTime() {
+        return totalTime;
+    }
+
+    public void setTotalTime(Integer totalTime) {
+        this.totalTime = totalTime;
+    }
+
+}
+

+ 121 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/ImLiveRoomVideo.java

@@ -0,0 +1,121 @@
+package com.ym.mec.biz.dal.entity;
+
+
+import java.util.Date;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.TableId;
+
+import java.io.Serializable;
+
+/**
+ * 直播视频记录(ImLiveRoomVideo)表实体类
+ *
+ * @author hgw
+ * @since 2022-03-07 19:06:54
+ */
+@ApiModel(value = "im_live_room_video-直播视频记录")
+public class ImLiveRoomVideo implements Serializable {
+    @TableId(value = "id_", type = IdType.AUTO)
+    @ApiModelProperty(value = "主键")
+    private Integer id;
+
+    @TableField("room_uid_")
+    @ApiModelProperty(value = "房间编号")
+    private String roomUid;
+
+    @TableField("record_id_")
+    @ApiModelProperty(value = "融云直播视频id")
+    private String recordId;
+
+    @TableField("url_")
+    @ApiModelProperty(value = "直播视频地址")
+    private String url;
+
+    @TableField("start_time_")
+    @ApiModelProperty(value = "视频开始时间")
+    private Date startTime;
+
+    @TableField("end_time_")
+    @ApiModelProperty(value = "视频结束时间")
+    private Date endTime;
+
+    @TableField("type")
+    @ApiModelProperty(value = "录制状态 0开始录制  1录制结束 2融云回调完成")
+    private Integer type;
+
+    @TableField("created_time_")
+    @ApiModelProperty(value = "创建时间")
+    private Date createdTime;
+
+    private static final long serialVersionUID = 1L;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public String getRoomUid() {
+        return roomUid;
+    }
+
+    public void setRoomUid(String roomUid) {
+        this.roomUid = roomUid;
+    }
+
+    public String getRecordId() {
+        return recordId;
+    }
+
+    public void setRecordId(String recordId) {
+        this.recordId = recordId;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public Date getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(Date startTime) {
+        this.startTime = startTime;
+    }
+
+    public Date getEndTime() {
+        return endTime;
+    }
+
+    public void setEndTime(Date endTime) {
+        this.endTime = endTime;
+    }
+
+    public Integer getType() {
+        return type;
+    }
+
+    public void setType(Integer type) {
+        this.type = type;
+    }
+
+    public Date getCreatedTime() {
+        return createdTime;
+    }
+
+    public void setCreatedTime(Date createdTime) {
+        this.createdTime = createdTime;
+    }
+
+}
+

+ 42 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/QuestionnaireTopic.java

@@ -25,6 +25,12 @@ public class QuestionnaireTopic extends BaseEntity {
 
 	/** 创建人编号 */
 	private Integer creatorId;
+
+	/** 是否需要登录(1是0否) */
+	private Integer loginFlag = 1;
+
+	/** 是否逐题提交(1逐题0一起提交) */
+	private Integer commitType = 1;
 	
 	/**  */
 	private java.util.Date createTime;
@@ -38,6 +44,42 @@ public class QuestionnaireTopic extends BaseEntity {
 	//问卷题目
 	private List<QuestionnaireQuestion> questionnaireQuestionList;
 
+	private Integer templateType;
+
+	private Boolean modifyFlag = true;
+
+	public Boolean getModifyFlag() {
+		return modifyFlag;
+	}
+
+	public void setModifyFlag(Boolean modifyFlag) {
+		this.modifyFlag = modifyFlag;
+	}
+
+	public Integer getTemplateType() {
+		return templateType;
+	}
+
+	public void setTemplateType(Integer templateType) {
+		this.templateType = templateType;
+	}
+
+	public Integer getLoginFlag() {
+		return loginFlag;
+	}
+
+	public void setLoginFlag(Integer loginFlag) {
+		this.loginFlag = loginFlag;
+	}
+
+	public Integer getCommitType() {
+		return commitType;
+	}
+
+	public void setCommitType(Integer commitType) {
+		this.commitType = commitType;
+	}
+
 	public int getAgainCommitFlag() {
 		return againCommitFlag;
 	}

+ 13 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/TenantPreJoin.java

@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.annotation.TableId;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+import javax.validation.constraints.NotNull;
 import java.io.Serializable;
 import java.util.Date;
 
@@ -22,6 +23,10 @@ public class TenantPreJoin implements Serializable {
     @ApiModelProperty(value = "主键")
     private Integer id;
 
+    @TableField("recommender_")
+    @ApiModelProperty(value = "推荐人")
+    private Integer recommender;
+
     @TableField("tsign_name_")
     @ApiModelProperty(value = "公司全称")
     private String tsignName;
@@ -122,6 +127,14 @@ public class TenantPreJoin implements Serializable {
     @ApiModelProperty(value = "省份名称")
     private String provinceName;
 
+    public Integer getRecommender() {
+        return recommender;
+    }
+
+    public void setRecommender(Integer recommender) {
+        this.recommender = recommender;
+    }
+
     private static final long serialVersionUID = 1L;
 
     public Integer getId() {

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

@@ -69,7 +69,7 @@ public enum ExportEnum implements BaseEnum<String, ExportEnum> {
     MUSIC_ENLIGHTENMENT_QUESTIONNAIRES("MUSIC_ENLIGHTENMENT_QUESTIONNAIRES", "启蒙课问卷导出"),
     STUDENT_INSTRUMENT("STUDENT_INSTRUMENT", "乐保导出"),
     EXPORT_BILL("EXPORT_BILL", "对账单导出"),
-    QUESTIONNAIRE_USER_RESULT("QUESTIONNAIRE_USER_RESULT", "问卷调查导出"),
+//    QUESTIONNAIRE_USER_RESULT("QUESTIONNAIRE_USER_RESULT", "问卷调查导出"),
     STUDENT_VIP_COURSE_INFO("STUDENT_VIP_COURSE_INFO", "VIP课学员课程信息导出"),
     STUDENT_MUSIC_THEORY_COURSE_INFO("STUDENT_MUSIC_THEORY_COURSE_INFO", "乐理课学员课程信息导出"),
     EXERCISES_SITUATION("EXERCISES_SITUATION", "服务指标导出");

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

@@ -30,6 +30,7 @@ public enum IndexErrorType implements BaseEnum<String, IndexErrorType> {
     COURSE_TIME_ERROR("COURSE_TIME_ERROR", "课程时间安排异常"),
     TEACHER_LEAVE("TEACHER_LEAVE", "老师请假"),
     TEACHER_EXPECT_SALARY_BE_LOW("TEACHER_EXPECT_SALARY_BE_LOW", "预计课酬较低"),
+    MUSIC_GROUP_HAS_COURSE_TIMES("MUSIC_GROUP_HAS_COURSE_TIMES", "乐团剩余时长未排课"),
     INSPECTION_ITEM("INSPECTION_ITEM", "乐团巡查任务未计划"),
     INSPECTION_ITEM_PLAN("INSPECTION_ITEM_PLAN", "乐团巡查任务未提交"),
     STUDENT_VISIT("STUDENT_VISIT", "回访任务未完成"),
@@ -38,6 +39,7 @@ public enum IndexErrorType implements BaseEnum<String, IndexErrorType> {
     TEACHER_EXCEPTION_ATTENDANCE("TEACHER_EXCEPTION_ATTENDANCE", "课程考勤异常"),
     TEACHER_NOT_A_CLASS("TEACHER_NOT_A_CLASS", "课程异常"),
     TEACHER_SERVE_ERROR("TEACHER_SERVE_ERROR", "服务指标异常"),
+    HAS_FREE_COURSE_TIMES("HAS_FREE_COURSE_TIMES", "学员已排课时长未消耗完"),
     ;
 
     private String code;

+ 1 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/enums/MessageTypeEnum.java

@@ -217,6 +217,7 @@ public enum MessageTypeEnum implements BaseEnum<String, MessageTypeEnum> {
 
     STUDENT_SMS_CLOUD_PAYMENT("STUDENT_SMS_CLOUD_PAYMENT",  "待缴费订单"),
     STUDENT_PUSH_CLOUD_PAYMENT("STUDENT_PUSH_CLOUD_PAYMENT",  "待缴费订单"),
+    IM_SHARE_LIVE_URL("IM_SHARE_LIVE_URL",  "直播链接分享")
     ;
 
     MessageTypeEnum(String code, String msg) {

+ 19 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/page/CloudCoachPaymentProgramQueryInfo.java

@@ -3,6 +3,7 @@ package com.ym.mec.biz.dal.page;
 import com.ym.mec.common.page.QueryInfo;
 
 public class CloudCoachPaymentProgramQueryInfo extends QueryInfo {
+    private String organId;
 
     private String period;
 
@@ -10,6 +11,24 @@ public class CloudCoachPaymentProgramQueryInfo extends QueryInfo {
 
     private String endTime;
 
+    private String status;
+
+    public String getOrganId() {
+        return organId;
+    }
+
+    public void setOrganId(String organId) {
+        this.organId = organId;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
     public String getPeriod() {
         return period;
     }

+ 3 - 4
mec-biz/src/main/java/com/ym/mec/biz/dal/page/MusicGroupQueryInfo.java

@@ -1,14 +1,13 @@
 package com.ym.mec.biz.dal.page;
 
+import com.ym.mec.biz.dal.enums.CourseViewTypeEnum;
+import com.ym.mec.biz.dal.enums.MusicGroupStatusEnum;
+import com.ym.mec.common.page.QueryInfo;
 import io.swagger.annotations.ApiModelProperty;
 
 import java.util.Date;
 import java.util.List;
 
-import com.ym.mec.biz.dal.enums.CourseViewTypeEnum;
-import com.ym.mec.biz.dal.enums.MusicGroupStatusEnum;
-import com.ym.mec.common.page.QueryInfo;
-
 public class MusicGroupQueryInfo extends QueryInfo {
 
     @ApiModelProperty(value = "所属分部编号",required = false)

+ 101 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/vo/ImLiveBroadcastRoomDetailVo.java

@@ -0,0 +1,101 @@
+package com.ym.mec.biz.dal.vo;
+
+import com.ym.mec.biz.dal.entity.ImLiveRoomVideo;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author hgw
+ * Created by 2022-02-25
+ */
+public class ImLiveBroadcastRoomDetailVo implements Serializable {
+
+    @ApiModelProperty(value = "房间编号")
+    private String roomUid;
+
+    @ApiModelProperty(value = "房间标题/最多12个字")
+    private String roomTitle;
+
+    @ApiModelProperty(value = "主讲人名称")
+    private String speakerName;
+
+    @ApiModelProperty(value = "直播内容/最多200个字")
+    private String liveRemark;
+
+    @ApiModelProperty(value = "参与人员数量")
+    private Integer totalLookNum;
+
+    @ApiModelProperty(value = "点赞数")
+    private Integer totalLikeNum;
+
+    @ApiModelProperty(value = "直播时长")
+    private Integer totalLiveTime;
+
+    private List<ImLiveRoomVideo> videoList;
+
+    public String getRoomUid() {
+        return roomUid;
+    }
+
+    public void setRoomUid(String roomUid) {
+        this.roomUid = roomUid;
+    }
+
+    public String getRoomTitle() {
+        return roomTitle;
+    }
+
+    public void setRoomTitle(String roomTitle) {
+        this.roomTitle = roomTitle;
+    }
+
+    public String getSpeakerName() {
+        return speakerName;
+    }
+
+    public void setSpeakerName(String speakerName) {
+        this.speakerName = speakerName;
+    }
+
+    public String getLiveRemark() {
+        return liveRemark;
+    }
+
+    public void setLiveRemark(String liveRemark) {
+        this.liveRemark = liveRemark;
+    }
+
+    public Integer getTotalLookNum() {
+        return totalLookNum;
+    }
+
+    public void setTotalLookNum(Integer totalLookNum) {
+        this.totalLookNum = totalLookNum;
+    }
+
+    public Integer getTotalLikeNum() {
+        return totalLikeNum;
+    }
+
+    public void setTotalLikeNum(Integer totalLikeNum) {
+        this.totalLikeNum = totalLikeNum;
+    }
+
+    public Integer getTotalLiveTime() {
+        return totalLiveTime;
+    }
+
+    public void setTotalLiveTime(Integer totalLiveTime) {
+        this.totalLiveTime = totalLiveTime;
+    }
+
+    public List<ImLiveRoomVideo> getVideoList() {
+        return videoList;
+    }
+
+    public void setVideoList(List<ImLiveRoomVideo> videoList) {
+        this.videoList = videoList;
+    }
+}

+ 102 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/vo/ImLiveBroadcastRoomMemberVo.java

@@ -0,0 +1,102 @@
+package com.ym.mec.biz.dal.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.Date;
+
+/**
+ * @author hgw
+ * Created by 2022-02-25
+ */
+public class ImLiveBroadcastRoomMemberVo implements java.io.Serializable {
+
+    @ApiModelProperty(value = "房间编号")
+    private String roomUid;
+
+    @ApiModelProperty(value = "房间标题")
+    private String roomTitle;
+
+    @ApiModelProperty(value = "学生编号")
+    private Integer studentId;
+
+    @ApiModelProperty(value = "学生姓名")
+    private String studentName;
+
+    @ApiModelProperty(value = "手机号")
+    private String phone;
+
+    @ApiModelProperty(value = "声部名称")
+    private String subName;
+
+    @ApiModelProperty(value = "进入房间时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date joinTime;
+
+    @ApiModelProperty(value = "累计观看时长")
+    private Integer totalViewTime;
+
+    public Integer getStudentId() {
+        return studentId;
+    }
+
+    public void setStudentId(Integer studentId) {
+        this.studentId = studentId;
+    }
+
+    public String getStudentName() {
+        return studentName;
+    }
+
+    public void setStudentName(String studentName) {
+        this.studentName = studentName;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+
+    public String getSubName() {
+        return subName;
+    }
+
+    public void setSubName(String subName) {
+        this.subName = subName;
+    }
+
+    public Date getJoinTime() {
+        return joinTime;
+    }
+
+    public void setJoinTime(Date joinTime) {
+        this.joinTime = joinTime;
+    }
+
+    public Integer getTotalViewTime() {
+        return totalViewTime;
+    }
+
+    public void setTotalViewTime(Integer totalViewTime) {
+        this.totalViewTime = totalViewTime;
+    }
+
+    public String getRoomUid() {
+        return roomUid;
+    }
+
+    public void setRoomUid(String roomUid) {
+        this.roomUid = roomUid;
+    }
+
+    public String getRoomTitle() {
+        return roomTitle;
+    }
+
+    public void setRoomTitle(String roomTitle) {
+        this.roomTitle = roomTitle;
+    }
+}

+ 249 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/vo/ImLiveBroadcastRoomVo.java

@@ -0,0 +1,249 @@
+package com.ym.mec.biz.dal.vo;
+
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 直播房间管理表(ImLiveBroadcastRoom)表实体类
+ *
+ * @author hgw
+ * @since 2022-02-17 20:52:05
+ */
+@ApiModel(value = "im_live_broadcast_room-直播房间管理表")
+public class ImLiveBroadcastRoomVo implements Serializable {
+    @ApiModelProperty(value = "主键")
+    private Integer id;
+
+    @ApiModelProperty(value = "机构id")
+    private Integer tenantId;
+
+    @ApiModelProperty(value = "机构名称")
+    private String tenantName;
+
+    @ApiModelProperty(value = "机构logo")
+    private String tenantLogo;
+
+    @ApiModelProperty(value = "房间编号")
+    private String roomUid;
+
+    @ApiModelProperty(value = "房间标题/最多12个字")
+    private String roomTitle;
+
+    @ApiModelProperty(value = "直播内容/最多200个字")
+    private String liveRemark;
+
+    @ApiModelProperty(value = "主讲人id/老师id")
+    private Integer speakerId;
+
+    @ApiModelProperty(value = "主讲人名称")
+    private String speakerName;
+
+    @ApiModelProperty(value = "主讲人头像")
+    private String speakerPic;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "直播开始时间")
+    private Date liveStartTime;
+
+    @ApiModelProperty(value = "直播状态 0未开始 1开始 2结束")
+    private Integer liveState;
+
+    @ApiModelProperty(value = "房间状态 0正常 1已删除")
+    private Integer roomState;
+
+    @ApiModelProperty(value = "创建人")
+    private String createdByName;
+
+    @ApiModelProperty(value = "预热模版")
+    private String preTemplate;
+
+    @ApiModelProperty(value = "房间配置json格式-是否允许点赞-是否允许聊天互动-是否允许保存直播回放")
+    private String roomConfig;
+
+    @ApiModelProperty(value = "imToken")
+    private String imToken;
+
+    @ApiModelProperty(value = "播出端")
+    private String os = "pc";
+
+    @ApiModelProperty(value = "点赞数")
+    private Integer likeNum;
+    @ApiModelProperty(value = "当前观看人数")
+    private Integer lookNum;
+    @ApiModelProperty(value = "累计观看人数")
+    private Integer totalLookNum;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Integer getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(Integer tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public String getTenantName() {
+        return tenantName;
+    }
+
+    public void setTenantName(String tenantName) {
+        this.tenantName = tenantName;
+    }
+
+    public String getTenantLogo() {
+        return tenantLogo;
+    }
+
+    public void setTenantLogo(String tenantLogo) {
+        this.tenantLogo = tenantLogo;
+    }
+
+    public String getRoomUid() {
+        return roomUid;
+    }
+
+    public void setRoomUid(String roomUid) {
+        this.roomUid = roomUid;
+    }
+
+    public String getRoomTitle() {
+        return roomTitle;
+    }
+
+    public void setRoomTitle(String roomTitle) {
+        this.roomTitle = roomTitle;
+    }
+
+    public String getLiveRemark() {
+        return liveRemark;
+    }
+
+    public void setLiveRemark(String liveRemark) {
+        this.liveRemark = liveRemark;
+    }
+
+    public Integer getSpeakerId() {
+        return speakerId;
+    }
+
+    public void setSpeakerId(Integer speakerId) {
+        this.speakerId = speakerId;
+    }
+
+    public String getSpeakerName() {
+        return speakerName;
+    }
+
+    public void setSpeakerName(String speakerName) {
+        this.speakerName = speakerName;
+    }
+
+    public String getSpeakerPic() {
+        return speakerPic;
+    }
+
+    public void setSpeakerPic(String speakerPic) {
+        this.speakerPic = speakerPic;
+    }
+
+    public Date getLiveStartTime() {
+        return liveStartTime;
+    }
+
+    public void setLiveStartTime(Date liveStartTime) {
+        this.liveStartTime = liveStartTime;
+    }
+
+    public Integer getLiveState() {
+        return liveState;
+    }
+
+    public void setLiveState(Integer liveState) {
+        this.liveState = liveState;
+    }
+
+    public Integer getRoomState() {
+        return roomState;
+    }
+
+    public void setRoomState(Integer roomState) {
+        this.roomState = roomState;
+    }
+
+    public String getCreatedByName() {
+        return createdByName;
+    }
+
+    public void setCreatedByName(String createdByName) {
+        this.createdByName = createdByName;
+    }
+
+    public String getPreTemplate() {
+        return preTemplate;
+    }
+
+    public void setPreTemplate(String preTemplate) {
+        this.preTemplate = preTemplate;
+    }
+
+    public String getRoomConfig() {
+        return roomConfig;
+    }
+
+    public void setRoomConfig(String roomConfig) {
+        this.roomConfig = roomConfig;
+    }
+
+    public String getImToken() {
+        return imToken;
+    }
+
+    public void setImToken(String imToken) {
+        this.imToken = imToken;
+    }
+
+    public String getOs() {
+        return os;
+    }
+
+    public void setOs(String os) {
+        this.os = os;
+    }
+
+    public Integer getLikeNum() {
+        return likeNum;
+    }
+
+    public void setLikeNum(Integer likeNum) {
+        this.likeNum = likeNum;
+    }
+
+    public Integer getLookNum() {
+        return lookNum;
+    }
+
+    public void setLookNum(Integer lookNum) {
+        this.lookNum = lookNum;
+    }
+
+    public Integer getTotalLookNum() {
+        return totalLookNum;
+    }
+
+    public void setTotalLookNum(Integer totalLookNum) {
+        this.totalLookNum = totalLookNum;
+    }
+}
+

+ 100 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/vo/RoomUserInfoVo.java

@@ -0,0 +1,100 @@
+package com.ym.mec.biz.dal.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @author hgw
+ * Created by 2022-02-24
+ */
+public class RoomUserInfoVo implements Serializable {
+    private Integer userId;
+
+    private String userName;
+
+    private Integer tenantId;
+
+    //累计观看时长
+    private Integer totalViewTime;
+
+    //首次进入时间
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date firstJoinTime;
+
+    //动态进入房间时间  多次进入房间每次进入更新
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date dynamicJoinTime;
+
+    //最后一次退出时间 该字段是为了控制连续退出的 如果2次退出时间间隔不足1分钟则不处理
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date lastOutTime;
+
+    //0:在房间 1:不在房间
+    private Integer state;
+
+    public Integer getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Integer userId) {
+        this.userId = userId;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public Integer getTotalViewTime() {
+        return totalViewTime;
+    }
+
+    public void setTotalViewTime(Integer totalViewTime) {
+        this.totalViewTime = totalViewTime;
+    }
+
+    public Date getFirstJoinTime() {
+        return firstJoinTime;
+    }
+
+    public void setFirstJoinTime(Date firstJoinTime) {
+        this.firstJoinTime = firstJoinTime;
+    }
+
+    public Date getDynamicJoinTime() {
+        return dynamicJoinTime;
+    }
+
+    public void setDynamicJoinTime(Date dynamicJoinTime) {
+        this.dynamicJoinTime = dynamicJoinTime;
+    }
+
+    public Date getLastOutTime() {
+        return lastOutTime;
+    }
+
+    public void setLastOutTime(Date lastOutTime) {
+        this.lastOutTime = lastOutTime;
+    }
+
+    public Integer getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(Integer tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public Integer getState() {
+        return state;
+    }
+
+    public void setState(Integer state) {
+        this.state = state;
+    }
+}

+ 18 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/vo/TenantPreJoinVo.java

@@ -0,0 +1,18 @@
+package com.ym.mec.biz.dal.vo;
+
+import com.ym.mec.biz.dal.entity.TenantPreJoin;
+import io.swagger.annotations.ApiModelProperty;
+
+public class TenantPreJoinVo extends TenantPreJoin {
+
+    @ApiModelProperty(value = "推荐人姓名")
+    private String recommenderName;
+
+    public String getRecommenderName() {
+        return recommenderName;
+    }
+
+    public void setRecommenderName(String recommenderName) {
+        this.recommenderName = recommenderName;
+    }
+}

+ 7 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/CloudCoachPaymentProgramService.java

@@ -2,6 +2,7 @@ package com.ym.mec.biz.service;
 
 import com.ym.mec.biz.dal.entity.CloudCoachPaymentProgram;
 import com.ym.mec.common.service.BaseService;
+import org.springframework.transaction.annotation.Transactional;
 
 public interface CloudCoachPaymentProgramService extends BaseService<Long, CloudCoachPaymentProgram> {
 
@@ -13,4 +14,10 @@ public interface CloudCoachPaymentProgramService extends BaseService<Long, Cloud
     * @date 2022/1/14 15:52
     */
     void add(CloudCoachPaymentProgram cloudCoachPaymentProgram);
+
+    void auditPass(CloudCoachPaymentProgram cloudCoachPaymentProgram);
+
+    void modify(CloudCoachPaymentProgram cloudCoachPaymentProgram);
+
+    void audit(CloudCoachPaymentProgram cloudCoachPaymentProgram);
 }

+ 18 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/ImLiveBroadcastRoomDataService.java

@@ -0,0 +1,18 @@
+package com.ym.mec.biz.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ym.mec.biz.dal.dao.ImLiveBroadcastRoomDataDao;
+import com.ym.mec.biz.dal.entity.ImLiveBroadcastRoomData;
+
+/**
+ * 直播房间数据表(ImLiveBroadcastRoomData)表服务接口
+ *
+ * @author hgw
+ * @since 2022-02-21 14:26:58
+ */
+public interface ImLiveBroadcastRoomDataService extends IService<ImLiveBroadcastRoomData> {
+
+    ImLiveBroadcastRoomDataDao getDao();
+
+}
+

+ 33 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/ImLiveBroadcastRoomMemberService.java

@@ -0,0 +1,33 @@
+package com.ym.mec.biz.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ym.mec.biz.dal.dao.ImLiveBroadcastRoomMemberDao;
+import com.ym.mec.biz.dal.entity.ImLiveBroadcastRoomMember;
+import com.ym.mec.biz.dal.vo.ImLiveBroadcastRoomDetailVo;
+import com.ym.mec.biz.dal.vo.ImLiveBroadcastRoomMemberVo;
+import com.ym.mec.common.page.PageInfo;
+
+import java.util.Map;
+
+/**
+ * 直播间人员关系表(ImLiveBroadcastRoomMember)表服务接口
+ *
+ * @author hgw
+ * @since 2022-02-21 14:26:59
+ */
+public interface ImLiveBroadcastRoomMemberService extends IService<ImLiveBroadcastRoomMember> {
+
+    ImLiveBroadcastRoomMemberDao getDao();
+
+    /**
+     * 查询房间详情
+     */
+    ImLiveBroadcastRoomDetailVo queryRoomDetail(Map<String, Object> param);
+
+    /**
+     * 查询房间观看人员详情
+     */
+    PageInfo<ImLiveBroadcastRoomMemberVo> queryRoomMember(Map<String, Object> param);
+
+}
+

+ 67 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/ImLiveBroadcastRoomService.java

@@ -0,0 +1,67 @@
+package com.ym.mec.biz.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ym.mec.biz.dal.dto.ImLiveBroadcastRoomDto;
+import com.ym.mec.biz.dal.entity.ImLiveBroadcastRoom;
+import com.ym.mec.biz.dal.vo.ImLiveBroadcastRoomVo;
+import com.ym.mec.biz.dal.vo.RoomUserInfoVo;
+import com.ym.mec.common.entity.ImUserState;
+import com.ym.mec.common.page.PageInfo;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 直播房间管理表(ImLiveBroadcastRoom)表服务接口
+ *
+ * @author hgw
+ * @since 2022-02-17 20:52:05
+ */
+public interface ImLiveBroadcastRoomService extends IService<ImLiveBroadcastRoom> {
+
+    PageInfo<ImLiveBroadcastRoomVo> queryPage(Map<String, Object> param);
+
+    ImLiveBroadcastRoomVo queryRoomAndCheck(String roomUid, Integer userId);
+
+    ImLiveBroadcastRoomVo queryRoomInfo(String roomUid);
+
+    void add(ImLiveBroadcastRoomDto dto);
+
+    void update(ImLiveBroadcastRoomDto dto);
+
+    void whetherChat(Integer id, Integer whetherChat);
+
+    void roomDestroy(Integer id);
+
+    void delete(Integer id);
+
+    void destroyExpiredLiveRoom();
+
+    void syncLike(String roomUid, Integer likeNum);
+
+    void opsRoom(List<ImUserState> userState);
+
+    ImLiveBroadcastRoomVo speakerJoinRoom(String roomUid);
+
+    void joinRoom(String roomUid, Integer userId);
+
+    void startLive(String roomUid,Integer userId);
+
+    void closeLive(String roomUid,Integer userId);
+
+    void createLiveRoom();
+
+    Map<String, Object> test(String roomUid, Integer userId);
+
+    /**
+    * @description: 分享直播链接
+     * @param roomUid
+    * @return void
+    * @author zx
+    * @date 2022/2/23 16:17
+    */
+    void shareGroup(String roomUid,String groupIds);
+
+    List<RoomUserInfoVo> queryRoomUserInfo(String roomUid);
+}
+

+ 21 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/ImLiveRoomVideoService.java

@@ -0,0 +1,21 @@
+package com.ym.mec.biz.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ym.mec.biz.dal.dao.ImLiveRoomVideoDao;
+import com.ym.mec.biz.dal.entity.ImLiveRoomVideo;
+
+import java.util.List;
+
+/**
+ * 直播视频记录(ImLiveRoomVideo)表服务接口
+ *
+ * @author hgw
+ * @since 2022-03-07 19:06:55
+ */
+public interface ImLiveRoomVideoService extends IService<ImLiveRoomVideo> {
+
+    ImLiveRoomVideoDao getDao();
+
+    List<ImLiveRoomVideo> queryList(String roomUid);
+}
+

+ 3 - 20
mec-biz/src/main/java/com/ym/mec/biz/service/MusicGroupPaymentCalenderDetailService.java

@@ -1,10 +1,5 @@
 package com.ym.mec.biz.service;
 
-import java.math.BigDecimal;
-import java.util.Date;
-import java.util.List;
-import java.util.Set;
-
 import com.ym.mec.biz.dal.dto.FeeStudentDto;
 import com.ym.mec.biz.dal.dto.MusicArrearageStudentDto;
 import com.ym.mec.biz.dal.dto.MusicGroupPaymentCalenderDetailDto;
@@ -13,20 +8,14 @@ import com.ym.mec.biz.dal.entity.*;
 import com.ym.mec.biz.dal.page.ArrearageStudentsQueryInfo;
 import com.ym.mec.biz.dal.page.MusicCalenderDetailQueryInfo;
 import com.ym.mec.common.page.PageInfo;
-import com.ym.mec.common.page.QueryInfo;
 import com.ym.mec.common.service.BaseService;
 
-import org.apache.ibatis.annotations.Param;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
 
 public interface MusicGroupPaymentCalenderDetailService extends BaseService<Long, MusicGroupPaymentCalenderDetail> {
 
-    /**
-     * 修改学员预计缴费金额
-     * @param expectAmount
-     * @param ids
-     * @return
-     */
-//    void updateExpectAmount(BigDecimal expectAmount,BigDecimal expectMemberAmount,String ids);
 
     /**
      * 开启缴费
@@ -49,12 +38,6 @@ public interface MusicGroupPaymentCalenderDetailService extends BaseService<Long
      */
     void refreshUserMusicGroupPaymentStatusTask();
 
-    /**
-     * 乐团缴费记录新增学员
-     * @param musicGroupPaymentCalenderId
-     * @param userIdList
-     */
-    void batchAdd(Long musicGroupPaymentCalenderId, Set<Integer> userIdList,MusicGroup musicGroup,Boolean autoCreate);
 
     /**
      * 跨团合班新增学员

+ 22 - 17
mec-biz/src/main/java/com/ym/mec/biz/service/MusicGroupPaymentCalenderService.java

@@ -1,15 +1,20 @@
 package com.ym.mec.biz.service;
 
-import java.math.BigDecimal;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 import com.ym.mec.biz.dal.dto.*;
-import com.ym.mec.biz.dal.entity.*;
+import com.ym.mec.biz.dal.entity.MusicGroup;
+import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender;
+import com.ym.mec.biz.dal.entity.MusicGroupStudentFee;
+import com.ym.mec.biz.dal.page.BaseOrganQueryInfo;
 import com.ym.mec.biz.dal.page.MusicGroupPaymentCalenderQueryInfo;
+import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.service.BaseService;
+import org.springframework.ui.ModelMap;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 public interface MusicGroupPaymentCalenderService extends BaseService<Long, MusicGroupPaymentCalender> {
 
@@ -25,7 +30,7 @@ public interface MusicGroupPaymentCalenderService extends BaseService<Long, Musi
 	 * @param musicGroupPaymentBaseCalender
 	 * @return
 	 */
-	String create1(MusicGroupPaymentBaseCalender musicGroupPaymentBaseCalender);
+	HttpResponseResult<ModelMap> create1(MusicGroupPaymentBaseCalender musicGroupPaymentBaseCalender);
 	
 	/**
 	 * 获取明细
@@ -52,11 +57,9 @@ public interface MusicGroupPaymentCalenderService extends BaseService<Long, Musi
 	/**
 	 * 进行中加学员
 	 * @param musicGroupPaymentCalender
-	 * @param musicGroupPaymentCalenderCourseSettingsList
 	 * @param musicGroup
 	 */
 	void addStudent(MusicGroupPaymentCalender musicGroupPaymentCalender,
-					List<MusicGroupPaymentCalenderCourseSettings> musicGroupPaymentCalenderCourseSettingsList,
 					MusicGroup musicGroup);
 
 
@@ -130,13 +133,6 @@ public interface MusicGroupPaymentCalenderService extends BaseService<Long, Musi
 	void auditPass(String batchNo,String auditMemo);
 
 	/**
-	 * 审核通过后自动排课
-	 * @author zouxuan
-	 * @param batchNo
-	 */
-	public void autoClassGroupAdjust(MusicGroupStudentClassAdjust musicGroupStudentClassAdjust);
-
-	/**
 	 * @describe 审核拒绝
 	 * @apiNote 时光荏苒,认真工作的时间总是过得很快,而我、享受这一刻!
 	 * @author zouxuan
@@ -195,7 +191,7 @@ public interface MusicGroupPaymentCalenderService extends BaseService<Long, Musi
 	* @author zx
 	* @date 2021/12/27 20:43
 	*/
-    String merge1(MusicGroupPaymentBaseCalender musicGroupPaymentBaseCalender);
+	HttpResponseResult<ModelMap> merge1(MusicGroupPaymentBaseCalender musicGroupPaymentBaseCalender);
 
     MusicGroupPaymentCalender getMusicGroupRegCalender(String musicGroupId);
 
@@ -216,4 +212,13 @@ public interface MusicGroupPaymentCalenderService extends BaseService<Long, Musi
 	* @date 2021/12/30 10:41
 	*/
 	MusicGroupPaymentCalender getApplyCalenderByMusicId(String musicGroupId);
+
+	/**
+	* @description: 学员已排课时长未消耗完
+	 * @param queryInfo
+	* @return com.ym.mec.common.page.PageInfo<com.ym.mec.biz.dal.dto.HasFreeCourseTimesDto>
+	* @author zx
+	* @date 2022/3/4 11:35
+	*/
+	PageInfo<HasFreeCourseTimesDto> queryHasFreeCourseTimesStudent(BaseOrganQueryInfo queryInfo);
 }

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

@@ -80,4 +80,6 @@ public interface OrganizationService extends BaseService<Integer, Organization>
     <T extends EducationBaseQueryInfo> T onlyEducation(T queryInfo);
     
     boolean updateBasicInfo(Organization organization);
+
+    Long add(Organization organization);
 }

+ 10 - 40
mec-biz/src/main/java/com/ym/mec/biz/service/QuestionnaireUserResultService.java

@@ -1,28 +1,17 @@
 package com.ym.mec.biz.service;
 
-import com.alibaba.fastjson.JSONObject;
-import com.ym.mec.biz.dal.dto.ExportDto;
+import com.ym.mec.biz.dal.dto.QuestionnaireUserResultDto;
 import com.ym.mec.biz.dal.dto.ReplacementInstrumentActivityDto;
 import com.ym.mec.biz.dal.entity.QuestionnaireQuestion;
+import com.ym.mec.biz.dal.entity.QuestionnaireTopic;
 import com.ym.mec.biz.dal.entity.QuestionnaireUserResult;
-import com.ym.mec.biz.dal.enums.ExportEnum;
-import com.ym.mec.biz.dal.enums.QuestionnaireActiveTypeEnum;
 import com.ym.mec.biz.dal.page.QuestionnaireUserResultQueryInfo;
-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.service.BaseService;
-import com.ym.mec.common.tenant.TenantContextHolder;
-import com.ym.mec.util.date.DateUtil;
-import com.ym.mec.util.excel.POIUtil;
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.*;
-import java.util.stream.Collectors;
-
-import static com.ym.mec.biz.dal.enums.QuestionnaireActiveTypeEnum.CLOUD_TEACHER_FEEDBACK;
+import java.util.List;
+import java.util.Map;
 
 public interface QuestionnaireUserResultService extends BaseService<Long, QuestionnaireUserResult> {
 
@@ -32,11 +21,11 @@ public interface QuestionnaireUserResultService extends BaseService<Long, Questi
 
     /**
      *
-     * @param cooperationId
+     * @param topic
      * @param questionList
      * @return
      */
-    Map<String,Object> questionnaireUserResultExport(String activeType,Integer cooperationId, List<QuestionnaireQuestion> questionList);
+    Map<String,Object> getExportBody(QuestionnaireTopic topic,List<QuestionnaireQuestion> questionList);
 
     /**
      * 提交调查问卷
@@ -54,28 +43,9 @@ public interface QuestionnaireUserResultService extends BaseService<Long, Questi
     */
     void addResult(ReplacementInstrumentActivityDto replacementInstrumentActivity);
 
-    Object queryResultPage(QuestionnaireUserResultQueryInfo queryInfo);
-
-    /**
-    * @description: 获取问卷导出字段
-     * @param
-    * @return java.util.List<java.lang.String>
-    * @author zx
-    * @date 2022/2/14 11:18
-    */
-    List<String> getExportFields(Integer cooperationId, QuestionnaireActiveTypeEnum activeType,List<QuestionnaireQuestion> questionList);
-
-    /**
-    * @description: 获取问卷导出字段
-     * @param
-    * @return java.util.List<java.lang.String>
-    * @author zx
-    * @date 2022/2/14 11:18
-    */
-    Set<String> getExportBody(Integer cooperationId, QuestionnaireActiveTypeEnum activeType,List<QuestionnaireQuestion> questionList);
+    PageInfo<QuestionnaireUserResultDto> queryResultPage(QuestionnaireUserResultQueryInfo queryInfo);
 
-    List<QuestionnaireQuestion> getQuestionnaireQuestions(Integer cooperationId, QuestionnaireActiveTypeEnum activeType);
+    String[] getExportHeader(QuestionnaireTopic topic, List<QuestionnaireQuestion> questionList);
 
-    //导出问卷调查
-    void questionnaireUserResultExport(HttpServletResponse response, ExportDto exportDto) throws Exception;
+    QuestionnaireUserResultDto queryUserResult(Integer topicId);
 }

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

@@ -3,6 +3,7 @@ package com.ym.mec.biz.service;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ym.mec.biz.dal.dto.TenantPreJoinDto;
 import com.ym.mec.biz.dal.entity.TenantPreJoin;
+import com.ym.mec.biz.dal.vo.TenantPreJoinVo;
 import com.ym.mec.common.page.PageInfo;
 
 import java.util.Map;
@@ -15,7 +16,7 @@ import java.util.Map;
  */
 public interface TenantPreJoinService extends IService<TenantPreJoin> {
 
-    PageInfo<TenantPreJoin> queryPage(Map<String, Object> param);
+    PageInfo<TenantPreJoinVo> queryPage(Map<String, Object> param);
 
     int insert(TenantPreJoinDto obj);
 

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

@@ -159,6 +159,8 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
     private MusicGroupSchoolTermStudentCourseDetailDao musicGroupSchoolTermStudentCourseDetailDao;
     @Autowired
     private MusicGroupSchoolTermCourseDetailDao musicGroupSchoolTermCourseDetailDao;
+    @Autowired
+    private MusicGroupPaymentStudentCourseDetailDao musicGroupPaymentStudentCourseDetailDao;
 
     @Override
     public BaseDAO<Integer, ClassGroup> getDAO() {
@@ -210,14 +212,15 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
             throw new BizException("主教与助教存在冲突");
         }
 
+        //疫情原因去掉这块限制
         //基础技能班和线上基础技能班,可分班原则为声部人数/6向上取整
-        if (classGroup.getType().equals(HIGH_ONLINE) || classGroup.getType().equals(HIGH)) {
-            HighClassGroupNumDto highClassGroupNumDto = getSubjectMaxHighClassGroupNum(classGroup.getMusicGroupId(), classGroup.getType());
-            if (highClassGroupNumDto.getNowHighClassGroupNum() >= highClassGroupNumDto.getMaxHighClassGroupNum()) {
-                String errMsg = classGroup.getType().equals(HIGH_ONLINE) ? "线上基础技能班" : "基础技能班";
-                throw new BizException("此乐团," + errMsg + "数量不能大于" + highClassGroupNumDto.getMaxHighClassGroupNum());
-            }
-        }
+//        if (classGroup.getType().equals(HIGH_ONLINE) || classGroup.getType().equals(HIGH)) {
+//            HighClassGroupNumDto highClassGroupNumDto = getSubjectMaxHighClassGroupNum(classGroup.getMusicGroupId(), classGroup.getType());
+//            if (highClassGroupNumDto.getNowHighClassGroupNum() >= highClassGroupNumDto.getMaxHighClassGroupNum()) {
+//                String errMsg = classGroup.getType().equals(HIGH_ONLINE) ? "线上基础技能班" : "基础技能班";
+//                throw new BizException("此乐团," + errMsg + "数量不能大于" + highClassGroupNumDto.getMaxHighClassGroupNum());
+//            }
+//        }
 
         String userIds = classGroup.getUserIds();
 
@@ -2364,6 +2367,7 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
         Date date = new Date();
         Integer classGroupId = classGroup4MixDtos.get(0).getClassGroupId();
         String musicGroupId = classGroup4MixDtos.get(0).getMusicGroupId();
+//        Boolean checkCourseTimesFlag = classGroup4MixDtos.get(0).getCheckCourseTimesFlag();
         ClassGroup classGroup = classGroupDao.get(classGroupId);
         if (classGroup == null) {
             throw new BizException("班级不存在");
@@ -2444,6 +2448,15 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
         //计算每节课的课酬
         List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaryList = new ArrayList<>();
         List<CourseSchedule> courseScheduleList = new ArrayList<>();
+        List<CourseScheduleType> courseTypes = classGroup4MixDtos.stream().map(e -> e.getCourseType()).distinct().collect(Collectors.toList());
+        /*if(!checkCourseTimesFlag){
+            //校验剩余时长是否一致
+            Integer checkCourseTimes = musicGroupPaymentStudentCourseDetailDao.checkCourseTimes(musicGroupId, courseTypes, studentIds);
+            if(checkCourseTimes == null || checkCourseTimes == 0){
+                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+                return BaseController.failed(HttpStatus.ALREADY_REPORTED,"班级剩余排课时长不一致,请再次确认");
+            }
+        }*/
 
         for (ClassGroup4MixDto classGroup4MixDto : classGroup4MixDtos) {
             List<ClassGroupTeacherMapper> teacherMappers = classGroup4MixDto.getClassGroupTeacherMapperList();

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

@@ -1,5 +1,7 @@
 package com.ym.mec.biz.service.impl;
 
+import com.ym.mec.auth.api.client.SysUserFeignService;
+import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.biz.dal.dao.*;
 import com.ym.mec.biz.dal.entity.CloudCoachPaymentProgram;
 import com.ym.mec.biz.dal.entity.CloudTeacherOrder;
@@ -23,6 +25,8 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
+import java.time.Instant;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -48,6 +52,8 @@ public class CloudCoachPaymentProgramServiceImpl extends BaseServiceImpl<Long, C
 	private SysMessageService sysMessageService;
 	@Autowired
 	private TeacherDao teacherDao;
+	@Autowired
+	private SysUserFeignService sysUserFeignService;
 
 	@Override
 	public BaseDAO<Long, CloudCoachPaymentProgram> getDAO() {
@@ -74,15 +80,41 @@ public class CloudCoachPaymentProgramServiceImpl extends BaseServiceImpl<Long, C
 		cloudCoachPaymentProgram.setName(memberRankSetting.getName());
 		cloudCoachPaymentProgram.setUserNum(userIds.size());
 		cloudCoachPaymentProgram.setTenantId(tenantId);
-		//是否0元购买
-		Boolean isFree = cloudCoachPaymentProgram.getActualAmount().compareTo(BigDecimal.ZERO) == 0;
-		if(isFree){cloudCoachPaymentProgram.setPaymentUserNum(userIds.size());}
+		//获取缴费状态
+		cloudCoachPaymentProgram.setStatus(getStatus(cloudCoachPaymentProgram));
 		cloudCoachPaymentProgramDao.insert(cloudCoachPaymentProgram);
+		studentCloudCoachPaymentDetailsDao.batchInsert(cloudCoachPaymentProgram.getId(),userIds,tenantId);
+		if(cloudCoachPaymentProgram.getStatus() == CloudCoachPaymentProgram.StatusEnum.OPEN){
+			this.auditPass(cloudCoachPaymentProgram);
+		}
+	}
 
-		//批量插入学员缴费项目
-		studentCloudCoachPaymentDetailsDao.batchInsert(cloudCoachPaymentProgram.getId(),isFree?1:0,userIds,tenantId);
+	private CloudCoachPaymentProgram.StatusEnum getStatus(CloudCoachPaymentProgram cloudCoachPaymentProgram){
+		//价格是否变动
+		//获取现价
+		BigDecimal groupPurchaseFee = memberFeeSettingService.getAmount(cloudCoachPaymentProgram.getOrganId(),
+				cloudCoachPaymentProgram.getMemberRankSettingId(),
+				cloudCoachPaymentProgram.getPeriod(),
+				cloudCoachPaymentProgram.getMemberNum(),
+				MemberFeeSettingServiceImpl::getGroupPurchaseFee);
+		if(cloudCoachPaymentProgram.getActualAmount().compareTo(groupPurchaseFee) == 0){
+			return CloudCoachPaymentProgram.StatusEnum.OPEN;
+		}else {
+			return CloudCoachPaymentProgram.StatusEnum.AUDITING;
+		}
+	}
+
+	@Transactional(rollbackFor = Exception.class)
+	@Override
+	public void auditPass(CloudCoachPaymentProgram cloudCoachPaymentProgram){
+		List<Integer> userIds = cloudCoachPaymentProgram.getUserIds();
+		//是否0元购买
+		Boolean isFree = cloudCoachPaymentProgram.getActualAmount().compareTo(BigDecimal.ZERO) == 0;
 		//如果是0元订单,保存为待激活的云教练订单
 		if(isFree){
+			cloudCoachPaymentProgram.setPaymentUserNum(userIds.size());
+			cloudCoachPaymentProgramDao.update(cloudCoachPaymentProgram);
+			studentCloudCoachPaymentDetailsDao.updatePaymentStatus(cloudCoachPaymentProgram.getId());
 			CloudTeacherOrder cloudTeacherOrder = new CloudTeacherOrder();
 			cloudTeacherOrder.setTime(cloudCoachPaymentProgram.getMemberNum().intValue());
 			cloudTeacherOrder.setOrganId(cloudCoachPaymentProgram.getOrganId());
@@ -108,4 +140,46 @@ public class CloudCoachPaymentProgramServiceImpl extends BaseServiceImpl<Long, C
 					null,0,notifyUrl.toString(),"STUDENT");
 		}
 	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public void modify(CloudCoachPaymentProgram cloudCoachPaymentProgram) {
+		CloudCoachPaymentProgram paymentProgram = cloudCoachPaymentProgramDao.getLock(cloudCoachPaymentProgram.getId());
+		if(paymentProgram.getStatus() != CloudCoachPaymentProgram.StatusEnum.REJECT){
+			throw new BizException("当前状态缴费项目不可编辑");
+		}
+		cloudCoachPaymentProgram.setStatus(getStatus(cloudCoachPaymentProgram));
+		cloudCoachPaymentProgramDao.update(cloudCoachPaymentProgram);
+		if(cloudCoachPaymentProgram.getStatus() == CloudCoachPaymentProgram.StatusEnum.OPEN){
+			List<Integer> userIds = studentCloudCoachPaymentDetailsDao.findUserByProgramId(cloudCoachPaymentProgram.getId());
+			cloudCoachPaymentProgram.setUserIds(userIds);
+			this.auditPass(cloudCoachPaymentProgram);
+		}
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public void audit(CloudCoachPaymentProgram cloudCoachPaymentProgram) {
+		CloudCoachPaymentProgram paymentProgram = cloudCoachPaymentProgramDao.getLock(cloudCoachPaymentProgram.getId());
+		if(paymentProgram.getStatus() != CloudCoachPaymentProgram.StatusEnum.AUDITING){
+			throw new BizException("当前状态缴费项目不可审核");
+		}
+		CloudCoachPaymentProgram.StatusEnum status = cloudCoachPaymentProgram.getStatus();
+		if(status == CloudCoachPaymentProgram.StatusEnum.AUDITING){
+			throw new BizException("审核状态异常");
+		}
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		paymentProgram.setStatus(status);
+		paymentProgram.setMemo(cloudCoachPaymentProgram.getMemo());
+		Date date = new Date();
+		paymentProgram.setUpdateTime(date);
+		paymentProgram.setAuditTime(date);
+		paymentProgram.setAudit(sysUser.getId());
+		cloudCoachPaymentProgramDao.update(paymentProgram);
+		if(status == CloudCoachPaymentProgram.StatusEnum.OPEN){
+			List<Integer> userIds = studentCloudCoachPaymentDetailsDao.findUserByProgramId(paymentProgram.getId());
+			paymentProgram.setUserIds(userIds);
+			this.auditPass(paymentProgram);
+		}
+	}
 }

+ 2 - 25
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ExportServiceImpl.java

@@ -1370,7 +1370,7 @@ public class ExportServiceImpl implements ExportService {
         if (sysUser == null || sysUser.getId() == null) {
             return BaseController.failed(HttpStatus.FORBIDDEN, "请登录");
         }
-        queryInfo.setOrganId(organizationService.getEmployeeOrgan(sysUser.getId(),queryInfo.getOrganId(),sysUser.getIsSuperAdmin()));
+        queryInfo.setRoutingOrganId(organizationService.getEmployeeOrgan(sysUser.getId(),queryInfo.getRoutingOrganId(),sysUser.getIsSuperAdmin()));
         if (StringUtils.isNotBlank(queryInfo.getSearch())) {
             List<BasicUserDto> users = studentPaymentOrderDao.getUsers(queryInfo.getSearch());
             List<Integer> userIds = users.stream().map(BasicUserDto::getUserId).collect(Collectors.toList());
@@ -1389,7 +1389,7 @@ public class ExportServiceImpl implements ExportService {
         if (count > 50000) {
             return BaseController.failed("数据集太大,不能导出.最大数据集不能超过50000");
         }
-        queryInfo.setRoutingOrganId(null);
+//        queryInfo.setRoutingOrganId(null);
         ManagerDownload managerDownload = saveManagerDownload(ExportTypeEnum.ROUTE_ORDER,sysUser.getId());
         ExecutorService executor = Executors.newCachedThreadPool();
         CompletableFuture.runAsync(()->{
@@ -2348,29 +2348,6 @@ public class ExportServiceImpl implements ExportService {
 
         HSSFWorkbook workbook = null;
         try {
-        	/*if(isPlatformUser){
-                String[] header = {"序号", "学生编号", "学生姓名", "交易流水号", "订单编号", "收款渠道", "收款账户", "订单金额", "应付金额",
-                        "现金支付", "余额支付", "分润账户", "分润金额", "分配余额", "优惠金额", "乐团课", "VIP课", "网管课", "乐理课",
-                        "考级", "维修费用", "乐保费用", "团练宝", "押金", "乐器", "教辅费用", "上门费", "账户充值", "其它", "汇付手续费", "平台手续费", "到账时间",
-                        "关联乐团ID/VIP课ID", "课程形态", "零星收款类别", "专业", "分部", "教学点", "合作单位", "乐团主管", "备注"};
-                String[] body = {"id", "userId", "user.username", "transNo", "orderNo", "paymentChannel", "merNos", "orderAmount"
-                        , "expectAmount", "actualAmount", "balancePaymentAmount", "routeMerNo", "routeAmount", "routeBalance",  "couponRemitFee",
-                        "musicGroupCourseFee", "vipCourseFee", "practiceCourseFee", "theoryCourseFee", "degreeFee", "repairFee", "maintenanceFee", "cloudTeacherFee", "leaseFee", "musicalFee", "teachingFee", "visitFee",
-                        "rechargeFee", "otherFee", "transferFee", "platformFee", "payTime", "musicGroupId",
-                        "groupType.desc", "sporadicType", "subjectName", "organName", "schoolName", "cooperationOrganName", "eduTeacher", "memo"};
-                workbook = POIUtil.exportExcel(header, body, studentPaymentOrderExportDtos);
-        	}else{
-                String[] header = {"序号", "学生编号", "学生姓名", "交易流水号", "订单编号", "收款渠道", "收款账户", "订单金额", "应付金额",
-                        "现金支付", "余额支付", "分润账户", "分润金额", "分配余额", "优惠金额", "乐团课", "VIP课", "网管课", "乐理课",
-                        "考级", "维修费用", "乐保费用", "团练宝", "押金", "乐器", "教辅费用", "上门费", "账户充值", "其它", "平台手续费", "到账时间",
-                        "关联乐团ID/VIP课ID", "课程形态", "零星收款类别", "专业", "分部", "教学点", "合作单位", "乐团主管", "备注"};
-                String[] body = {"id", "userId", "user.username", "transNo", "orderNo", "paymentChannel", "merNos", "orderAmount"
-                        , "expectAmount", "actualAmount", "balancePaymentAmount", "routeMerNo", "routeAmount", "routeBalance",  "couponRemitFee",
-                        "musicGroupCourseFee", "vipCourseFee", "practiceCourseFee", "theoryCourseFee", "degreeFee", "repairFee", "maintenanceFee", "cloudTeacherFee", "leaseFee", "musicalFee", "teachingFee", "visitFee",
-                        "rechargeFee", "otherFee", "platformFee", "payTime", "musicGroupId",
-                        "groupType.desc", "sporadicType", "subjectName", "organName", "schoolName", "cooperationOrganName", "eduTeacher", "memo"};
-                workbook = POIUtil.exportExcel(header, body, studentPaymentOrderExportDtos);
-        	}*/
             Map<String, String> headMap = getExportMap(new ExportDto(ExportEnum.ROUTE_ORDER_LIST1, headColumns));
             String[] header = headMap.keySet().toArray(new String[headMap.keySet().size()]);
             String[] body = headMap.values().toArray(new String[headMap.keySet().size()]);

+ 28 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ImLiveBroadcastRoomDataServiceImpl.java

@@ -0,0 +1,28 @@
+package com.ym.mec.biz.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ym.mec.biz.dal.dao.ImLiveBroadcastRoomDataDao;
+import com.ym.mec.biz.dal.entity.ImLiveBroadcastRoomData;
+import com.ym.mec.biz.service.ImLiveBroadcastRoomDataService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+/**
+ * 直播房间数据表(ImLiveBroadcastRoomData)表服务实现类
+ *
+ * @author hgw
+ * @since 2022-02-21 14:26:58
+ */
+@Service("imLiveBroadcastRoomDataService")
+public class ImLiveBroadcastRoomDataServiceImpl extends ServiceImpl<ImLiveBroadcastRoomDataDao, ImLiveBroadcastRoomData> implements ImLiveBroadcastRoomDataService {
+
+    private final static Logger log = LoggerFactory.getLogger(ImLiveBroadcastRoomDataServiceImpl.class);
+
+    @Override
+    public ImLiveBroadcastRoomDataDao getDao() {
+        return this.baseMapper;
+    }
+
+}
+

+ 62 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ImLiveBroadcastRoomMemberServiceImpl.java

@@ -0,0 +1,62 @@
+package com.ym.mec.biz.service.impl;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ym.mec.biz.dal.dao.ImLiveBroadcastRoomMemberDao;
+import com.ym.mec.biz.dal.entity.ImLiveBroadcastRoomMember;
+import com.ym.mec.biz.dal.vo.ImLiveBroadcastRoomDetailVo;
+import com.ym.mec.biz.dal.vo.ImLiveBroadcastRoomMemberVo;
+import com.ym.mec.biz.service.ImLiveBroadcastRoomDataService;
+import com.ym.mec.biz.service.ImLiveBroadcastRoomMemberService;
+import com.ym.mec.biz.service.ImLiveRoomVideoService;
+import com.ym.mec.common.page.PageInfo;
+import com.ym.mec.common.page.PageUtil;
+import com.ym.mec.common.page.WrapperUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+/**
+ * 直播间人员关系表(ImLiveBroadcastRoomMember)表服务实现类
+ *
+ * @author hgw
+ * @since 2022-02-21 14:26:59
+ */
+@Service("imLiveBroadcastRoomMemberService")
+public class ImLiveBroadcastRoomMemberServiceImpl extends ServiceImpl<ImLiveBroadcastRoomMemberDao, ImLiveBroadcastRoomMember> implements ImLiveBroadcastRoomMemberService {
+
+    private final static Logger log = LoggerFactory.getLogger(ImLiveBroadcastRoomMemberServiceImpl.class);
+
+    @Autowired
+    private ImLiveBroadcastRoomDataService imLiveBroadcastRoomDataService;
+@Autowired
+private ImLiveRoomVideoService imLiveRoomVideoService;
+
+
+    @Override
+    public ImLiveBroadcastRoomMemberDao getDao() {
+        return this.baseMapper;
+    }
+
+    /**
+     * 查询直播详情
+     */
+    @Override
+    public ImLiveBroadcastRoomDetailVo queryRoomDetail(Map<String, Object> param) {
+        String roomUid = WrapperUtil.toStr(param, "roomUid", "请传入房间编号");
+        ImLiveBroadcastRoomDetailVo vo = imLiveBroadcastRoomDataService.getDao().queryByRoomUid(roomUid);
+        vo.setVideoList(imLiveRoomVideoService.queryList(roomUid));
+        return vo;
+    }
+
+    @Override
+    public PageInfo<ImLiveBroadcastRoomMemberVo> queryRoomMember(Map<String, Object> param) {
+        Page<ImLiveBroadcastRoomMemberVo> pageInfo = PageUtil.getPageInfo(param);
+        return PageUtil.pageInfo(baseMapper.queryMemberPage(pageInfo, param));
+    }
+
+}
+

+ 980 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ImLiveBroadcastRoomServiceImpl.java

@@ -0,0 +1,980 @@
+package com.ym.mec.biz.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ym.mec.auth.api.client.SysUserFeignService;
+import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.biz.dal.dao.ImLiveBroadcastRoomDao;
+import com.ym.mec.biz.dal.dao.SysConfigDao;
+import com.ym.mec.biz.dal.dto.ImLiveBroadcastRoomDto;
+import com.ym.mec.biz.dal.entity.ImLiveBroadcastRoom;
+import com.ym.mec.biz.dal.entity.ImLiveBroadcastRoomData;
+import com.ym.mec.biz.dal.entity.ImLiveBroadcastRoomMember;
+import com.ym.mec.biz.dal.enums.MessageTypeEnum;
+import com.ym.mec.biz.dal.vo.ImLiveBroadcastRoomVo;
+import com.ym.mec.biz.dal.vo.RoomUserInfoVo;
+import com.ym.mec.biz.service.*;
+import com.ym.mec.common.entity.ImRoomMessage;
+import com.ym.mec.common.entity.ImUserState;
+import com.ym.mec.common.exception.BizException;
+import com.ym.mec.common.page.PageInfo;
+import com.ym.mec.common.page.PageUtil;
+import com.ym.mec.common.page.WrapperUtil;
+import com.ym.mec.common.tenant.TenantContextHolder;
+import com.ym.mec.im.ImFeignService;
+import com.ym.mec.util.date.DateUtil;
+import com.ym.mec.util.http.HttpUtil;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.redisson.api.RBucket;
+import org.redisson.api.RMap;
+import org.redisson.api.RedissonClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.Serializable;
+import java.util.*;
+import java.util.function.BiConsumer;
+import java.util.stream.Collectors;
+
+/**
+ * 直播房间管理表(ImLiveBroadcastRoom)表服务实现类
+ *
+ * @author hgw
+ * @since 2022-02-17 20:52:05
+ */
+@Service("imLiveBroadcastRoomService")
+public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastRoomDao, ImLiveBroadcastRoom> implements ImLiveBroadcastRoomService {
+
+    private final static Logger log = LoggerFactory.getLogger(ImLiveBroadcastRoomServiceImpl.class);
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private ImFeignService imFeignService;
+    @Autowired
+    private RedissonClient redissonClient;
+    @Autowired
+    private SysMessageService sysMessageService;
+    @Autowired
+    private SysConfigDao sysConfigDao;
+    @Autowired
+    private ImLiveBroadcastRoomMemberService liveBroadcastRoomMemberService;
+    @Autowired
+    private ImLiveBroadcastRoomDataService liveBroadcastRoomDataService;
+
+    public static final String USER_ID = "${userId}";
+    public static final String ROOM_UID = "${roomUid}";
+
+    //直播间累计用户信息-指只要进入到该房间的用户都要记录
+    public static final String LIVE_ROOM_TOTAL_USER_LIST = "IM:LIVE_ROOM_TOTAL_USER_LIST:" + ROOM_UID;
+    //主讲人信息
+    public static final String LIVE_SPEAKER_INFO = "IM:LIVE_SPEAKER_INFO:" + USER_ID;
+    //用户对应的直播间Uid
+    public static final String LIVE_USER_ROOM = "IM:LIVE_ROOM_USER:" + USER_ID;
+    //房间点赞数
+    public static final String LIVE_ROOM_LIKE = "IM:LIVE_ROOM_LIKE:" + ROOM_UID;
+
+    /**
+     * 进入直播间检查数据
+     *
+     * @param roomUid 房间uid
+     * @param userId  用户id
+     */
+    @Override
+    public ImLiveBroadcastRoomVo queryRoomAndCheck(String roomUid, Integer userId) {
+        SysUser sysUser;
+        if (Objects.isNull(userId)) {
+            sysUser = getSysUser();
+        } else {
+            sysUser = getSysUser(userId);
+        }
+        return queryRoomAndCheck(roomUid, sysUser);
+    }
+
+    public ImLiveBroadcastRoomVo queryRoomAndCheck(String roomUid, SysUser sysUser) {
+        //直播间信息校验
+        Optional<ImLiveBroadcastRoomVo> optional = Optional.ofNullable(roomUid)
+                .map(this::queryRoomInfo);
+        optional.orElseThrow(() -> new BizException("直播间不存在"));
+        optional.filter(r -> r.getTenantId().equals(sysUser.getTenantId()))
+                .orElseThrow(() -> new BizException("您不是该直播机构人员,不可观看!"));
+        optional.filter(r -> r.getRoomState() != 1).orElseThrow(() -> new BizException("直播间不存在"));
+        ImLiveBroadcastRoomVo room = optional.get();
+        if (room.getLiveState() == 0) {
+            throw new BizException("直播未开始,直播开启的时间是 "
+                    + DateUtil.format(room.getLiveStartTime(), DateUtil.EXPANDED_DATE_TIME_FORMAT));
+        }
+        if (room.getLiveState() == 2) {
+            throw new BizException("直播已结束!");
+        }
+        return room;
+    }
+
+
+    /**
+     * 查询直播间信息
+     *
+     * @param roomUid 直播间uid
+     */
+    @Override
+    public ImLiveBroadcastRoomVo queryRoomInfo(String roomUid) {
+        List<ImLiveBroadcastRoomVo> list = baseMapper.queryPage(new HashMap<String, Object>() {{
+            put("roomUid", roomUid);
+        }});
+        if (CollectionUtils.isEmpty(list)) {
+            return null;
+        }
+        ImLiveBroadcastRoomVo roomVo = list.get(0);
+        getRoomData(roomVo);
+        return roomVo;
+    }
+
+    /**
+     * 分页查询直播间列表
+     */
+    @Override
+    public PageInfo<ImLiveBroadcastRoomVo> queryPage(Map<String, Object> param) {
+        Page<ImLiveBroadcastRoomVo> pageInfo = PageUtil.getPageInfo(param);
+        pageInfo.setDesc("a.created_time_");
+        param.put("tenantId", TenantContextHolder.getTenantId());
+        BiConsumer<String, String> addTimeCons = (key, time) -> Optional.ofNullable(param.get(key)).map(String::valueOf)
+                .ifPresent(date -> param.put(key, date + " " + time));
+        addTimeCons.accept("startTime", "00:00:00");
+        addTimeCons.accept("endTime", "23:59:59");
+        IPage<ImLiveBroadcastRoomVo> page = baseMapper.queryPage(pageInfo, param);
+        return PageUtil.pageInfo(page);
+    }
+
+    /**
+     * 预创建直播间
+     *
+     * @param dto 直播间信息
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void add(ImLiveBroadcastRoomDto dto) {
+        SysUser sysUser = getSysUser(dto.getSpeakerId());
+        ImLiveBroadcastRoom obj = new ImLiveBroadcastRoom();
+        BeanUtils.copyProperties(dto, obj);
+        Date now = new Date();
+        String roomUid = "LIVE-" + sysUser.getId() + "-" + now.getTime();
+        obj.setTenantId(TenantContextHolder.getTenantId());
+        obj.setRoomUid(roomUid);
+        obj.setRoomConfig(JSONObject.toJSONString(dto.getRoomConfig()));
+        obj.setLiveState(0);
+        obj.setRoomState(0);
+        obj.setCreatedBy(getSysUser().getId());
+        obj.setCreatedTime(now);
+        this.save(obj);
+    }
+
+    /**
+     * 修改直播间信息
+     *
+     * @param dto
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void update(ImLiveBroadcastRoomDto dto) {
+        ImLiveBroadcastRoom obj = this.getById(dto.getId());
+        BeanUtils.copyProperties(dto, obj);
+        obj.setRoomConfig(JSONObject.toJSONString(dto.getRoomConfig()));
+        obj.setUpdatedBy(getSysUser().getId());
+        obj.setUpdatedTime(new Date());
+        log.info("update room  >>>  :{}", JSONObject.toJSONString(obj));
+        this.updateById(obj);
+    }
+
+    /**
+     * 是否禁言
+     *
+     * @param id          房间id
+     * @param whetherChat 是否允许聊天互动  0允许 1不允许
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void whetherChat(Integer id, Integer whetherChat) {
+        ImLiveBroadcastRoom obj = this.getById(id);
+        ImLiveBroadcastRoomDto.RoomConfig roomConfig = getRoomConfig(obj.getRoomConfig()).orElse(null);
+        if (Objects.isNull(roomConfig)) {
+            return;
+        }
+        roomConfig.setWhether_chat(whetherChat);
+        obj.setRoomConfig(JSONObject.toJSONString(roomConfig));
+        this.updateById(obj);
+    }
+
+    /**
+     * 删除直播间
+     *
+     * @param id 直播间id
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void delete(Integer id) {
+        ImLiveBroadcastRoom obj = this.getById(id);
+        if (obj.getLiveState() == 1) {
+            throw new BizException("直播已经开始,无法删除");
+        }
+        obj.setId(id);
+        obj.setRoomState(1);
+        obj.setUpdatedBy(getSysUser().getId());
+        obj.setUpdatedTime(new Date());
+        this.updateById(obj);
+    }
+
+    /**
+     * 定时任务,每分钟执行
+     * 销毁主讲人退出超过30分钟的直播间
+     */
+    public void destroyExpiredLiveRoom() {
+        //查询已经开始并且没有删除及销毁的直播间
+        List<ImLiveBroadcastRoom> list = this.list(new WrapperUtil<ImLiveBroadcastRoom>()
+                .hasEq("live_state_", 1)
+                .hasEq("room_state_", 0)
+                .queryWrapper());
+        if (CollectionUtils.isEmpty(list)) {
+            return;
+        }
+        //查询房间过期时间
+        String expiredMinuteStr = sysConfigDao.findConfigValue("destroy_expired_live_room_minute");
+        if (StringUtils.isEmpty(expiredMinuteStr)) {
+            log.info("roomDestroy>>>> 未查询到配置:destroy_expired_live_room_minute");
+            return;
+        }
+        int expiredMinute = Integer.parseInt(expiredMinuteStr);
+        Date now = new Date();
+        list.forEach(room -> {
+            try {
+                destroyExpiredLiveRoom(now, room, expiredMinute);
+            } catch (Exception e) {
+                log.error("roomDestroy>>>> failed roomId:{} msg:{}", room.getId(), e.getMessage());
+            }
+        });
+    }
+
+    private void destroyExpiredLiveRoom(Date now, ImLiveBroadcastRoom room, int expiredMinute) {
+        log.error("roomDestroy destroyExpiredLiveRoom >>>> now {} roomInfo : {} expiredMinute:{}", now, JSONObject.toJSONString(room), expiredMinute);
+        //获取直播间主讲人信息
+        RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, room.getSpeakerId().toString()));
+        if (speakerCache.isExists()) {
+            RoomSpeakerInfo speakerInfo = speakerCache.get();
+            //过期时间= 房间正式开始时间+expiredMinute 分钟
+            Date expiredTime = DateUtil.addMinutes(room.getCreatedTime(), expiredMinute);
+            //先决条件 当前时间 大于(创建房间时填入的开播时间 + 设置的过期分钟数)
+            if (now.getTime() >= expiredTime.getTime()) {
+
+                //1.主播没有进入房间,则直接销毁房间
+                if (Objects.isNull(speakerInfo.getJoinRoomTime())) {
+                    log.info("roomDestroy not joinRoom >>>> cache : {}", JSONObject.toJSONString(test(room.getRoomUid(), room.getSpeakerId())));
+                    roomDestroy(room);
+                    return;
+                }
+
+                //如果主播已经进入了房间 就判断是否退出过房间
+                if (Objects.nonNull(speakerInfo.getExitRoomTime())) {
+                    //如果退出过房间 判断退出时间是否大于进入时间
+                    if (speakerInfo.getExitRoomTime().getTime() > speakerInfo.getJoinRoomTime().getTime()) {
+                        //如果退出时间大于进入时间,就将退出时间+expiredMinute分钟
+                        Date exitExpiredTime = DateUtil.addMinutes(speakerInfo.getExitRoomTime(), expiredMinute);
+                        if (now.getTime() >= exitExpiredTime.getTime()) {
+                            log.info("roomDestroy exitExpiredTime >>>> cache : {}", JSONObject.toJSONString(test(room.getRoomUid(), room.getSpeakerId())));
+                            roomDestroy(room);
+                        }
+                    }
+                }
+
+            }
+        }
+    }
+
+    /**
+     * 关闭房间-融云
+     * 获取所有直播间缓存数据并写入数据库后并清理缓存
+     *
+     * @param id 直播房间表id
+     */
+    @Override
+    public void roomDestroy(Integer id) {
+        ImLiveBroadcastRoom room = this.getById(id);
+        if (Objects.isNull(room)) {
+            return;
+        }
+        if (room.getLiveState() == 0) {
+            throw new BizException("直播未开始");
+        }
+        roomDestroy(room);
+    }
+
+    public void roomDestroy(ImLiveBroadcastRoom room) {
+        log.error("roomDestroy>>>> room : {}", JSONObject.toJSONString(room));
+        String roomUid = room.getRoomUid();
+        Integer speakerId = room.getSpeakerId();
+
+        try {
+            //向聊天室发自定义消息踢出所有人
+            ImRoomMessage message = new ImRoomMessage();
+            message.setFromUserId(speakerId.toString());
+            message.setToChatroomId(roomUid);
+            message.setObjectName(ImRoomMessage.FORCED_OFFLINE);
+            imFeignService.publishRoomMsg(message);
+            log.info("roomDestroy>>>> FORCED_OFFLINE {}", JSONObject.toJSONString(message));
+            //销毁直播间
+            imFeignService.destroyLiveRoom(roomUid);
+            log.info("roomDestroy>>>> destroyLiveRoom {}", JSONObject.toJSONString(message));
+        } catch (Exception e) {
+            log.error("roomDestroy>>>> errorMsg{}", e.getMessage(), e.getCause());
+        }
+
+        //获取所有直播间缓存数据并写入数据库后并清理缓存
+        insertAndCleanLiveData(roomUid, speakerId);
+        log.info("roomDestroy>>>> insertAndCleanLiveData {}", JSONObject.toJSONString(room));
+
+        //将房间状态改为已销毁
+        Date date = new Date();
+        room.setRoomState(2);
+        room.setLiveState(2);
+        Integer userId = -1;
+        try {
+            userId = getSysUser().getId();
+        } catch (Exception ignored) {
+        }
+        room.setUpdatedBy(userId);
+        room.setUpdatedTime(date);
+        room.setLiveEndTime(date);
+        this.updateById(room);
+    }
+
+    //获取该直播间所有数据写入数据库-并清理缓存
+    private void insertAndCleanLiveData(String roomUid, Integer speakerId) {
+        //总观看人数
+        int totalLookNum = 0;
+        //获取直播间所有人数据写入 im_live_broadcast_room_member
+        RMap<Integer, RoomUserInfoVo> roomTotalUserCache = redissonClient.getMap(LIVE_ROOM_TOTAL_USER_LIST.replace(ROOM_UID, roomUid));
+        if (roomTotalUserCache.isExists()) {
+            List<RoomUserInfoVo> roomTotalUser = new ArrayList<>(roomTotalUserCache.values());
+            List<ImLiveBroadcastRoomMember> memberList = new ArrayList<>();
+            roomTotalUser.forEach(v -> {
+                ImLiveBroadcastRoomMember member = new ImLiveBroadcastRoomMember();
+                member.setTenantId(v.getTenantId());
+                member.setRoomUid(roomUid);
+                member.setUserId(v.getUserId());
+                member.setJoinTime(v.getFirstJoinTime());
+                member.setTotalTime(v.getTotalViewTime());
+                memberList.add(member);
+            });
+            if (CollectionUtils.isNotEmpty(memberList)) {
+                liveBroadcastRoomMemberService.getDao().insertBatch(memberList);
+                totalLookNum = roomTotalUser.size();
+            }
+            //删除用户对应的直播间关系缓存
+            roomTotalUser.stream()
+                    .map(RoomUserInfoVo::getUserId)
+                    .filter(Objects::nonNull)
+                    .forEach(id -> redissonClient.getBucket(LIVE_USER_ROOM.replace(USER_ID, id.toString())).delete());
+            //删除直播间所有人数据
+            roomTotalUserCache.clear();
+        }
+
+        //获取直播点赞
+        int like = 0;
+        RBucket<Object> likeCache = redissonClient.getBucket(LIVE_ROOM_LIKE.replace(ROOM_UID, roomUid));
+        if (likeCache.isExists()) {
+            like = (int) likeCache.get();
+            //删除房间点赞数据
+            likeCache.delete();
+        }
+
+        //获取直播间主讲人信息 写入im_live_broadcast_room_data
+        RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, speakerId.toString()));
+        if (speakerCache.isExists()) {
+            ImLiveBroadcastRoomData liveData = new ImLiveBroadcastRoomData();
+            RoomSpeakerInfo speakerInfo = speakerCache.get();
+            liveData.setTenantId(speakerInfo.getTenantId());
+            liveData.setRoomUid(roomUid);
+            liveData.setLikeNum(like);
+            liveData.setTotalUserNum(totalLookNum);
+            liveData.setUpdatedTime(new Date());
+            liveData.setLiveTime(speakerInfo.getTotalLiveTime());
+            liveBroadcastRoomDataService.save(liveData);
+            //删除房间主讲人数据
+            speakerCache.delete();
+        }
+
+    }
+
+    /**
+     * 同步点赞数量
+     *
+     * @param roomUid 房间uid
+     * @param likeNum 点赞数
+     */
+    @Override
+    public void syncLike(String roomUid, Integer likeNum) {
+        redissonClient.getBucket(LIVE_ROOM_LIKE.replace(ROOM_UID, roomUid)).set(likeNum);
+    }
+
+    /**
+     * <p>主讲人处理进入和退出房间数据
+     * <p>观看者只处理退出房间数据
+     *
+     * @param userState 用户状态数据
+     */
+    @Override
+    public void opsRoom(List<ImUserState> userState) {
+        if (CollectionUtils.isEmpty(userState)) {
+            return;
+        }
+        userState.forEach(user -> {
+            log.info("opsRoom>>>> {}", JSONObject.toJSONString(user));
+            if (StringUtils.isBlank(user.getStatus())) {
+                return;
+            }
+            Date now = new Date();
+            //查询主讲人userId,若是主讲人
+            RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, user.getUserid()));
+            if (speakerCache.isExists()) {
+                RoomSpeakerInfo speakerInfo = speakerCache.get();
+                //主讲人进入房间
+                if (user.getStatus().equals("0")) {
+                    speakerInfo.setJoinRoomTime(now);
+                    log.info("opsRoom>>>> join speakerCache {}", JSONObject.toJSONString(speakerInfo));
+                    speakerCache.set(speakerInfo);
+                    return;
+                }
+                //主讲人退出房间关闭录像
+                closeLive(speakerInfo);
+                speakerInfo.setExitRoomTime(now);
+                log.info("opsRoom>>>> exit speakerCache {}", JSONObject.toJSONString(speakerInfo));
+                speakerCache.set(speakerInfo);
+                return;
+            }
+            //未查询到主讲人信息,观看者只接受退出消息 status=0 是进入房间
+            if (user.getStatus().equals("0")) {
+                return;
+            }
+            //获取当前用户所在房间的uid
+            RBucket<String> userRoom = redissonClient.getBucket(LIVE_USER_ROOM.replace(USER_ID, user.getUserid()));
+            if (!userRoom.isExists()) {
+                return;
+            }
+            String roomUid = userRoom.get();
+            Integer userId = Integer.valueOf(user.getUserid());
+
+            //从房间累计用户信息中查询该用户的信息
+            RMap<Integer, RoomUserInfoVo> roomTotalUser = redissonClient.getMap(LIVE_ROOM_TOTAL_USER_LIST.replace(ROOM_UID, roomUid));
+            //该房间未查询到用户数据则不处理
+            if (!roomTotalUser.isExists() && !roomTotalUser.containsKey(userId)) {
+                return;
+            }
+            //查询到用户数据
+            RoomUserInfoVo userInfo = roomTotalUser.get(userId);
+            //用户是在房间的状态 并且 突然离线 - 那么融云会发送用户离线消息-此刻就发送退出房间消息给主讲人
+            if (userInfo.getState() == 0 && user.getStatus().equals("1")) {
+                ImRoomMessage message = new ImRoomMessage();
+                message.setFromUserId(userId.toString());
+                message.setToChatroomId(roomUid);
+                message.setObjectName(ImRoomMessage.LOOKER_LOGIN_OUT);
+                try {
+                    imFeignService.publishRoomMsg(message);
+                } catch (Exception e) {
+                    log.error("opsRoom>>>>  looker error {}", e.getMessage());
+                    log.error("opsRoom>>>>  looker error sendMessage {} : LOOKER_LOGIN_OUT : {}", message, JSONObject.toJSONString(userInfo));
+                }
+                log.info("opsRoom>>>> looker LOOKER_LOGIN_OUT : {}", JSONObject.toJSONString(userInfo));
+            }
+            //每次退出房间计算当前用户观看时长
+            int minutesBetween = getMinutesBetween(userInfo.getDynamicJoinTime(), now);
+            userInfo.setTotalViewTime(userInfo.getTotalViewTime() + minutesBetween);
+            //记录退出时间 并写入缓存
+            userInfo.setLastOutTime(now);
+            userInfo.setState(1);
+            roomTotalUser.fastPut(userId, userInfo);
+            log.info("opsRoom>>>> looker userInfo: {}", JSONObject.toJSONString(userInfo));
+        });
+
+    }
+
+    /**
+     * 主讲人登录专用
+     *
+     * @param roomUid
+     */
+    public ImLiveBroadcastRoomVo speakerJoinRoom(String roomUid) {
+        SysUser sysUser = getSysUser();
+        ImLiveBroadcastRoomVo roomVo = queryRoomAndCheck(roomUid, sysUser);
+        Integer userId = sysUser.getId();
+        if (!userId.equals(roomVo.getSpeakerId())) {
+            throw new BizException("您不是该直播间的主讲人");
+        }
+        Date now = new Date();
+        //获取直播间信息
+        RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, userId.toString()));
+        if (!speakerCache.isExists()) {
+            //没有主讲人信息则生成一个
+            createSpeakerInfo(this.getById(roomVo.getId()), sysUser);
+            speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, userId.toString()));
+        }
+        RoomSpeakerInfo speakerInfo = speakerCache.get();
+        speakerInfo.setJoinRoomTime(now);
+        speakerCache.set(speakerInfo);
+        return roomVo;
+    }
+
+    /**
+     * 进入房间-修改用户对应的房间号信息
+     *
+     * @param roomUid 房间uid
+     * @param userId  用户id
+     */
+    public void joinRoom(String roomUid, Integer userId) {
+        //记录用户当前房间uid
+        redissonClient.getBucket(LIVE_USER_ROOM.replace(USER_ID, userId.toString())).set(roomUid);
+        //房间累计用户信息-指只要进入到该房间的用户都要记录
+        RMap<Integer, RoomUserInfoVo> roomTotalUser = redissonClient.getMap(LIVE_ROOM_TOTAL_USER_LIST.replace(ROOM_UID, roomUid));
+        //判断是否第一次进房间
+        RoomUserInfoVo userInfo;
+        Date now = new Date();
+        if (roomTotalUser.containsKey(userId)) {
+            //多次进入更新动态进入时间
+            userInfo = roomTotalUser.get(userId);
+        } else {
+            //第一次进该房间 写入用户首次进入时间
+            userInfo = getUserInfo(userId);
+            userInfo.setFirstJoinTime(now);
+            userInfo.setTotalViewTime(0);
+        }
+        userInfo.setState(0);//0 进入/在房间
+        userInfo.setDynamicJoinTime(now);
+        roomTotalUser.fastPut(userId, userInfo);
+        log.info("joinRoom>>>> userInfo: {}", JSONObject.toJSONString(userInfo));
+    }
+
+    /**
+     * 开始直播-录像
+     *
+     * @param roomUid 房间uid
+     */
+    public void startLive(String roomUid, Integer userId) {
+        //查询房间信息是否允许录像
+        RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, userId.toString()));
+        RoomSpeakerInfo roomSpeakerInfo = speakerCache.get();
+        if (Objects.nonNull(roomSpeakerInfo.getWhetherVideo()) && roomSpeakerInfo.getWhetherVideo() == 0) {
+            //开始录制视频
+            try {
+                imFeignService.startRecord(roomUid);
+            } catch (Exception e) {
+                log.error("startRecord error: {}", e.getMessage());
+            }
+        }
+        //开始直播
+        roomSpeakerInfo.setState(0);
+        roomSpeakerInfo.setStartLiveTime(new Date());
+        speakerCache.set(roomSpeakerInfo);
+        log.info("startLive>>>> roomSpeakerInfo: {}", JSONObject.toJSONString(roomSpeakerInfo));
+    }
+
+    /**
+     * 关闭直播-录像
+     *
+     * @param roomUid 房间uid
+     */
+    public void closeLive(String roomUid, Integer userId) {
+        //查询房间主播信息
+        RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, userId.toString()));
+        RoomSpeakerInfo roomSpeakerInfo = speakerCache.get();
+        //关闭直播
+        closeLive(roomSpeakerInfo);
+        speakerCache.set(roomSpeakerInfo);
+    }
+
+    private void closeLive(RoomSpeakerInfo roomSpeakerInfo) {
+        boolean stateFlag = Objects.nonNull(roomSpeakerInfo.getState()) && roomSpeakerInfo.getState() == 0;
+        if (Objects.nonNull(roomSpeakerInfo.getWhetherVideo()) && roomSpeakerInfo.getWhetherVideo() == 0
+                && stateFlag) {
+            //停止录制视频
+            try {
+                imFeignService.stopRecord(roomSpeakerInfo.getRoomUid());
+            } catch (Exception e) {
+                log.error("stopRecord error: {}", e.getMessage());
+            }
+        }
+        if (stateFlag) {
+            Date now = new Date();
+            roomSpeakerInfo.setEndLiveTime(now);
+            roomSpeakerInfo.setState(1);
+            //计算时长
+            int minutesBetween = getMinutesBetween(roomSpeakerInfo.getStartLiveTime(), now);
+            int i = Objects.isNull(roomSpeakerInfo.getTotalLiveTime()) ? 0 : roomSpeakerInfo.getTotalLiveTime();
+            roomSpeakerInfo.setTotalLiveTime(i + minutesBetween);
+        }
+        log.info("closeLive>>>> roomSpeakerInfo: {}", JSONObject.toJSONString(roomSpeakerInfo));
+    }
+
+    /**
+     * 定时任务,每分钟执行
+     * 提前30分钟主动去融云注册并创建房间
+     */
+    public void createLiveRoom() {
+        Date now = new Date();
+        Date endTime = DateUtil.addMinutes(now, 30);
+        List<ImLiveBroadcastRoom> list = this.list(new WrapperUtil<ImLiveBroadcastRoom>()
+                .hasEq("live_state_", 0)
+                .hasEq("room_state_", 0)
+                .hasGe("live_start_time_", now)
+                .hasLe("live_start_time_", endTime)
+                .queryWrapper());
+        if (CollectionUtils.isEmpty(list)) {
+            return;
+        }
+        list.forEach(this::createLiveRoom);
+    }
+
+    /**
+     * 去融云创建房间
+     */
+    private void createLiveRoom(ImLiveBroadcastRoom room) {
+        log.info("createLiveRoom>>>>>>roomUid:{}", room.getRoomUid());
+        try {
+            //生成主讲人信息到缓存
+            SysUser sysUser = getSysUser(room.getSpeakerId());
+            createSpeakerInfo(room, sysUser);
+            //去融云创建房间
+            imFeignService.createLiveRoom(room.getRoomUid(), room.getRoomTitle());
+        } catch (Exception e) {
+            log.error(">>>>>>>>>> createLiveRoom error roomUid:{} msg:{}", room.getRoomUid(), e.getMessage());
+        }
+    }
+
+    //生成主讲人信息
+    private void createSpeakerInfo(ImLiveBroadcastRoom room, SysUser sysUser) {
+        Date now = new Date();
+        RoomSpeakerInfo speakerInfo = new RoomSpeakerInfo();
+        speakerInfo.setSpeakerId(sysUser.getId());
+        speakerInfo.setSpeakerName(sysUser.getRealName());
+        speakerInfo.setCreateRoomTime(now);
+        speakerInfo.setRoomUid(room.getRoomUid());
+        speakerInfo.setTenantId(sysUser.getTenantId());
+        speakerInfo.setTotalLiveTime(0);
+
+        //查询房间信息是否允许录像
+        ImLiveBroadcastRoom one = this.getOne(new QueryWrapper<ImLiveBroadcastRoom>().eq("room_uid_", room.getRoomUid()));
+        boolean video = getRoomConfig(one.getRoomConfig())
+                .filter(c -> Objects.nonNull(c.getWhether_video()))
+                .map(c -> c.getWhether_video() == 0)
+                .orElse(false);
+        if (video) {
+            //可以录制视频
+            speakerInfo.setWhetherVideo(0);
+        } else {
+            //不可以录制视频
+            speakerInfo.setWhetherVideo(1);
+        }
+        //写入主讲人信息
+        redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, room.getSpeakerId().toString())).set(speakerInfo);
+
+        //生成0点赞
+        redissonClient.getBucket(LIVE_ROOM_LIKE.replace(ROOM_UID, room.getRoomUid())).set(0);
+
+        //修改房间状态为开始
+        room.setLiveState(1);
+        room.setUpdatedTime(now);
+        room.setUpdatedBy(-2);
+        baseMapper.updateById(room);
+    }
+
+    private Optional<ImLiveBroadcastRoomDto.RoomConfig> getRoomConfig(String roomConfig) {
+        return Optional.ofNullable(roomConfig)
+                .map(c -> JSON.parseObject(c, ImLiveBroadcastRoomDto.RoomConfig.class));
+    }
+
+    private void getRoomData(ImLiveBroadcastRoomVo roomVo) {
+        //点赞数
+        Object like = redissonClient.getBucket(LIVE_ROOM_LIKE.replace(ROOM_UID, roomVo.getRoomUid())).get();
+        if (Objects.isNull(like)) {
+            like = 0;
+        }
+        roomVo.setLikeNum((int) like);
+        //累计总用户数量
+        List<RoomUserInfoVo> roomUserInfoVos = queryTotalRoomUserInfo(roomVo.getRoomUid());
+        if (CollectionUtils.isNotEmpty(roomUserInfoVos)) {
+            roomVo.setTotalLookNum(roomUserInfoVos.size());
+            //在房间观看用户数量
+            roomVo.setLookNum(queryRoomUserInfo(roomUserInfoVos).size());
+        } else {
+            roomVo.setTotalLookNum(0);
+            roomVo.setLookNum(0);
+        }
+
+    }
+
+    private SysUser getSysUser(Integer userId) {
+        return Optional.ofNullable(userId)
+                .map(sysUserFeignService::queryUserById)
+                .orElseThrow(() -> new BizException("用户不存在"));
+    }
+
+    private SysUser getSysUser() {
+        //修改机构基础信息
+        return Optional.ofNullable(sysUserFeignService.queryUserInfo())
+                .orElseThrow(() -> new BizException("用户不存在"));
+    }
+
+    /**
+     * 测试
+     */
+    public Map<String, Object> test(String roomUid, Integer userId) {
+        //test
+        Map<String, Object> result = new HashMap<>();
+        //点赞数
+        Object like = redissonClient.getBucket(LIVE_ROOM_LIKE.replace(ROOM_UID, roomUid)).get();
+        if (Objects.isNull(like)) {
+            like = 0;
+        }
+        result.put("点赞数", like);
+
+        int totalLook = 0;
+        int look = 0;
+        List<RoomUserInfoVo> inRoomUserInfo;
+
+        //累计总观看的用户数量
+        List<RoomUserInfoVo> totalUserInfo = queryTotalRoomUserInfo(roomUid);
+        if (CollectionUtils.isNotEmpty(totalUserInfo)) {
+            //正在房间观看的用户数据
+            inRoomUserInfo = queryRoomUserInfo(totalUserInfo);
+            if (CollectionUtils.isNotEmpty(inRoomUserInfo)) {
+                look = inRoomUserInfo.size();
+                result.put("正在观看的人员信息", inRoomUserInfo);
+            } else {
+                result.put("正在观看的人员信息", "没有正在观看的人员数据");
+            }
+            totalLook = totalUserInfo.size();
+            result.put("总人员数据", totalUserInfo);
+        } else {
+            result.put("总人员数据", "没有人员数据");
+        }
+
+        //获取主讲人信息
+        RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, userId.toString()));
+        if (speakerCache.isExists()) {
+            result.put("主讲人信息", speakerCache.get());
+        } else {
+            result.put("主讲人信息", "主讲人信息不存在");
+        }
+        result.put("总观看人数", totalLook);
+        result.put("实时观看数", look);
+        return result;
+    }
+
+    @Override
+    public void shareGroup(String roomUid, String groupIds) {
+        ImLiveBroadcastRoomVo imLiveBroadcastRoomVo = queryRoomInfo(roomUid);
+        if (imLiveBroadcastRoomVo == null) {
+            throw new BizException("直播间信息异常!");
+        }
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        String baseApiUrl = sysConfigDao.findConfigValue(SysConfigService.BASE_API_URL);
+        StringBuffer pushUrl = new StringBuffer(baseApiUrl).append("/#/liveClassTransfer?roomUid=").append(roomUid);
+        sysMessageService.batchSendImGroupMessage(MessageTypeEnum.IM_SHARE_LIVE_URL, sysUser.getId().toString(), null, groupIds.split(","), null,
+                imLiveBroadcastRoomVo.getTenantName(), imLiveBroadcastRoomVo.getRoomTitle(), imLiveBroadcastRoomVo.getSpeakerName(),
+                DateUtil.format(imLiveBroadcastRoomVo.getLiveStartTime(), DateUtil.CHINESE_DATA_FORMAT_1),
+                imLiveBroadcastRoomVo.getLiveRemark(), HttpUtil.getSortUrl(pushUrl.toString()));
+    }
+
+    /**
+     * 查询在观看直播的用户信息
+     *
+     * @param roomUid 直播间uid
+     */
+    @Override
+    public List<RoomUserInfoVo> queryRoomUserInfo(String roomUid) {
+        List<RoomUserInfoVo> roomUserInfoVos = queryTotalRoomUserInfo(roomUid);
+        return queryRoomUserInfo(roomUserInfoVos);
+    }
+
+    public List<RoomUserInfoVo> queryRoomUserInfo(List<RoomUserInfoVo> totalUserInfo) {
+        return totalUserInfo.stream()
+                .filter(o -> Objects.nonNull(o.getState()) && o.getState() == 0)
+                .collect(Collectors.toList());
+    }
+
+    public List<RoomUserInfoVo> queryTotalRoomUserInfo(String roomUid) {
+        RMap<Integer, RoomUserInfoVo> roomTotalUser = redissonClient.getMap(LIVE_ROOM_TOTAL_USER_LIST.replace(ROOM_UID, roomUid));
+        return roomTotalUser.values().stream()
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+    }
+
+    private RoomUserInfoVo getUserInfo(Integer userId) {
+        RoomUserInfoVo userInfo = new RoomUserInfoVo();
+        userInfo.setUserId(userId);
+        SysUser sysUser = sysUserFeignService.queryUserById(userId);
+        String name = userId.toString();
+        if (Objects.nonNull(sysUser)) {
+            name = sysUser.getPhone();
+            if (sysUser.getUserType().contains("STUDENT")) {
+                name = sysUser.getUsername();
+            } else {
+                if (StringUtils.isNotBlank(sysUser.getRealName())) {
+                    name = sysUser.getRealName();
+                }
+            }
+        }
+        userInfo.setUserName(name);
+        userInfo.setTenantId(sysUser.getTenantId());
+        return userInfo;
+    }
+
+    //计算时间差-分钟数不满一分钟为0
+    private int getMinutesBetween(Date startDT, Date endDT) {
+        if (Objects.isNull(startDT) || Objects.isNull(endDT)) {
+            return 0;
+        }
+        //课程结束时间-课程开始时间
+        long durationTime = endDT.getTime() - startDT.getTime();
+        //相差多少分钟
+        return new Long(durationTime / 1000 / 60).intValue();
+    }
+
+    /**
+     * 主讲人信息
+     */
+    public static class RoomSpeakerInfo implements Serializable {
+        //主讲人id
+        private Integer speakerId;
+        //主讲人名称
+        private String speakerName;
+        //直播状态 0 直播中 1关闭直播
+        private Integer state;
+        //房间uid
+        private String roomUid;
+        //房间创建时间
+        private Date createRoomTime;
+        //进入房间时间
+        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+        private Date joinRoomTime;
+        //开始直播时间
+        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+        private Date startLiveTime;
+        //开始直播时间
+        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+        private Date endLiveTime;
+        //退出房间时间
+        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+        private Date exitRoomTime;
+        //总直播时间
+        private Integer totalLiveTime = 0;
+        //是否录像 0允许 1不允许
+        private Integer whetherVideo;
+        //机构
+        private Integer tenantId;
+
+        public Integer getSpeakerId() {
+            return speakerId;
+        }
+
+        public void setSpeakerId(Integer speakerId) {
+            this.speakerId = speakerId;
+        }
+
+        public String getSpeakerName() {
+            return speakerName;
+        }
+
+        public void setSpeakerName(String speakerName) {
+            this.speakerName = speakerName;
+        }
+
+        public Integer getState() {
+            return state;
+        }
+
+        public void setState(Integer state) {
+            this.state = state;
+        }
+
+        public String getRoomUid() {
+            return roomUid;
+        }
+
+        public void setRoomUid(String roomUid) {
+            this.roomUid = roomUid;
+        }
+
+        public Date getJoinRoomTime() {
+            return joinRoomTime;
+        }
+
+        public void setJoinRoomTime(Date joinRoomTime) {
+            this.joinRoomTime = joinRoomTime;
+        }
+
+        public Date getStartLiveTime() {
+            return startLiveTime;
+        }
+
+        public void setStartLiveTime(Date startLiveTime) {
+            this.startLiveTime = startLiveTime;
+        }
+
+        public Integer getTotalLiveTime() {
+            return totalLiveTime;
+        }
+
+        public void setTotalLiveTime(Integer totalLiveTime) {
+            this.totalLiveTime = totalLiveTime;
+        }
+
+        public Date getCreateRoomTime() {
+            return createRoomTime;
+        }
+
+        public void setCreateRoomTime(Date createRoomTime) {
+            this.createRoomTime = createRoomTime;
+        }
+
+        public Date getExitRoomTime() {
+            return exitRoomTime;
+        }
+
+        public void setExitRoomTime(Date exitRoomTime) {
+            this.exitRoomTime = exitRoomTime;
+        }
+
+        public Integer getWhetherVideo() {
+            return whetherVideo;
+        }
+
+        public void setWhetherVideo(Integer whetherVideo) {
+            this.whetherVideo = whetherVideo;
+        }
+
+        public Integer getTenantId() {
+            return tenantId;
+        }
+
+        public void setTenantId(Integer tenantId) {
+            this.tenantId = tenantId;
+        }
+
+        public Date getEndLiveTime() {
+            return endLiveTime;
+        }
+
+        public void setEndLiveTime(Date endLiveTime) {
+            this.endLiveTime = endLiveTime;
+        }
+    }
+
+}
+

+ 44 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ImLiveRoomVideoServiceImpl.java

@@ -0,0 +1,44 @@
+package com.ym.mec.biz.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ym.mec.biz.dal.dao.ImLiveRoomVideoDao;
+import com.ym.mec.biz.dal.entity.ImLiveRoomVideo;
+import com.ym.mec.biz.service.ImLiveRoomVideoService;
+import com.ym.mec.common.page.PageInfo;
+import com.ym.mec.common.page.PageUtil;
+import com.ym.mec.common.page.WrapperUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 直播视频记录(ImLiveRoomVideo)表服务实现类
+ *
+ * @author hgw
+ * @since 2022-03-07 19:06:55
+ */
+@Service("imLiveRoomVideoService")
+public class ImLiveRoomVideoServiceImpl extends ServiceImpl<ImLiveRoomVideoDao, ImLiveRoomVideo> implements ImLiveRoomVideoService {
+
+    private final static Logger log = LoggerFactory.getLogger(ImLiveRoomVideoServiceImpl.class);
+
+    @Override
+    public ImLiveRoomVideoDao getDao() {
+        return this.baseMapper;
+    }
+
+    public List<ImLiveRoomVideo> queryList(String roomUid) {
+        return baseMapper.selectList(new WrapperUtil<ImLiveRoomVideo>()
+                .hasEq("room_uid_",roomUid)
+                .hasEq("type",2).queryWrapper()
+        );
+    }
+
+
+}
+

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

@@ -668,6 +668,12 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 			List<Long> quitGroupNum = indexBaseMonthDataDao.queryApplyForQuitGroupNum(organIds,educationUserId,tenantId);
 			twoChild.add(new IndexErrInfoDto(IndexErrorType.STUDENT_APPLY_FOR_QUIT_MUSIC_GROUP, IndexErrorType.STUDENT_APPLY_FOR_QUIT_MUSIC_GROUP.getMsg(), quitGroupNum.size(),  quitGroupNum));
 
+			//学员已排课时长未消耗完
+			Map<String, Object> params = new HashMap<>();
+			params.put("organId", organIdsStr);
+			params.put("tenantId", tenantId);
+			twoChild.add(new IndexErrInfoDto(IndexErrorType.HAS_FREE_COURSE_TIMES, IndexErrorType.HAS_FREE_COURSE_TIMES.getMsg(), musicGroupDao.countHasFreeCourseTimes(params), null));
+
 			//乐团学员会员到期首页提醒
 //			List<StudentRegistration> studentRegistrations = studentRegistrationDao.queryMemberEndAutoQuitMusic(null,educationUserId,organIdsStr);
 //			IndexErrInfoDto noClassMusicGroupStudentInfo = new IndexErrInfoDto();
@@ -755,7 +761,6 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 				int serveErrTeacherNum = studentExtracurricularExercisesSituationDao.countTeacherServeInfo(params);
 				fourChild.add(new IndexErrInfoDto(IndexErrorType.TEACHER_SERVE_ERROR, IndexErrorType.TEACHER_SERVE_ERROR.getMsg(), serveErrTeacherNum, null));
 			}
-
 			four.setNum(fourChild.stream().mapToInt(IndexErrInfoDto::getNum).sum());
 			four.setResult(fourChild);
 			all.add(four);
@@ -1059,6 +1064,10 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 		infoDto1.setNum2(musicGroupPerformances.stream().map(e -> e.getId()).collect(Collectors.toSet()).size());
 		infoDto1.setDesc(IndexErrorType.MUSIC_GROUP_PERFORMANCE.getMsg());
 		result.add(infoDto1);
+
+		//乐团剩余时长未排课
+		List<String> musicGroupIds = musicGroupDao.queryHasSubCourseTimes(organIds,tenantId);
+		result.add(new IndexErrInfoDto(IndexErrorType.MUSIC_GROUP_HAS_COURSE_TIMES, IndexErrorType.MUSIC_GROUP_HAS_COURSE_TIMES.getMsg(),musicGroupIds.size(), null));
 		return result;
 	}
 
@@ -1137,7 +1146,15 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 				flag2 = true;
 			}
 		}
-
+		if(!flag2){
+			Map<String, Object> params = new HashMap<String, Object>(2);
+			params.put("organId",organIdsStr);
+			params.put("tenantId",tenantId);
+			Integer hasFreeCourseTimes = musicGroupDao.countHasFreeCourseTimes(params);
+			if(hasFreeCourseTimes != null && hasFreeCourseTimes > 0){
+				flag2 = true;
+			}
+		}
 		resultMap.put("studentInfo",flag2);
 		boolean flag3 = false;
 
@@ -1252,6 +1269,14 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 				}
 			}
 		}
+		if(!flag5){
+			if(!flag5){
+				List<String> strings = musicGroupDao.queryHasSubCourseTimes(organIdsStr, tenantId);
+				if(strings.size() > 0){
+					flag5 = true;
+				}
+			}
+		}
 		resultMap.put("remindMatterData",flag5);
 
 		return resultMap;

+ 3 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/MemberRankSettingServiceImpl.java

@@ -131,6 +131,9 @@ public class MemberRankSettingServiceImpl extends BaseServiceImpl<Integer, Membe
         if (cloudCoachPaymentProgram == null) {
             throw new BizException("团练宝缴费订单不存在,请联系指导老师");
         }
+        if (cloudCoachPaymentProgram.getStatus() != CloudCoachPaymentProgram.StatusEnum.OPEN) {
+            throw new BizException("当前团练宝缴费订单状态不允许缴费");
+        }
         SysUser sysUser = sysUserFeignService.queryUserInfo();
         StudentCloudCoachPaymentDetails cloudCoachPaymentDetails = studentCloudCoachPaymentDetailsService.findByUserId(paymentId, sysUser.getId());
         if (cloudCoachPaymentDetails == null) {

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/MusicGroupPaymentCalenderCourseSettingsServiceImpl.java

@@ -8,14 +8,17 @@ import com.ym.mec.biz.dal.entity.*;
 import com.ym.mec.biz.dal.enums.CalenderBaseServiceEnum;
 import com.ym.mec.biz.service.MusicGroupOrganizationCourseSettingsService;
 import com.ym.mec.biz.service.MusicGroupPaymentCalenderBaseService;
+import com.ym.mec.common.controller.BaseController;
 import com.ym.mec.common.exception.BizException;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Service;
 
 import com.ym.mec.biz.dal.dao.MusicGroupPaymentCalenderCourseSettingsDao;
 import com.ym.mec.biz.service.MusicGroupPaymentCalenderCourseSettingsService;
 import com.ym.mec.common.dal.BaseDAO;
 import com.ym.mec.common.service.impl.BaseServiceImpl;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
 import org.springframework.util.CollectionUtils;
 
 import java.math.BigDecimal;
@@ -72,6 +75,14 @@ public class MusicGroupPaymentCalenderCourseSettingsServiceImpl extends BaseServ
 			}
 			result.put(courseTypeDetailsEntry.getKey().getCode(), details.stream().min(Comparator.comparing(MusicGroupPaymentStudentCourseDetail::getTotalCourseMinutes)).get().getTotalCourseMinutes());
 		}
+		//校验剩余时长是否一致
+		List<CourseSchedule.CourseScheduleType> courseTypes = mgpscds.stream().map(e -> e.getCourseType()).distinct().collect(Collectors.toList());
+		Integer checkCourseTimes = musicGroupPaymentStudentCourseDetailDao.checkCourseTimes(musicGroupId, courseTypes, studentIds);
+		if(checkCourseTimes == null || checkCourseTimes == 0){
+			result.put("checkCourseTimesFlag",1);
+		}else {
+			result.put("checkCourseTimesFlag",0);
+		}
 		return result;
 	}
 

+ 23 - 297
mec-biz/src/main/java/com/ym/mec/biz/service/impl/MusicGroupPaymentCalenderDetailServiceImpl.java

@@ -1,71 +1,15 @@
 package com.ym.mec.biz.service.impl;
 
-import static com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PayUserType.STUDENT;
-import static com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentCalenderStatusEnum.AUDITING;
-import static com.ym.mec.biz.dal.entity.MusicGroupStudentFee.PaymentStatus.NON_PAYMENT;
-import static com.ym.mec.biz.dal.entity.MusicGroupStudentFee.PaymentStatus.PAID_COMPLETED;
-
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-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.Set;
-import java.util.stream.Collectors;
-
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import com.ym.mec.biz.dal.dao.CloudTeacherOrderDao;
-import com.ym.mec.biz.dal.dao.MusicGroupDao;
-import com.ym.mec.biz.dal.dao.MusicGroupPaymentCalenderCourseSettingsDao;
-import com.ym.mec.biz.dal.dao.MusicGroupPaymentCalenderDao;
-import com.ym.mec.biz.dal.dao.MusicGroupPaymentCalenderDetailDao;
-import com.ym.mec.biz.dal.dao.MusicGroupPaymentStudentCourseDetailDao;
-import com.ym.mec.biz.dal.dao.MusicGroupStudentFeeDao;
-import com.ym.mec.biz.dal.dao.StudentDao;
-import com.ym.mec.biz.dal.dao.StudentPaymentOrderDao;
-import com.ym.mec.biz.dal.dao.StudentPaymentOrderDetailDao;
-import com.ym.mec.biz.dal.dao.SysConfigDao;
-import com.ym.mec.biz.dal.dto.FeeStudentDto;
-import com.ym.mec.biz.dal.dto.MusicArrearageStudentDto;
-import com.ym.mec.biz.dal.dto.MusicGroupPaymentCalenderDetailDto;
-import com.ym.mec.biz.dal.dto.SimpleUserDto;
-import com.ym.mec.biz.dal.dto.StudentSubTotalCourseTimesDto;
-import com.ym.mec.biz.dal.entity.ActivityUserMapper;
-import com.ym.mec.biz.dal.entity.CloudTeacherOrder;
-import com.ym.mec.biz.dal.entity.MusicGroup;
-import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender;
+import com.ym.mec.biz.dal.dao.*;
+import com.ym.mec.biz.dal.dto.*;
+import com.ym.mec.biz.dal.entity.*;
 import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentCalenderStatusEnum;
-import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalenderActivity;
-import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalenderCourseSettings;
-import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalenderDetail;
-import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalenderMember;
-import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalenderStudentDetail;
-import com.ym.mec.biz.dal.entity.MusicGroupPaymentStudentCourseDetail;
 import com.ym.mec.biz.dal.entity.MusicGroupStudentFee.PaymentStatus;
-import com.ym.mec.biz.dal.entity.Student;
-import com.ym.mec.biz.dal.entity.StudentPaymentOrder;
-import com.ym.mec.biz.dal.entity.StudentPaymentOrderDetail;
-import com.ym.mec.biz.dal.entity.StudentRegistration;
 import com.ym.mec.biz.dal.enums.MessageTypeEnum;
 import com.ym.mec.biz.dal.enums.OrderDetailTypeEnum;
 import com.ym.mec.biz.dal.page.ArrearageStudentsQueryInfo;
 import com.ym.mec.biz.dal.page.MusicCalenderDetailQueryInfo;
-import com.ym.mec.biz.service.ActivityUserMapperService;
-import com.ym.mec.biz.service.MusicGroupPaymentCalenderActivityService;
-import com.ym.mec.biz.service.MusicGroupPaymentCalenderDetailService;
-import com.ym.mec.biz.service.MusicGroupPaymentCalenderMemberService;
-import com.ym.mec.biz.service.MusicGroupPaymentCalenderService;
-import com.ym.mec.biz.service.SysConfigService;
-import com.ym.mec.biz.service.SysMessageService;
+import com.ym.mec.biz.service.*;
 import com.ym.mec.common.dal.BaseDAO;
 import com.ym.mec.common.exception.BizException;
 import com.ym.mec.common.page.PageInfo;
@@ -73,6 +17,19 @@ import com.ym.mec.common.service.impl.BaseServiceImpl;
 import com.ym.mec.common.tenant.TenantContextHolder;
 import com.ym.mec.thirdparty.message.MessageSenderPluginContext;
 import com.ym.mec.util.collection.MapUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PayUserType.STUDENT;
+import static com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentCalenderStatusEnum.AUDITING;
+import static com.ym.mec.biz.dal.entity.MusicGroupStudentFee.PaymentStatus.NON_PAYMENT;
+import static com.ym.mec.biz.dal.entity.MusicGroupStudentFee.PaymentStatus.PAID_COMPLETED;
 
 @Service
 public class MusicGroupPaymentCalenderDetailServiceImpl extends BaseServiceImpl<Long, MusicGroupPaymentCalenderDetail>  implements MusicGroupPaymentCalenderDetailService {
@@ -115,145 +72,6 @@ public class MusicGroupPaymentCalenderDetailServiceImpl extends BaseServiceImpl<
 		return musicGroupPaymentCalenderDetailDao;
 	}
 
-	/*@Override
-	@Transactional(rollbackFor = Exception.class)
-	public void updateExpectAmount(BigDecimal expectAmount,BigDecimal expectMemberAmount,String ids) {
-		if((expectAmount == null && expectMemberAmount == null) || StringUtils.isEmpty(ids)){
-			throw new BizException("参数校验失败");
-		}
-		if(expectAmount == null){
-			expectAmount = BigDecimal.ZERO;
-		}
-		if(expectMemberAmount == null){
-			expectMemberAmount = BigDecimal.ZERO;
-		}
-		//获取缴费列表
-		List<MusicGroupPaymentCalenderDetail> calenderDetails = musicGroupPaymentCalenderDetailDao.queryListByIds(ids);
-		if(calenderDetails.size() == 0){
-			throw new BizException("缴费记录不存在");
-		}
-		Date date = new Date();
-		MusicGroupPaymentCalender calender = musicGroupPaymentCalenderService.get(calenderDetails.get(0).getMusicGroupPaymentCalenderId());
-		MusicGroup musicGroup = musicGroupDao.get(calender.getMusicGroupId());
-
-		if(calender.getPaymentAmount().doubleValue() > 0d){
-			BigDecimal totalAmount = calender.getPaymentAmount();
-			BigDecimal subExpectAmount = expectAmount;
-			if(calender.getPaymentType() == MusicGroupPaymentCalender.PaymentType.SPAN_GROUP_CLASS_ADJUST){
-				List<MusicGroupPaymentCalenderStudentDetail> studentDetails = musicGroupPaymentCalenderStudentDetailDao.findByBatchNoAndUserId(calender.getBatchNo(), calenderDetails.get(0).getUserId());
-				if(studentDetails.size() == 0){
-					throw new BizException("修改失败:缴费项目数据异常");
-				}
-				List<Integer> studentIds = calenderDetails.stream().map(e -> e.getUserId()).collect(Collectors.toList());
-				for (int i = 0; i < studentDetails.size(); i++) {
-					MusicGroupPaymentCalenderStudentDetail studentDetail = studentDetails.get(i);
-					if(i == studentDetails.size() - 1){
-						musicGroupPaymentCalenderStudentDetailDao.updateByCourseType(studentDetail.getCourseType(),calender.getBatchNo(),studentIds,subExpectAmount);
-					}else {
-						BigDecimal divide = studentDetail.getCourseCurrentPrice().divide(totalAmount, CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN);
-						BigDecimal courseAmount = divide.multiply(expectAmount).setScale(0, BigDecimal.ROUND_DOWN);
-						subExpectAmount = subExpectAmount.subtract(courseAmount);
-						musicGroupPaymentCalenderStudentDetailDao.updateByCourseType(studentDetail.getCourseType(),calender.getBatchNo(),studentIds,courseAmount);
-					}
-				}
-			}else {
-				List<MusicGroupPaymentCalenderCourseSettings> courseSettingsList = musicGroupPaymentCalenderCourseSettingsDao.getWithPaymentCalender(calender.getId());
-				if(courseSettingsList.size() == 0){
-					throw new BizException("修改失败:缴费项目数据异常");
-				}
-				for (int i = 0; i < courseSettingsList.size(); i++) {
-					MusicGroupPaymentCalenderCourseSettings courseSettings = courseSettingsList.get(i);
-					if(i == courseSettingsList.size() - 1){
-						musicGroupPaymentStudentCourseDetailDao.updateByCourseType(courseSettings.getCourseType().getCode(),ids,subExpectAmount);
-					}else {
-						BigDecimal divide = courseSettings.getCourseCurrentPrice().divide(totalAmount, CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN);
-						BigDecimal courseAmount = divide.multiply(expectAmount).setScale(0, BigDecimal.ROUND_DOWN);
-						subExpectAmount = subExpectAmount.subtract(courseAmount);
-						musicGroupPaymentStudentCourseDetailDao.updateByCourseType(courseSettings.getCourseType().getCode(),ids,courseAmount);
-					}
-				}
-			}
-		}
-		//为了解决学员欠费数量的问题,只要学员没有缴费就可以修改金额
-		Set<Integer> studentIds = new HashSet<>();
-		for (MusicGroupPaymentCalenderDetail e : calenderDetails) {
-			if(e.getPaymentStatus() == null || e.getPaymentStatus() != NON_PAYMENT){
-				throw new BizException("修改失败:缴费状态不匹配");
-			}
-			e.setUpdateTime(date);
-//			e.setExpectAmount(expectAmount);
-//			e.setExpectMemberAmount(expectMemberAmount);
-
-			if(expectAmount.doubleValue() > 0 || expectMemberAmount.doubleValue() > 0){
-				if((e.getOpen() != null && e.getOpen() == 1) || calender.getStatus() == PaymentCalenderStatusEnum.OPEN){
-					studentIds.add(e.getUserId());
-				}
-			}else {
-				// 添加会员有效时长
-				if(calender.getMemberRankSettingId() != null){
-					CloudTeacherOrder cloudTeacherOrder = new CloudTeacherOrder();
-					cloudTeacherOrder.setOrganId(musicGroup.getOrganId());
-					cloudTeacherOrder.setType(calender.getMemberPeriod());
-					cloudTeacherOrder.setTime(calender.getMemberValidDate());
-					//只用会员价格
-					cloudTeacherOrder.setAmount(expectMemberAmount);
-					cloudTeacherOrder.setStudentId(e.getUserId());
-					cloudTeacherOrder.setLevel(calender.getMemberRankSettingId());
-					cloudTeacherOrder.setStatus(1);
-					if(calender.getPaymentType() == MusicGroupPaymentCalender.PaymentType.ADD_STUDENT){
-						cloudTeacherOrder.setRemark("进行中乐团加学生,缴费金额改为0元");
-					}else {
-						cloudTeacherOrder.setRemark("乐团续费,缴费金额改为0元");
-					}
-					cloudTeacherOrder.setMusicGroupId(calender.getMusicGroupId());
-					cloudTeacherOrderDao.insert(cloudTeacherOrder);
-//					studentService.updateMemberRank(cloudTeacherOrder);
-				}
-				calender.setActualNum((calender.getActualNum()==null?0:calender.getActualNum()) + 1);
-				e.setPaymentStatus(PAID_COMPLETED);
-				if(calender.getPaymentType() == MusicGroupPaymentCalender.PaymentType.ADD_STUDENT){
-					MusicGroupStudentFee musicGroupStudentFee = musicGroupStudentFeeDao.findByUser(e.getUserId(), calender.getMusicGroupId());
-					if (musicGroupStudentFee != null) {
-						musicGroupStudentFee.setUpdateTime(date);
-						musicGroupStudentFee.setLatestPaidTime(date);
-						musicGroupStudentFee.setPaymentStatus(PaymentStatus.PAID_COMPLETED);
-						musicGroupStudentFee.setTemporaryCourseFee(new BigDecimal(0));
-						musicGroupStudentFeeDao.update(musicGroupStudentFee);
-					}
-					//如果是进行中加学员
-					StudentRegistration studentRegistration = studentRegistrationDao.queryByUserIdAndMusicGroupId(e.getUserId(), calender.getMusicGroupId());
-					studentRegistration.setPaymentStatus(YES);
-					studentRegistration.setMusicGroupStatus(StudentMusicGroupStatusEnum.NORMAL);
-					studentRegistrationDao.update(studentRegistration);
-
-					//统计变更学员数
-					groupEventSource.musicGroupStudentChangeEvent(calender.getMusicGroupId(), StudentMusicGroupStatusEnum.NORMAL, new ArrayList<>(Arrays.asList(e.getUserId())));
-				}
-			}
-		}
-		musicGroupPaymentCalenderDao.update(calender);
-		musicGroupPaymentCalenderDetailDao.batchUpdate(calenderDetails);
-		//推送消息
-		if (calender.getPayUserType() == STUDENT && studentIds.size() > 0) {
-			Map<Integer, String> push = new HashMap<>();
-			for (Integer userId : studentIds) {
-				push.put(userId, userId + "");
-			}
-			String baseUrl = sysConfigDao.findConfigValue(SysConfigService.BASE_API_URL);
-			String memo = "4?" + baseUrl + "/#/musicGroupRenew?calenderId="+calender.getId()+"&id=" + calender.getMusicGroupId();
-			// 发送续费通知
-			sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.STUDENT_PUSH_WAIT_RENEW_MESSAGE, push,
-					null, 0, memo,"STUDENT",musicGroup.getName());
-
-			//获取未缴费且不是0元的学员列表
-			Map<Integer,String> studentMaps = MapUtil.convertMybatisMap(musicGroupPaymentCalenderDetailDao.queryNoPaymentAndNotZeroStudent(calender.getId(),studentIds));
-			if(studentMaps.size() > 0){
-				sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.STUDENT_SMS_WAIT_RENEW_MESSAGE, studentMaps,
-						null, 0, memo, null, musicGroup.getName());
-			}
-		}
-	}*/
-
 	@Override
 	@Transactional(rollbackFor = Exception.class)
 	public String openPayment(String ids, Date startPaymentDate, Date deadlinePaymentDate) {
@@ -314,103 +132,6 @@ public class MusicGroupPaymentCalenderDetailServiceImpl extends BaseServiceImpl<
 		musicGroupPaymentCalenderDetailDao.refreshUserMusicGroupPaymentStatusTask();
 	}
 
-	@Override
-	@Transactional(rollbackFor = Exception.class)
-	public void batchAdd(Long musicGroupPaymentCalenderId, Set<Integer> userIdList,MusicGroup musicGroup,Boolean autoCreate) {
-		
-		MusicGroupPaymentCalender musicGroupPaymentCalender = musicGroupPaymentCalenderService.get(musicGroupPaymentCalenderId);
-		if(musicGroupPaymentCalender == null){
-			throw new BizException("查询缴费信息失败");
-		}
-		if(musicGroupPaymentCalender.getPaymentType() == MusicGroupPaymentCalender.PaymentType.MUSIC_APPLY){
-			throw new BizException("操作失败:报名缴费项不允许添加学员");
-		}
-		if (musicGroupPaymentCalender.getStatus() == PaymentCalenderStatusEnum.AUDITING
-				|| musicGroupPaymentCalender.getStatus() == PaymentCalenderStatusEnum.REJECT) {
-			throw new BizException("当前缴费状态不能添加学生");
-		}
-		
-		//判断学生是否已存在
-		Set<Integer> userList = musicGroupPaymentCalenderDetailDao.queryStudentIds(musicGroupPaymentCalenderId);
-
-		if(Collections.disjoint(userList, userIdList) == false){
-			throw new BizException("操作失败:包含已存在的学员");
-		}
-		
-		List<MusicGroupPaymentCalenderCourseSettings> courseSettingsList = musicGroupPaymentCalenderCourseSettingsDao.getWithPaymentCalender(musicGroupPaymentCalenderId);
-
-		Date date = new Date();
-		MusicGroupPaymentCalenderDetail musicGroupPaymentCalenderDetail = null;
-		List<MusicGroupPaymentCalenderDetail> musicGroupPaymentCalenderDetailList = new ArrayList<MusicGroupPaymentCalenderDetail>();
-		//创建缴费明细
-		for(Integer studentId : userIdList){
-			musicGroupPaymentCalenderDetail = new MusicGroupPaymentCalenderDetail();
-			musicGroupPaymentCalenderDetail.setMusicGroupPaymentCalenderId(musicGroupPaymentCalenderId);
-			musicGroupPaymentCalenderDetail.setCreateTime(date);
-			if (musicGroupPaymentCalender.getCurrentTotalAmount().compareTo(BigDecimal.ZERO) == 0) {
-				musicGroupPaymentCalenderDetail.setPaymentStatus(PaymentStatus.PAID_COMPLETED);
-			} else {
-				musicGroupPaymentCalenderDetail.setPaymentStatus(PaymentStatus.NON_PAYMENT);
-			}
-			musicGroupPaymentCalenderDetail.setUpdateTime(date);
-			musicGroupPaymentCalenderDetail.setUserId(studentId);
-			musicGroupPaymentCalenderDetail.setStartPaymentDate(musicGroupPaymentCalender.getStartPaymentDate());
-			musicGroupPaymentCalenderDetail.setDeadlinePaymentDate(musicGroupPaymentCalender.getDeadlinePaymentDate());
-			musicGroupPaymentCalenderDetail.setResponsibleUserId(musicGroupPaymentCalender.getOperator());
-
-			musicGroupPaymentCalenderDetailList.add(musicGroupPaymentCalenderDetail);
-		}
-
-		Map<Integer,Long> userMap = new HashMap<>();
-		if (musicGroupPaymentCalenderDetailList.size() > 0) {
-			musicGroupPaymentCalenderDetailDao.batchInsert(musicGroupPaymentCalenderDetailList);
-			for(MusicGroupPaymentCalenderDetail cd : musicGroupPaymentCalenderDetailList){
-				userMap.put(cd.getUserId(), cd.getId());
-			}
-		}
-		//更新预计缴费人数
-		musicGroupPaymentCalender.setExpectNum(musicGroupPaymentCalender.getExpectNum() + userIdList.size());
-		if (musicGroupPaymentCalender.getCurrentTotalAmount().compareTo(BigDecimal.ZERO) == 0) {
-			musicGroupPaymentCalender.setActualNum(musicGroupPaymentCalender.getActualNum() + userIdList.size());
-		}
-		musicGroupPaymentCalender.setUpdateTime(date);
-		musicGroupPaymentCalenderService.update(musicGroupPaymentCalender);
-
-		List<MusicGroupPaymentStudentCourseDetail> musicGroupPaymentStudentCourseDetailList = new ArrayList<MusicGroupPaymentStudentCourseDetail>();
-		MusicGroupPaymentStudentCourseDetail musicGroupPaymentStudentCourseDetail = null;
-		if(courseSettingsList.size() > 0){
-			//创建学生课排课分钟数
-			for(Integer studentId : userIdList){
-				for(MusicGroupPaymentCalenderCourseSettings courseSettings : courseSettingsList){
-					if (courseSettings.getIsStudentOptional() == true || courseSettings.getCourseTotalMinuties() == null || courseSettings.getCourseTotalMinuties() == 0) {
-						continue;
-					}
-					musicGroupPaymentStudentCourseDetail = new MusicGroupPaymentStudentCourseDetail();
-					musicGroupPaymentStudentCourseDetail.setCourseType(courseSettings.getCourseType());
-					musicGroupPaymentStudentCourseDetail.setCreateTime(date);
-					musicGroupPaymentStudentCourseDetail.setMusicGroupPaymentCalenderId(musicGroupPaymentCalenderId);
-					musicGroupPaymentStudentCourseDetail.setMusicGroupPaymentCalenderDetailId(userMap.get(studentId));
-					musicGroupPaymentStudentCourseDetail.setTotalCourseMinutes(courseSettings.getCourseTotalMinuties());
-					musicGroupPaymentStudentCourseDetail.setCourseOriginalPrice(courseSettings.getCourseOriginalPrice());
-					musicGroupPaymentStudentCourseDetail.setCourseCurrentPrice(courseSettings.getCourseCurrentPrice());
-					musicGroupPaymentStudentCourseDetail.setUpdateTime(date);
-					musicGroupPaymentStudentCourseDetail.setUsedCourseMinutes(0);
-					musicGroupPaymentStudentCourseDetail.setUserId(studentId);
-					musicGroupPaymentStudentCourseDetailList.add(musicGroupPaymentStudentCourseDetail);
-				}
-			}
-		}
-
-		if(musicGroupPaymentStudentCourseDetailList.size() > 0){
-			musicGroupPaymentStudentCourseDetailDao.batchInsert(musicGroupPaymentStudentCourseDetailList);
-		}
-		if(!autoCreate){
-			//给学员推送缴费通知
-			if(musicGroupPaymentCalender.getPayUserType() == STUDENT && musicGroupPaymentCalender.getStatus() == PaymentCalenderStatusEnum.OPEN){
-				musicGroupPaymentCalenderService.pushWaitRenewMessage(musicGroupPaymentCalenderId,musicGroupDao.get(musicGroupPaymentCalender.getMusicGroupId()),userIdList);
-			}
-		}
-	}
 
 	@Override
 	@Transactional(rollbackFor = Exception.class)
@@ -590,6 +311,9 @@ public class MusicGroupPaymentCalenderDetailServiceImpl extends BaseServiceImpl<
 			MusicGroupPaymentStudentCourseDetail musicGroupPaymentStudentCourseDetail = null;
 			for(Integer studentId : userIdList){
 				for(MusicGroupPaymentCalenderCourseSettings courseSettings : courseSettingsList){
+					if (courseSettings.getCourseTotalMinuties() == null || courseSettings.getCourseTotalMinuties() == 0) {
+						continue;
+					}
 					musicGroupPaymentStudentCourseDetail = new MusicGroupPaymentStudentCourseDetail();
 					musicGroupPaymentStudentCourseDetail.setCourseType(courseSettings.getCourseType());
 					musicGroupPaymentStudentCourseDetail.setCreateTime(date);
@@ -604,7 +328,9 @@ public class MusicGroupPaymentCalenderDetailServiceImpl extends BaseServiceImpl<
 					musicGroupPaymentStudentCourseDetailList.add(musicGroupPaymentStudentCourseDetail);
 				}
 			}
-			musicGroupPaymentStudentCourseDetailDao.batchInsert(musicGroupPaymentStudentCourseDetailList);
+			if(musicGroupPaymentStudentCourseDetailList.size() > 0){
+				musicGroupPaymentStudentCourseDetailDao.batchInsert(musicGroupPaymentStudentCourseDetailList);
+			}
 		}
 		//给学员推送缴费通知
 		if (musicGroupPaymentCalender.getPayUserType() == STUDENT && musicGroupPaymentCalender.getStatus() == PaymentCalenderStatusEnum.OPEN) {

+ 52 - 105
mec-biz/src/main/java/com/ym/mec/biz/service/impl/MusicGroupPaymentCalenderServiceImpl.java

@@ -12,11 +12,14 @@ import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentCalenderStatus
 import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentType;
 import com.ym.mec.biz.dal.entity.MusicGroupStudentFee.PaymentStatus;
 import com.ym.mec.biz.dal.enums.*;
+import com.ym.mec.biz.dal.page.BaseOrganQueryInfo;
 import com.ym.mec.biz.dal.page.MusicGroupPaymentCalenderQueryInfo;
 import com.ym.mec.biz.event.source.GroupEventSource;
 import com.ym.mec.biz.event.source.SendSeoMessageSource;
 import com.ym.mec.biz.service.*;
+import com.ym.mec.common.controller.BaseController;
 import com.ym.mec.common.dal.BaseDAO;
+import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.exception.BizException;
 import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.service.IdGeneratorService;
@@ -26,9 +29,12 @@ import com.ym.mec.util.collection.MapUtil;
 import com.ym.mec.util.date.DateUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Isolation;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+import org.springframework.ui.ModelMap;
 
 import java.math.BigDecimal;
 import java.util.*;
@@ -69,14 +75,8 @@ public class MusicGroupPaymentCalenderServiceImpl extends BaseServiceImpl<Long,
     @Autowired
     private MusicGroupDao musicGroupDao;
     @Autowired
-    private ClassGroupDao classGroupDao;
-    @Autowired
     private CourseScheduleDao courseScheduleDao;
     @Autowired
-    private CourseScheduleTeacherSalaryDao courseScheduleTeacherSalaryDao;
-    @Autowired
-    private TeacherAttendanceDao teacherAttendanceDao;
-    @Autowired
     private MusicGroupBuildLogDao musicGroupBuildLogDao;
     @Autowired
     private SysConfigDao sysConfigDao;
@@ -89,12 +89,8 @@ public class MusicGroupPaymentCalenderServiceImpl extends BaseServiceImpl<Long,
     @Autowired
     private SysUserFeignService sysUserFeignService;
     @Autowired
-    private ImGroupMemberService imGroupMemberService;
-    @Autowired
     private ImUserFriendService imUserFriendService;
     @Autowired
-    private ClassGroupStudentMapperDao classGroupStudentMapperDao;
-    @Autowired
     private MusicGroupStudentClassAdjustDao musicGroupStudentClassAdjustDao;
     @Autowired
     private MusicGroupPaymentCalenderDetailService musicGroupPaymentCalenderDetailService;
@@ -222,7 +218,7 @@ public class MusicGroupPaymentCalenderServiceImpl extends BaseServiceImpl<Long,
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public String create1(MusicGroupPaymentBaseCalender musicGroupPaymentBaseCalender) {
+    public HttpResponseResult<ModelMap> create1(MusicGroupPaymentBaseCalender musicGroupPaymentBaseCalender) {
         checkObjectNull(musicGroupPaymentBaseCalender, o -> {
             throw new BizException("参数校验异常");
         });
@@ -237,20 +233,15 @@ public class MusicGroupPaymentCalenderServiceImpl extends BaseServiceImpl<Long,
             throw new BizException("请登录");
         });
 
-//		if(musicGroupPaymentBaseCalender.getCalenderActivityList() == null
-//				&& musicGroupPaymentBaseCalender.getCalenderMember() == null
-//				&& musicGroupPaymentBaseCalender.getMusicGroupPaymentCalenderCourseSettingsList() == null
-//				&& musicGroupPaymentBaseCalender.getMusicRepair() == null){
-//			throw new BizException("请选择一个缴费项目");
-//		}
         if (musicGroup.getStatus() != MusicGroupStatusEnum.PROGRESS && musicGroup.getStatus() != MusicGroupStatusEnum.PRE_BUILD_FEE) {
             throw new BizException("创建缴费失败:已存在缴费项目");
         }
         // 所有缴费项目已完成排课才能创建下一个缴费项目
-        /*String orignBatchNo = musicGroupPaymentStudentCourseDetailDao.getUnUseBatchNoWithStudentAndCourseTypeAndCourseMinutes(musicGroupId, null, null, null);
-        if (StringUtils.isNoneBlank(orignBatchNo)) {
-            throw new BizException("当前乐团存在未排课的缴费项目,请先完成排课再操作");
-        }*/
+        String orignBatchNo = musicGroupPaymentStudentCourseDetailDao.getUnUseBatchNoWithStudentAndCourseTypeAndCourseMinutes(musicGroupId, null, null, null);
+        if (!musicGroupPaymentBaseCalender.getConfirmCreate() && StringUtils.isNoneBlank(orignBatchNo)) {
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+            return BaseController.failed(HttpStatus.MULTI_STATUS,"当前乐团存在未排课的缴费项目,请再次确认操作");
+        }
 
         // 不是进行中,只能创建一次缴费
         if (musicGroup.getStatus() != MusicGroupStatusEnum.PROGRESS) {
@@ -413,7 +404,7 @@ public class MusicGroupPaymentCalenderServiceImpl extends BaseServiceImpl<Long,
                     null, null, MessageTypeEnum.BACKSTAGE_PAYMENT_CALENDER_AUDIT, organization.getName(), musicGroup.getName());
         } else {
             if (musicGroupPaymentCalender.getPaymentType() == PaymentType.ADD_STUDENT) {
-                addStudent(musicGroupPaymentCalender, musicGroupPaymentCalender.getMusicGroupPaymentCalenderCourseSettingsList(), musicGroup);
+                addStudent(musicGroupPaymentCalender, musicGroup);
                 //将0元未缴费学员缴费状态更新为已缴费
                 this.updateNoPaymentAndZeroPaymentStatus(musicGroupPaymentCalender, true);
                 // 学生加到班级
@@ -426,7 +417,9 @@ public class MusicGroupPaymentCalenderServiceImpl extends BaseServiceImpl<Long,
                 executor.shutdown();
             }
         }
-        return batchNo;
+        ModelMap map = new ModelMap(1);
+        map.put("musicGroupPaymentCalenderBatchNo", batchNo);
+        return BaseController.succeed(map);
     }
 
     //校验缴费项目进行中加学员
@@ -618,13 +611,13 @@ public class MusicGroupPaymentCalenderServiceImpl extends BaseServiceImpl<Long,
         musicGroupPaymentCalender.setBatchNo(batchNo);
         musicGroupPaymentCalenderDto.setBatchNo(batchNo);
         musicGroupPaymentCalenderDao.insert(musicGroupPaymentCalender);
-        List<MusicGroupPaymentCalenderCourseSettings> currentMusicGroupPaymentCalenderCourseSettings = musicGroupPaymentCalender
-                .getMusicGroupPaymentCalenderCourseSettingsList();
+//        List<MusicGroupPaymentCalenderCourseSettings> currentMusicGroupPaymentCalenderCourseSettings = musicGroupPaymentCalender
+//                .getMusicGroupPaymentCalenderCourseSettingsList();
 
         if (musicGroupPaymentCalender.getStatus() != AUDITING) {
             // 如果是进行中加学生
             if (musicGroupPaymentCalender.getPaymentType() == PaymentType.ADD_STUDENT) {
-                addStudent(musicGroupPaymentCalender, currentMusicGroupPaymentCalenderCourseSettings, musicGroup);
+                addStudent(musicGroupPaymentCalender, musicGroup);
             } else if (musicGroupPaymentCalender.getPaymentType() == SPAN_GROUP_CLASS_ADJUST) {
                 //如果是跨团班级合并,添加学员
                 musicGroupPaymentCalenderDetailService.batchAdd(musicGroupPaymentCalender, musicGroupPaymentCalenderDto.getMusicGroupPaymentCalenderStudentDetails());
@@ -685,7 +678,6 @@ public class MusicGroupPaymentCalenderServiceImpl extends BaseServiceImpl<Long,
     @Transactional(rollbackFor = Exception.class)
     @Override
     public void addStudent(MusicGroupPaymentCalender musicGroupPaymentCalender,
-                           List<MusicGroupPaymentCalenderCourseSettings> musicGroupPaymentCalenderCourseSettingsList,
                            MusicGroup musicGroup) {
         //如果是进行中加学生
         Date date = new Date();
@@ -693,8 +685,8 @@ public class MusicGroupPaymentCalenderServiceImpl extends BaseServiceImpl<Long,
         if (StringUtils.isNoneBlank(studentIdStr)) {
             //当前乐团是否有预排课计划
             MusicGroupSchoolTermCourseDetail termCourseDetail = musicGroupSchoolTermCourseDetailDao.findByCourseDateAndMusicGroupId(musicGroup.getId(), null, 0);
-            List<MusicGroupPaymentStudentCourseDetail> musicGroupPaymentStudentCourseDetailList = new ArrayList<MusicGroupPaymentStudentCourseDetail>();
-            MusicGroupPaymentStudentCourseDetail musicGroupPaymentStudentCourseDetail = null;
+//            List<MusicGroupPaymentStudentCourseDetail> musicGroupPaymentStudentCourseDetailList = new ArrayList<MusicGroupPaymentStudentCourseDetail>();
+//            MusicGroupPaymentStudentCourseDetail musicGroupPaymentStudentCourseDetail = null;
 
             List<MusicGroupPaymentCalenderActivity> calenderActivities = musicGroupPaymentCalenderActivityService.findByCalenderId(musicGroupPaymentCalender.getId());
             MusicGroupPaymentCalenderMember calenderMember = musicGroupPaymentCalenderMemberService.findByCalenderId(musicGroupPaymentCalender.getId());
@@ -768,7 +760,7 @@ public class MusicGroupPaymentCalenderServiceImpl extends BaseServiceImpl<Long,
                     //统计变更学员数
                     groupEventSource.musicGroupStudentChangeEvent(musicGroupPaymentCalender.getMusicGroupId(), StudentMusicGroupStatusEnum.NORMAL, new ArrayList<>(Arrays.asList(Integer.parseInt(studentId))));
                 }
-                if (musicGroupPaymentCalenderCourseSettingsList != null && musicGroupPaymentCalenderCourseSettingsList.size() > 0) {
+                /*if (musicGroupPaymentCalenderCourseSettingsList != null && musicGroupPaymentCalenderCourseSettingsList.size() > 0) {
                     // 学生加课程明细
                     for (MusicGroupPaymentCalenderCourseSettings courseSettings : musicGroupPaymentCalenderCourseSettingsList) {
                         if (courseSettings.getIsStudentOptional() == true) {
@@ -787,11 +779,10 @@ public class MusicGroupPaymentCalenderServiceImpl extends BaseServiceImpl<Long,
                         musicGroupPaymentStudentCourseDetail.setUserId(Integer.parseInt(studentId));
                         musicGroupPaymentStudentCourseDetailList.add(musicGroupPaymentStudentCourseDetail);
                     }
-
                 }
                 if (musicGroupPaymentStudentCourseDetailList.size() > 0) {
                     musicGroupPaymentStudentCourseDetailDao.batchInsert(musicGroupPaymentStudentCourseDetailList);
-                }
+                }*/
             }
         }
     }
@@ -923,71 +914,6 @@ public class MusicGroupPaymentCalenderServiceImpl extends BaseServiceImpl<Long,
         return calenderAuditDetailDto;
     }
 
-    //审核通过后自动排课
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void autoClassGroupAdjust(MusicGroupStudentClassAdjust musicGroupStudentClassAdjust) {
-        List<MusicGroupPaymentCalender> musicGroupPaymentCalenders = musicGroupPaymentCalenderDao.findByBatchNo(musicGroupStudentClassAdjust.getBatchNo());
-        for (MusicGroupPaymentCalender musicGroupPaymentCalender : musicGroupPaymentCalenders) {
-            if (musicGroupPaymentCalender.getStatus() == AUDITING || musicGroupPaymentCalender.getStatus() == REJECT) {
-                return;
-            }
-        }
-        List<ClassGroup4MixDto> classGroup4MixDtos = JSON.parseArray(musicGroupStudentClassAdjust.getNewClassGroupJson(), ClassGroup4MixDto.class);
-        String musicGroupId = musicGroupPaymentCalenders.get(0).getMusicGroupId();
-        MusicGroup musicGroup = musicGroupDao.get(musicGroupId);
-        for (MusicGroupPaymentCalender calender : musicGroupPaymentCalenders) {
-            //缴费项目添加学员
-            int[] ints = Arrays.stream(calender.getStudentIds().split(",")).mapToInt(Integer::parseInt).toArray();
-            Set<Integer> list2 = Arrays.stream(ints).boxed().collect(Collectors.toSet());
-            musicGroupPaymentCalenderDetailService.batchAdd(calender.getId(), list2, musicGroup, false);
-        }
-        //每种课程类型单独排课
-        ClassGroup classGroup = null;
-        for (ClassGroup4MixDto classGroup4MixDto : classGroup4MixDtos) {
-            classGroup4MixDto.setClassGroup(classGroup);
-            classGroup4MixDto.setMusicGroupStudentClassAdjustId(musicGroupStudentClassAdjust.getId());
-            classGroup4MixDto.setClassCourseMinute(musicGroupStudentClassAdjust.getClassCourseMinute());
-            classGroup = classGroupService.classGroupAdjust2(classGroup4MixDto);
-        }
-        //排课完成后删除所选课程
-        List<Long> courseIds = JSON.parseArray(musicGroupStudentClassAdjust.getSubLockCourseIds(), Long.class);
-        List<Integer> studentIds = JSON.parseArray(musicGroupStudentClassAdjust.getStudentIds(), Integer.class);
-        courseScheduleDao.deleteMusicGroupCourseSchedulesWithStudents(courseIds, studentIds);
-        //解冻课程
-        List<Long> allCourseIds = JSON.parseArray(musicGroupStudentClassAdjust.getAllLockCourseIds(), Long.class);
-        courseScheduleDao.batchUpdateLockByCourseIds(allCourseIds, 0, null);
-        //解冻班级
-        List<Integer> classGroupIds = JSON.parseArray(musicGroupStudentClassAdjust.getClassGroupIds(), Integer.class);
-        classGroupDao.batchUpdateLockByClassGroupIds(classGroupIds, 0);
-        //删除班级学员
-        musicGroupStudentClassAdjustDao.update(musicGroupStudentClassAdjust);
-        String classGroupStudents = musicGroupStudentClassAdjust.getClassGroupStudents();
-        if (StringUtils.isNotEmpty(classGroupStudents)) {
-            List<Map> maps = JSON.parseArray(classGroupStudents, Map.class);
-            for (Map<Integer, String> classGroupStudent : maps) {
-                Set<Integer> integers = classGroupStudent.keySet();
-                for (Integer integer : integers) {
-                    List<Integer> collect = Arrays.asList(classGroupStudent.get(integer).split(",")).stream().map(e -> Integer.parseInt(e)).collect(Collectors.toList());
-                    //学员退出群聊
-                    imGroupMemberService.quit(integer.longValue(), collect);
-                    classGroupStudentMapperDao.deleteByClassGroupIdAndStudents(integer, classGroupStudent.get(integer));
-                }
-            }
-        }
-        //获取没有学员的课程列表
-        List<Long> delCourseIds = courseScheduleDao.findNoStudentCourseIds(courseIds);
-        if (delCourseIds != null && delCourseIds.size() > 0) {
-            //删除课程
-            courseScheduleDao.deleteCourseSchedulesByClassGroupIds(delCourseIds);
-            //删除教师考勤
-            teacherAttendanceDao.batchDeleteByCourseSchedules(delCourseIds);
-            //删除教师课酬
-            courseScheduleTeacherSalaryDao.batchDeleteByCourseScheduleIds(delCourseIds);
-        }
-        classGroupService.batchUpdateTeacherSalary(classGroupIds);
-        imUserFriendService.refreshGroupImUserFriend(musicGroupId, GroupType.MUSIC);
-    }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -1021,8 +947,8 @@ public class MusicGroupPaymentCalenderServiceImpl extends BaseServiceImpl<Long,
 
                 if (musicGroupPaymentCalender.getPaymentType() == PaymentType.ADD_STUDENT) {
                     musicGroupPaymentCalender.setExpectNum(1);
-                    List<MusicGroupPaymentCalenderCourseSettings> musicGroupPaymentCalenderCourseSettings = musicGroupPaymentCalenderCourseSettingsService.queryCalenderCourseSettings(musicGroupPaymentCalender.getId());
-                    addStudent(musicGroupPaymentCalender, musicGroupPaymentCalenderCourseSettings, musicGroup);
+//                    List<MusicGroupPaymentCalenderCourseSettings> musicGroupPaymentCalenderCourseSettings = musicGroupPaymentCalenderCourseSettingsService.queryCalenderCourseSettings(musicGroupPaymentCalender.getId());
+                    addStudent(musicGroupPaymentCalender, musicGroup);
                 }
             }
             if (calender.getPaymentType() == ADD_STUDENT || calender.getPaymentType() == SPAN_GROUP_CLASS_ADJUST) {
@@ -1071,11 +997,11 @@ public class MusicGroupPaymentCalenderServiceImpl extends BaseServiceImpl<Long,
                     classGroupService.addStudentToClassGroupAndCourseArranging(Integer.parseInt(calender.getStudentIds()), classGroupIdStr, batchNo,
                             musicGroupPaymentCalenderCourseSettingsService.queryCalenderCourseSettingsByBatchNo(batchNo), musicGroup);
                 }
-                MusicGroupStudentClassAdjust musicGroupStudentClassAdjust = musicGroupStudentClassAdjustDao.findByBatchNo(batchNo);
-                if (musicGroupStudentClassAdjust != null) {
-                    //如果是合班缴费
-                    autoClassGroupAdjust(musicGroupStudentClassAdjust);
-                }
+//                MusicGroupStudentClassAdjust musicGroupStudentClassAdjust = musicGroupStudentClassAdjustDao.findByBatchNo(batchNo);
+//                if (musicGroupStudentClassAdjust != null) {
+//                    如果是合班缴费
+//                    autoClassGroupAdjust(musicGroupStudentClassAdjust);
+//                }
             } else if (calender.getPaymentType() == SPAN_GROUP_CLASS_ADJUST) {
                 //删除和解冻班级,课程信息
                 MusicGroupStudentClassAdjust adjust = musicGroupStudentClassAdjustDao.findByBatchNo(batchNo);
@@ -1221,7 +1147,7 @@ public class MusicGroupPaymentCalenderServiceImpl extends BaseServiceImpl<Long,
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public String merge1(MusicGroupPaymentBaseCalender musicGroupPaymentBaseCalender) {
+    public HttpResponseResult<ModelMap> merge1(MusicGroupPaymentBaseCalender musicGroupPaymentBaseCalender) {
         del(musicGroupPaymentBaseCalender.getCalenderId());
         return create1(musicGroupPaymentBaseCalender);
     }
@@ -1260,6 +1186,27 @@ public class MusicGroupPaymentCalenderServiceImpl extends BaseServiceImpl<Long,
     }
 
     @Override
+    public PageInfo<HasFreeCourseTimesDto> queryHasFreeCourseTimesStudent(BaseOrganQueryInfo queryInfo) {
+        PageInfo<HasFreeCourseTimesDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
+        Map<String, Object> params = new HashMap<String, Object>();
+        MapUtil.populateMap(params, queryInfo);
+
+        List<HasFreeCourseTimesDto> dataList = null;
+
+        int count = musicGroupDao.countHasFreeCourseTimes(params);
+        if (count > 0) {
+            pageInfo.setTotal(count);
+            params.put("offset", pageInfo.getOffset());
+            dataList = musicGroupDao.queryHasFreeCourseTimes(params);
+        }
+        if (count == 0) {
+            dataList = new ArrayList<>();
+        }
+        pageInfo.setRows(dataList);
+        return pageInfo;
+    }
+
+    @Override
     @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
     public boolean autoUpdateMusicGroupPaymentCalenderStatus() {
         Date date = new Date();

+ 8 - 2
mec-biz/src/main/java/com/ym/mec/biz/service/impl/MusicGroupQuestionnaireServiceImpl.java

@@ -84,7 +84,10 @@ public class MusicGroupQuestionnaireServiceImpl extends BaseServiceImpl<Integer,
 			result.setActiveType(QuestionnaireActiveTypeEnum.MUSIC_GROUP_QUESTION);
 		}
 		//删除原来的问卷结果
-		questionnaireUserResultDao.delByActiveIdAndUserId(musicGroupQuestionnaire.getId(), null,"MUSIC_GROUP_QUESTION");
+		HashMap<String, Object> paramMap = new HashMap<>(4);
+		paramMap.put("activeId",musicGroupQuestionnaire.getId());
+		paramMap.put("activeType",QuestionnaireActiveTypeEnum.MUSIC_GROUP_QUESTION);
+		questionnaireUserResultDao.delByActiveIdAndUserId(paramMap);
 		questionnaireUserResultDao.batchInsert1(questionnaireUserResultList);
 	}
 
@@ -102,7 +105,10 @@ public class MusicGroupQuestionnaireServiceImpl extends BaseServiceImpl<Integer,
 	@Override
 	@Transactional(rollbackFor = Exception.class)
 	public void del(Integer id) {
-		questionnaireUserResultDao.delByActiveIdAndUserId(id, null,"MUSIC_GROUP_QUESTION");
+		HashMap<String, Object> paramMap = new HashMap<>(4);
+		paramMap.put("activeId",id);
+		paramMap.put("activeType",QuestionnaireActiveTypeEnum.MUSIC_GROUP_QUESTION);
+		questionnaireUserResultDao.delByActiveIdAndUserId(paramMap);
 		musicGroupQuestionnaireDao.delete(id);
 	}
 }

+ 19 - 6
mec-biz/src/main/java/com/ym/mec/biz/service/impl/MusicGroupServiceImpl.java

@@ -32,7 +32,6 @@ import com.ym.mec.util.collection.MapUtil;
 import com.ym.mec.util.date.DateUtil;
 import com.ym.mec.util.http.HttpUtil;
 import com.ym.mec.util.json.JsonUtil;
-
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
@@ -127,8 +126,6 @@ public class MusicGroupServiceImpl extends BaseServiceImpl<String, MusicGroup> i
     @Autowired
     private SysUserFeignService sysUserFeignService;
     @Autowired
-    private EmployeeDao employeeDao;
-    @Autowired
     private SysMessageService sysMessageService;
     @Autowired
     private SysConfigDao sysConfigDao;
@@ -3076,8 +3073,15 @@ public class MusicGroupServiceImpl extends BaseServiceImpl<String, MusicGroup> i
         if (sysUser == null) {
             throw new BizException("获取用户信息失败");
         }
-        PageInfo<MusicGroup> musicGroupPageInfo;
-        musicGroupPageInfo = queryPage(queryInfo);
+        //查询有剩余排课时长的乐团
+        if("MUSIC_GROUP_HAS_COURSE_TIMES".equals(queryInfo.getSearchType())){
+            List<String> musicGroupIds = musicGroupDao.queryHasSubCourseTimes(queryInfo.getOrganId(),queryInfo.getTenantId());
+            if(musicGroupIds == null || musicGroupIds.size() == 0){
+                return new PageInfo<>();
+            }
+            queryInfo.setMusicGroupIds(musicGroupIds);
+        }
+        PageInfo<MusicGroup> musicGroupPageInfo = queryPage(queryInfo);
         List<MusicGroup> musicGroupList = musicGroupPageInfo.getRows();
 
         if (musicGroupList == null || musicGroupList.size() == 0) {
@@ -3710,7 +3714,16 @@ public class MusicGroupServiceImpl extends BaseServiceImpl<String, MusicGroup> i
             }
             //退用户余额
             if (userReBack.compareTo(BigDecimal.ZERO) > 0) {
-                sysUserCashAccountService.updateBalance(musicGroupReg.getUserId(), userReBack, PlatformCashAccountDetailTypeEnum.REFUNDS, "关闭乐团");
+                SysUserCashAccountLog sysUserCashAccountLog = new SysUserCashAccountLog();
+                sysUserCashAccountLog.setGroupType(GroupType.MUSIC);
+                sysUserCashAccountLog.setUserId(musicGroupReg.getUserId());
+                sysUserCashAccountLog.setOrganId(musicGroup.getOrganId());
+                sysUserCashAccountLog.setGroupId(musicGroup.getId());
+                sysUserCashAccountLog.setAmount(userReBack);
+                sysUserCashAccountLog.setReturnFeeType(ReturnFeeEnum.MUSIC);
+                sysUserCashAccountLog.setComment("关闭乐团");
+                sysUserCashAccountLogDao.insert(sysUserCashAccountLog);
+//                sysUserCashAccountService.updateBalance(musicGroupReg.getUserId(), userReBack, PlatformCashAccountDetailTypeEnum.REFUNDS, "关闭乐团");
             }
             //清除剩余课程费用
             if (musicGroupReg.getSurplusCourseFee().compareTo(BigDecimal.ZERO) > 0) {

+ 25 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/OrganizationServiceImpl.java

@@ -225,4 +225,29 @@ public class OrganizationServiceImpl extends BaseServiceImpl<Integer, Organizati
 		return true;
 	}
 
+    @Override
+	@Transactional(rollbackFor = Exception.class)
+    public Long add(Organization organization) {
+		long insert = organizationDao.insert(organization);
+		TenantInfo tenantInfo = tenantInfoDao.selectById(organization.getTenantId());
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		if(!sysUser.getId().equals(tenantInfo.getUserId())){
+			updateOrganId(tenantInfo.getUserId(),organization.getId());
+		}
+		updateOrganId(sysUser.getId(),organization.getId());
+		return insert;
+    }
+
+	@Transactional(rollbackFor = Exception.class)
+    public void updateOrganId(Integer userId,Integer organId){
+		Employee employee = employeeDao.get(userId);
+		String organIdList = employee.getOrganIdList();
+		if(StringUtils.isNotEmpty(organIdList)){
+			employee.setOrganIdList(new StringBuffer(organIdList).append(",").append(organId).toString());
+		}else {
+			employee.setOrganIdList(organId+"");
+		}
+		employeeDao.update(employee);
+	}
+
 }

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

@@ -129,6 +129,11 @@ public class QuestionnaireTopicServiceImpl extends BaseServiceImpl<Integer, Ques
 		if(questionnaireTopic == null){
 			throw new BizException("问卷[{}]模板查询失败", topicId);
 		}
+		//调查问卷是否有用户参与
+		int num = questionnaireUserResultDao.countByTopicId(topicId);
+		if(num > 0){
+			questionnaireTopic.setModifyFlag(false);
+		}
 		Map<String,Object> paramMap = new HashMap(1);
 		paramMap.put("topicId",topicId);
 		paramMap.put("tenantId",questionnaireTopic.getTenantId());

+ 80 - 154
mec-biz/src/main/java/com/ym/mec/biz/service/impl/QuestionnaireUserResultServiceImpl.java

@@ -1,47 +1,32 @@
 package com.ym.mec.biz.service.impl;
 
-import com.alibaba.fastjson.JSONObject;
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.biz.dal.dao.*;
-import com.ym.mec.biz.dal.dto.ExportDto;
 import com.ym.mec.biz.dal.dto.QuestionnaireUserResultDto;
 import com.ym.mec.biz.dal.dto.ReplacementInstrumentActivityDto;
-import com.ym.mec.biz.dal.entity.*;
-import com.ym.mec.biz.dal.enums.ExportEnum;
-import com.ym.mec.biz.dal.enums.MessageTypeEnum;
+import com.ym.mec.biz.dal.entity.QuestionnaireQuestion;
+import com.ym.mec.biz.dal.entity.QuestionnaireQuestionItem;
+import com.ym.mec.biz.dal.entity.QuestionnaireTopic;
+import com.ym.mec.biz.dal.entity.QuestionnaireUserResult;
 import com.ym.mec.biz.dal.enums.QuestionnaireActiveTypeEnum;
-import com.ym.mec.biz.dal.enums.YesOrNoEnum;
 import com.ym.mec.biz.dal.page.QuestionnaireUserResultQueryInfo;
-import com.ym.mec.biz.dal.page.ReplacementInstrumentActivityQueryInfo;
-import com.ym.mec.biz.service.CooperationOrganService;
-import com.ym.mec.biz.service.ExportService;
+import com.ym.mec.biz.service.QuestionnaireUserResultService;
 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.page.QueryInfo;
-import com.ym.mec.common.tenant.TenantContextHolder;
-import com.ym.mec.thirdparty.message.MessageSenderPluginContext;
+import com.ym.mec.common.service.impl.BaseServiceImpl;
 import com.ym.mec.util.collection.MapUtil;
-import com.ym.mec.util.date.DateUtil;
-import com.ym.mec.util.excel.POIUtil;
-import com.ym.mec.util.http.HttpUtil;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.springframework.beans.factory.annotation.Autowired;
-import com.ym.mec.common.service.impl.BaseServiceImpl;
-import com.ym.mec.biz.service.QuestionnaireUserResultService;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.OutputStream;
+import java.time.Instant;
 import java.util.*;
 import java.util.stream.Collectors;
 
-import static com.ym.mec.biz.dal.enums.QuestionnaireActiveTypeEnum.CLOUD_TEACHER_FEEDBACK;
-
 @Service
 public class QuestionnaireUserResultServiceImpl extends BaseServiceImpl<Long, QuestionnaireUserResult>  implements QuestionnaireUserResultService {
 	
@@ -57,10 +42,6 @@ public class QuestionnaireUserResultServiceImpl extends BaseServiceImpl<Long, Qu
 	private TeacherDao teacherDao;
 	@Autowired
 	private StudentDao studentDao;
-	@Autowired
-	private QuestionnaireQuestionDao questionnaireQuestionDao;
-	@Autowired
-	private ExportService exportService;
 
 	@Override
 	public BaseDAO<Long, QuestionnaireUserResult> getDAO() {
@@ -93,10 +74,10 @@ public class QuestionnaireUserResultServiceImpl extends BaseServiceImpl<Long, Qu
 	}
 
 	@Override
-	public Map<String,Object> questionnaireUserResultExport(String activeType,Integer cooperationId,List<QuestionnaireQuestion> questionList) {
+	public Map<String,Object> getExportBody(QuestionnaireTopic topic,List<QuestionnaireQuestion> questionList) {
 		HashMap<String, Object> paramMap = new HashMap<>(2);
-		paramMap.put("activeId",cooperationId);
-		paramMap.put("activeType",activeType);
+		paramMap.put("topicId",topic.getId());
+		paramMap.put("tenantId",topic.getTenantId());
 		List<QuestionnaireUserResult> userResults = questionnaireUserResultDao.findAll(paramMap);
 
 		Map<String,Object> resultMap = new HashMap<>(2);
@@ -118,35 +99,33 @@ public class QuestionnaireUserResultServiceImpl extends BaseServiceImpl<Long, Qu
 				userIdSet.add(userResult.getUserId());
 			}
 			List<Integer> userIdList = new ArrayList<>(userIdSet);
+			Map<Integer, String> nameList = null;
 			Map<Integer, List<QuestionnaireUserResult>> userIdMap = userResults.parallelStream().collect(Collectors.groupingBy(QuestionnaireUserResult::getUserId));
-//			List<Integer> userIdList = new ArrayList<>(userIdMap.keySet());
-//			Collections.sort(userIdList);
-			Map<Integer, String> nameList;
-			if(cooperationId != null){
-				nameList = MapUtil.convertMybatisMap(questionnaireQuestionItemDao.queryUserName(cooperationId));
-			}else {
-				nameList = MapUtil.convertMybatisMap(questionnaireUserResultDao.queryUserName(activeType));
+			Map<Integer, String> phoneList = null;
+			Map<Integer, String> organNameMap = null;
+			Boolean isLogin = topic.getLoginFlag() == 1;
+			if(isLogin){
+				nameList = MapUtil.convertMybatisMap(questionnaireUserResultDao.queryUserName(topic.getId()));
+				phoneList = MapUtil.convertMybatisMap(teacherDao.queryPhoneByIds(StringUtils.join(userIdList,",")));
+				organNameMap = MapUtil.convertMybatisMap(studentDao.queryStudentOrganNameMap(userIdList));
 			}
-			Map<Integer, String> phoneList = MapUtil.convertMybatisMap(teacherDao.queryPhoneByIds(StringUtils.join(userIdList,",")));
-
-			Map<Integer, String> organNameMap = MapUtil.convertMybatisMap(studentDao.queryStudentOrganNameMap(userIdList));
 			for (Integer userId : userIdList) {
 				List<QuestionnaireUserResult> userResultList = userIdMap.get(userId);
 				if(userResultList != null && userResultList.size() > 0){
 					QuestionnaireUserResult result1 = userResultList.get(0);
 					Map<String,Object> jsonObject = new LinkedHashMap<>();
-					body.add("cooperationId");
-					body.add("organName");
+					if(isLogin){
+						body.add("organName");
+						jsonObject.put("organName",organNameMap.get(userId));
+						body.add("userId");
+						jsonObject.put("userId",userId);
+						body.add("userName");
+						jsonObject.put("userName",nameList.get(userId));
+						body.add("phone");
+						jsonObject.put("phone",phoneList.get(userId));
+					}
 					body.add("createTime");
-					body.add("userId");
-					body.add("userName");
-					body.add("phone");
-					jsonObject.put("cooperationId",cooperationId);
-					jsonObject.put("organName",organNameMap.get(userId));
 					jsonObject.put("createTime",result1.getCreateTime());
-					jsonObject.put("userId",userId);
-					jsonObject.put("userName",nameList.get(userId));
-					jsonObject.put("phone",phoneList.get(userId));
 					//分解当前学员答案
 					for (QuestionnaireUserResult result : userResultList) {
 						//获取问题列表
@@ -179,37 +158,45 @@ public class QuestionnaireUserResultServiceImpl extends BaseServiceImpl<Long, Qu
     @Override
 	@Transactional(rollbackFor = Exception.class)
     public void add(ReplacementInstrumentActivityDto replacementInstrumentActivity) {
-		SysUser sysUser = sysUserFeignService.queryUserInfo();
-		if (sysUser == null) {
-			throw new BizException("用户信息获取失败,请重新登陆");
-		}
 		Integer topicId = replacementInstrumentActivity.getTopicId();
-
-		List<QuestionnaireUserResult> questionnaireUserResultList = replacementInstrumentActivity.getQuestionnaireUserResultList();
-		if(questionnaireUserResultList == null || questionnaireUserResultList.size() == 0){
-			throw new BizException("请填写问卷结果");
-		}
-		QuestionnaireActiveTypeEnum activeType = replacementInstrumentActivity.getActiveType();
 		QuestionnaireTopic topic = questionnaireTopicDao.get(topicId);
-		if(topic.getAgainCommitFlag() == 0){
-			HashMap<String, Object> paramMap = new HashMap<>(3);
+		if(topic.getStatus() == 0){
+			throw new BizException("当前问卷已停用");
+		}
+		if(topic.getLoginFlag() == 1){
+			SysUser sysUser = sysUserFeignService.queryUserInfo();
+			if (sysUser == null) {
+				throw new BizException("用户信息获取失败,请重新登陆");
+			}
+			if (!sysUser.getTenantId().equals(topic.getTenantId())) {
+				throw new BizException("您不可填写该问卷: 请联系教务老师");
+			}
+			List<QuestionnaireUserResult> questionnaireUserResultList = replacementInstrumentActivity.getQuestionnaireUserResultList();
+			if(questionnaireUserResultList == null || questionnaireUserResultList.size() == 0){
+				throw new BizException("请填写问卷结果");
+			}
+			QuestionnaireActiveTypeEnum activeType = replacementInstrumentActivity.getActiveType();
+			HashMap<String, Object> paramMap = new HashMap<>(4);
 			paramMap.put("activeId",replacementInstrumentActivity.getReplacementInstrumentCooperationId());
-			paramMap.put("activeType",activeType.getCode());
+			paramMap.put("activeType",activeType);
 			paramMap.put("userId",sysUser.getId());
-			List<QuestionnaireUserResult> userResults = questionnaireUserResultDao.findAll(paramMap);
-			if(userResults != null && userResults.size() > 0){
-				throw new BizException("您已提交问卷,请勿重复操作");
+			paramMap.put("topicId",topicId);
+//			List<QuestionnaireUserResult> userResults = questionnaireUserResultDao.findAll(paramMap);
+//			if(userResults != null && userResults.size() > 0){
+//				throw new BizException("您已提交问卷,请勿重复操作");
+//			}
+			//删除原来的问卷结果
+			questionnaireUserResultDao.delByActiveIdAndUserId(paramMap);
+			for (QuestionnaireUserResult result : questionnaireUserResultList) {
+				result.setUserId(sysUser.getId());
+				result.setQuestionnaireTopicId(topicId);
+				result.setActiveType(activeType);
 			}
+			//新增问卷结果
+			questionnaireUserResultDao.batchInsert1(questionnaireUserResultList);
+		}else {
+			this.addResult(replacementInstrumentActivity);
 		}
-		//删除原来的问卷结果
-		questionnaireUserResultDao.delByActiveIdAndUserId(null, sysUser.getId(),activeType.getCode());
-		for (QuestionnaireUserResult result : questionnaireUserResultList) {
-			result.setUserId(sysUser.getId());
-			result.setQuestionnaireTopicId(topicId);
-			result.setActiveType(activeType);
-		}
-		//新增问卷结果
-		questionnaireUserResultDao.batchInsert1(questionnaireUserResultList);
 	}
 
     @Override
@@ -221,9 +208,9 @@ public class QuestionnaireUserResultServiceImpl extends BaseServiceImpl<Long, Qu
 		if(questionnaireUserResultList == null || questionnaireUserResultList.size() == 0){
 			throw new BizException("请填写问卷结果");
 		}
-		Long time = new Date().getTime();
+		int epochSecond = (int)Instant.now().getEpochSecond();
 		for (QuestionnaireUserResult result : questionnaireUserResultList) {
-			result.setUserId(time.intValue());
+			result.setUserId(epochSecond);
 			result.setQuestionnaireTopicId(topicId);
 			result.setActiveType(QuestionnaireActiveTypeEnum.ENTERPRISE_CUSTOMIZATION);
 		}
@@ -232,7 +219,7 @@ public class QuestionnaireUserResultServiceImpl extends BaseServiceImpl<Long, Qu
     }
 
 	@Override
-	public Object queryResultPage(QuestionnaireUserResultQueryInfo queryInfo) {
+	public PageInfo<QuestionnaireUserResultDto> queryResultPage(QuestionnaireUserResultQueryInfo queryInfo) {
 		PageInfo<QuestionnaireUserResultDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
 		Map<String, Object> params = new HashMap<String, Object>();
 		MapUtil.populateMap(params, queryInfo);
@@ -251,89 +238,28 @@ public class QuestionnaireUserResultServiceImpl extends BaseServiceImpl<Long, Qu
 		return pageInfo;
 	}
 
-    @Override
-    public List<String> getExportFields(Integer cooperationId,QuestionnaireActiveTypeEnum activeType,List<QuestionnaireQuestion> questionList) {
-		List<String> column = new ArrayList<>();
-		if(questionList != null && questionList.size() > 0) {
-			column.add("活动编号");
-			column.add("分部");
-			column.add("提交时间");
-			column.add("学员编号");
-			column.add("学员姓名");
-			column.add("手机号");
-			List<String> collect = questionList.stream().map(e -> e.getContent()).collect(Collectors.toList());
-			column.addAll(collect);
-		}
-		return column;
-    }
-
 	@Override
-	public Set<String> getExportBody(Integer cooperationId, QuestionnaireActiveTypeEnum activeType,List<QuestionnaireQuestion> questionList) {
-		if(questionList != null && questionList.size() > 0) {
-			Map<String,Object> resultMap = this.questionnaireUserResultExport(activeType.getCode(),cooperationId,questionList);
-			return (Set<String>)resultMap.get("body");
-		}else {
-			throw new BizException("暂无可导出数据");
-		}
+	public QuestionnaireUserResultDto queryUserResult(Integer topicId) {
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		return questionnaireUserResultDao.queryUserResult(topicId,sysUser.getId());
 	}
 
 	@Override
-	public List<QuestionnaireQuestion> getQuestionnaireQuestions(Integer cooperationId, QuestionnaireActiveTypeEnum activeType){
-		List<QuestionnaireQuestion> questionList;
-		if(cooperationId != null){
-			questionList = questionnaireQuestionDao.queryQuestionList(cooperationId);
-		}else {
-			if(activeType != CLOUD_TEACHER_FEEDBACK){
-				throw new BizException("报表中心暂不支持 {} 导出",CLOUD_TEACHER_FEEDBACK.getDesc());
+	public String[] getExportHeader(QuestionnaireTopic topic,List<QuestionnaireQuestion> questionList) {
+		if(questionList != null && questionList.size() > 0) {
+			List<String> column = new ArrayList<>();
+			if (topic.getLoginFlag() == 1) {
+				column.add("分部");
+				column.add("学员编号");
+				column.add("学员姓名");
+				column.add("手机号");
 			}
-			questionList = questionnaireQuestionDao.findByActiveType(activeType.getCode(), TenantContextHolder.getTenantId());
-		}
-		questionList.removeAll(Collections.singleton(null));
-		return questionList;
-	}
+			column.add("提交时间");
 
-	@Override
-	public void questionnaireUserResultExport(HttpServletResponse response, ExportDto exportDto) throws Exception {
-		Map<String, Object> info = exportDto.getQueryInfo();
-		Integer cooperationId = exportService.getParam(info, "cooperationId", Integer.class);
-		QuestionnaireActiveTypeEnum activeType = QuestionnaireActiveTypeEnum.valueOf(exportService.getParam(info, "activeType", String.class));
-		List<QuestionnaireQuestion> questionList = getQuestionnaireQuestions(cooperationId,activeType);
-		List<String> exportFields = getExportFields(cooperationId, activeType,questionList);
-		List<String> exportBody = new ArrayList<>(getExportBody(cooperationId, activeType,questionList));
-		if(exportBody.size() == 0){
-			throw new BizException("暂无可导出数据");
-		}
-		Map<String,String> headMap = new LinkedHashMap<>(exportDto.getHeadColumns().size());
-		for (int i = 0; i < exportFields.size(); i++) {
-			headMap.put(exportFields.get(i),exportBody.get(i));
-		}
-		headMap.keySet().removeAll(org.apache.commons.collections.CollectionUtils.subtract(exportFields, exportDto.getHeadColumns()));
-		String[] header = headMap.keySet().toArray(new String[headMap.keySet().size()]);
-		String[] body = headMap.values().toArray(new String[headMap.keySet().size()]);
-		Map<String,Object> resultMap = this.questionnaireUserResultExport(activeType.getCode(),cooperationId,questionList);
-		List<Map<String,Object>> jsonObjectList = (List<Map<String,Object>>)resultMap.get("jsonObjectList");
-		OutputStream outputStream = response.getOutputStream();
-		HSSFWorkbook workbook = null;
-		try {
-			workbook = POIUtil.exportExcel(header, body, jsonObjectList);
-			response.setContentType("application/octet-stream");
-			response.setHeader("Content-Disposition", "attachment;filename=replacement-" + DateUtil.getDate(new Date()) + ".xls");
-			response.flushBuffer();
-			outputStream = response.getOutputStream();
-			workbook.write(outputStream);
-			outputStream.flush();
-			workbook.close();
-		} catch (Exception e) {
-			e.printStackTrace();
-		} finally {
-			if (outputStream != null) {
-				try {
-					workbook.close();
-					outputStream.close();
-				} catch (IOException e) {
-					e.printStackTrace();
-				}
-			}
+			List<String> collect = questionList.stream().map(e -> e.getContent()).collect(Collectors.toList());
+			column.addAll(collect);
+			return column.toArray(new String[column.size()]);
 		}
+		return new String[0];
 	}
 }

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

@@ -235,8 +235,13 @@ public class ReplacementInstrumentActivityServiceImpl extends BaseServiceImpl<In
             replacementInstrumentActivityDao.update(replacementInstrumentActivity);
 
             if (questionnaireUserResultList != null && questionnaireUserResultList.size() > 0) {
+                HashMap<String, Object> paramMap = new HashMap<>(4);
+                paramMap.put("activeId",activity.getReplacementInstrumentCooperationId());
+                paramMap.put("activeType",QuestionnaireActiveTypeEnum.REPLACEMENT);
+                paramMap.put("userId",sysUser.getId());
+                paramMap.put("topicId",topicId);
                 //删除原来的问卷结果
-                questionnaireUserResultDao.delByActiveIdAndUserId(activity.getReplacementInstrumentCooperationId(), sysUser.getId(),"REPLACEMENT");
+                questionnaireUserResultDao.delByActiveIdAndUserId(paramMap);
             }
             if (replacementInstrumentActivity.getInstrumentsId() != null && (activity.getInstrumentsId() == null || activity.getInstrumentsId() == 0)) {
                 sendPush = true;

+ 0 - 4
mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentAttendanceServiceImpl.java

@@ -90,14 +90,10 @@ public class StudentAttendanceServiceImpl extends BaseServiceImpl<Long, StudentA
     @Autowired
     private SysMessageService sysMessageService;
     @Autowired
-    private SysConfigDao sysConfigDao;
-    @Autowired
     private SysTenantConfigService sysTenantConfigService;
     @Autowired
     private SchoolDao schoolDao;
     @Autowired
-    private SysConfigService sysConfigService;
-    @Autowired
     private TeacherAttendanceDao teacherAttendanceDao;
     @Autowired
     private StudentDao studentDao;

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

@@ -8,6 +8,7 @@ import com.ym.mec.biz.dal.dto.TenantPreJoinDto;
 import com.ym.mec.biz.dal.entity.SysArea;
 import com.ym.mec.biz.dal.entity.SysUserTsign;
 import com.ym.mec.biz.dal.entity.TenantPreJoin;
+import com.ym.mec.biz.dal.vo.TenantPreJoinVo;
 import com.ym.mec.biz.service.SysUserTsignService;
 import com.ym.mec.biz.service.TenantPreJoinService;
 import com.ym.mec.common.exception.BizException;
@@ -50,23 +51,10 @@ public class TenantPreJoinServiceImpl extends ServiceImpl<TenantPreJoinDao, Tena
      * @param param 条件
      */
     @Override
-    public PageInfo<TenantPreJoin> queryPage(Map<String, Object> param) {
-        Page<TenantPreJoin> pageInfo = PageUtil.getPageInfo(param);
-        //模糊搜索的字段
-        Object search = param.get("search");
-        //分页查询
-        IPage<TenantPreJoin> page = this.page(pageInfo,
-                new WrapperUtil<TenantPreJoin>()
-                        .hasEq("state_", param.get("state"))
-                        .hasGe("created_time_", param.get("startTime"))
-                        .hasLe("created_time_", param.get("endTime"))
-                        .queryWrapper()
-                        .and(Objects.nonNull(search),
-                                o -> o.eq("tsign_name_", search)
-                                        .or().eq("enterprise_liable_name_", search)
-                                        .or().eq("contacts_", search)
-                        ));
-        return PageUtil.pageInfo(page);
+    public PageInfo<TenantPreJoinVo> queryPage(Map<String, Object> param) {
+        Page<TenantPreJoinVo> pageInfo = PageUtil.getPageInfo(param);
+        pageInfo.setDesc("a.created_time_");
+        return PageUtil.pageInfo(baseMapper.queryPage(pageInfo, param));
     }
 
     @Override

+ 50 - 15
mec-biz/src/main/resources/config/mybatis/CloudCoachPaymentProgramMapper.xml

@@ -22,6 +22,12 @@
 		<result column="create_time_" property="createTime" />
 		<result column="update_time_" property="updateTime" />
 		<result column="tenant_id_" property="tenantId" />
+		<result column="audit_" property="audit" />
+		<result column="audit_name_" property="auditName" />
+		<result column="audit_time_" property="auditTime" />
+		<result column="organ_id_" property="organId" />
+		<result column="organ_name_" property="organName" />
+		<result column="status_" property="status" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
 	</resultMap>
 	
 	<!-- 根据主键查询一条记录 -->
@@ -38,49 +44,65 @@
 	<insert id="insert" parameterType="com.ym.mec.biz.dal.entity.CloudCoachPaymentProgram" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
 		INSERT INTO cloud_coach_payment_program (name_,remark_,member_num_,user_num_,
 		payment_user_num_,period_,member_rank_setting_id_,actual_amount_,original_amount_,
-		operator_,create_time_,update_time_,tenant_id_)
+		operator_,create_time_,update_time_,tenant_id_,memo_,status_,organ_id_)
 		VALUES(#{name},#{remark},#{memberNum},#{userNum},#{paymentUserNum},#{period,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
-		#{memberRankSettingId},#{actualAmount},#{originalAmount},#{operator},NOW(),NOW(),#{tenantId})
+		#{memberRankSettingId},#{actualAmount},#{originalAmount},#{operator},
+		NOW(),NOW(),#{tenantId},#{memo},#{status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{organId})
 	</insert>
 	
 	<!-- 根据主键查询一条记录 -->
 	<update id="update" parameterType="com.ym.mec.biz.dal.entity.CloudCoachPaymentProgram">
 		UPDATE cloud_coach_payment_program <set>
+		<if test="status != null">
+			status_ = #{status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+		</if>
+		<if test="memo != null">
+			memo_ = #{memo},
+		</if>
+		<if test="organId != null">
+			organ_id_ = #{organId},
+		</if>
+		<if test="audit != null">
+			audit_ = #{audit},
+		</if>
+		<if test="auditTime != null">
+			audit_time_ = #{auditTime},
+		</if>
 		<if test="operator != null">
-		operator_ = #{operator},
+			operator_ = #{operator},
 		</if>
 		<if test="memberNum != null">
-		member_num_ = #{memberNum},
+			member_num_ = #{memberNum},
 		</if>
 		<if test="tenantId != null">
-		tenant_id_ = #{tenantId},
+			tenant_id_ = #{tenantId},
 		</if>
 		<if test="paymentUserNum != null">
-		payment_user_num_ = #{paymentUserNum},
+			payment_user_num_ = #{paymentUserNum},
 		</if>
 		<if test="originalAmount != null">
-		original_amount_ = #{originalAmount},
+			original_amount_ = #{originalAmount},
 		</if>
 		<if test="name != null">
-		name_ = #{name},
+			name_ = #{name},
 		</if>
 		<if test="remark != null">
-		remark_ = #{remark},
+			remark_ = #{remark},
 		</if>
 		<if test="period != null">
-		period_ = #{period,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+			period_ = #{period,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
 		</if>
 		<if test="userNum != null">
-		user_num_ = #{userNum},
+			user_num_ = #{userNum},
 		</if>
 		<if test="updateTime != null">
-		update_time_ = #{updateTime},
+			update_time_ = #{updateTime},
 		</if>
 		<if test="memberRankSettingId != null">
-		member_rank_setting_id_ = #{memberRankSettingId},
+			member_rank_setting_id_ = #{memberRankSettingId},
 		</if>
 		<if test="actualAmount != null">
-		actual_amount_ = #{actualAmount},
+			actual_amount_ = #{actualAmount},
 		</if>
 		</set> WHERE id_ = #{id}
 	</update>
@@ -92,12 +114,18 @@
 
 	<sql id="queryPageSql">
 		<where>
+			<if test="organId != null and organId != ''">
+				AND FIND_IN_SET(ccpp.organ_id_,#{organId})
+			</if>
 			<if test="tenantId != null">
 				AND ccpp.tenant_id_ = #{tenantId}
 			</if>
 			<if test="period != null and period != ''">
 				AND ccpp.period_ = #{period}
 			</if>
+			<if test="status != null and status != ''">
+				AND ccpp.status_ = #{status}
+			</if>
 			<if test="startTime != null and startTime != ''">
 				AND DATE_FORMAT(ccpp.create_time_,"%Y-%m-%d") >= #{startTime}
 			</if>
@@ -109,8 +137,11 @@
 	
 	<!-- 分页查询 -->
 	<select id="queryPage" resultMap="CloudCoachPaymentProgram" parameterType="map">
-		SELECT ccpp.*,su.real_name_ operator_name_ FROM cloud_coach_payment_program ccpp
+		SELECT ccpp.*,su.real_name_ operator_name_,su1.real_name_ audit_name_,o.name_ organ_name_
+		FROM cloud_coach_payment_program ccpp
+		LEFT JOIN organization o ON o.id_ = ccpp.organ_id_
 		LEFT JOIN sys_user su ON su.id_ = ccpp.operator_
+		LEFT JOIN sys_user su1 ON su1.id_ = ccpp.audit_
 		<include refid="queryPageSql"/>
 		ORDER BY ccpp.id_ DESC
 		<include refid="global.limit"/>
@@ -119,6 +150,10 @@
 	<!-- 查询当前表的总记录数 -->
 	<select id="queryCount" resultType="int">
 		SELECT COUNT(DISTINCT ccpp.id_) FROM cloud_coach_payment_program ccpp
+		LEFT JOIN organization o ON o.id_ = ccpp.organ_id_
 		<include refid="queryPageSql"/>
 	</select>
+	<select id="getLock" resultMap="CloudCoachPaymentProgram">
+		SELECT * FROM cloud_coach_payment_program WHERE id_ = #{id} FOR UPDATE
+	</select>
 </mapper>

+ 45 - 0
mec-biz/src/main/resources/config/mybatis/ImLiveBroadcastRoomDataMapper.xml

@@ -0,0 +1,45 @@
+<?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.dao.ImLiveBroadcastRoomDataDao">
+    <resultMap id="BaseResultMap" type="com.ym.mec.biz.dal.entity.ImLiveBroadcastRoomData">
+        <id column="id_" jdbcType="INTEGER" property="id"/>
+        <result column="tenant_id_" jdbcType="INTEGER" property="tenantId"/>
+        <result column="room_uid_" jdbcType="VARCHAR" property="roomUid"/>
+        <result column="like_num_" jdbcType="INTEGER" property="likeNum"/>
+        <result column="look_user_num_" jdbcType="INTEGER" property="lookUserNum"/>
+        <result column="total_user_num_" jdbcType="INTEGER" property="totalUserNum"/>
+        <result column="updated_time_" jdbcType="TIMESTAMP" property="updatedTime"/>
+        <result column="live_time_" jdbcType="INTEGER" property="liveTime"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id_
+        , tenant_id_, room_uid_, like_num_, look_user_num_, total_user_num_, updated_time_, live_time_
+    </sql>
+
+    <insert id="insertBatch" keyColumn="id_" keyProperty="id" useGeneratedKeys="true"
+            parameterType="com.ym.mec.biz.dal.entity.ImLiveBroadcastRoomData">
+        insert into im_live_broadcast_room_data(tenant_id_, room_uid_, like_num_, look_user_num_, total_user_num_,
+        updated_time_, live_time_)
+        values
+        <foreach collection="entities" item="entity" separator=",">
+            (#{entity.tenantId}, #{entity.roomUid}, #{entity.likeNum}, #{entity.lookUserNum}, #{entity.totalUserNum},
+            #{entity.updatedTime}, #{entity.liveTime})
+        </foreach>
+    </insert>
+
+    <select id="queryByRoomUid" resultType="com.ym.mec.biz.dal.vo.ImLiveBroadcastRoomDetailVo">
+        select a.room_uid_                 as roomUid,
+               r.room_title_               as roomTitle,
+               b.real_name_                AS speakerName,
+               r.live_remark_              AS liveRemark,
+               ifnull(a.total_user_num_, 0) AS totalLookNum,
+               ifnull(a.like_num_, 0)      as totalLikeNum,
+               ifnull(a.live_time_, 0)     as totalLiveTime
+        from im_live_broadcast_room_data as a
+                 left join im_live_broadcast_room AS r on a.room_uid_ = r.room_uid_
+                 left join sys_user AS b on r.speaker_id_ = b.id_
+        where a.room_uid_ = #{roomUid}
+    </select>
+
+</mapper>

+ 92 - 0
mec-biz/src/main/resources/config/mybatis/ImLiveBroadcastRoomMapper.xml

@@ -0,0 +1,92 @@
+<?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.dao.ImLiveBroadcastRoomDao">
+    <resultMap id="BaseResultMap" type="com.ym.mec.biz.dal.entity.ImLiveBroadcastRoom">
+        <id column="id_" jdbcType="INTEGER" property="id"/>
+        <result column="tenant_id_" jdbcType="INTEGER" property="tenantId"/>
+        <result column="speaker_id_" jdbcType="INTEGER" property="speakerId"/>
+        <result column="room_uid_" jdbcType="VARCHAR" property="roomUid"/>
+        <result column="room_title_" jdbcType="VARCHAR" property="roomTitle"/>
+        <result column="live_start_time_" jdbcType="TIMESTAMP" property="liveStartTime"/>
+        <result column="live_end_time_" jdbcType="TIMESTAMP" property="liveEndTime"/>
+        <result column="live_remark_" jdbcType="VARCHAR" property="liveRemark"/>
+        <result column="pre_template_" jdbcType="VARCHAR" property="preTemplate"/>
+        <result column="room_config_" jdbcType="VARCHAR" property="roomConfig"/>
+        <result column="live_state_" jdbcType="INTEGER" property="liveState"/>
+        <result column="room_state_" jdbcType="INTEGER" property="roomState"/>
+        <result column="created_by_" jdbcType="INTEGER" property="createdBy"/>
+        <result column="created_time_" jdbcType="TIMESTAMP" property="createdTime"/>
+        <result column="updated_by_" jdbcType="INTEGER" property="updatedBy"/>
+        <result column="updated_time_" jdbcType="TIMESTAMP" property="updatedTime"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id_
+        , tenant_id_, speaker_id_, room_uid_, room_title_, live_start_time_, live_end_time_, live_remark_, pre_template_, room_config_, live_state_, room_state_, created_by_, created_time_, updated_by_, updated_time_
+    </sql>
+
+    <insert id="insertBatch" keyColumn="id_" keyProperty="id" useGeneratedKeys="true"
+            parameterType="com.ym.mec.biz.dal.entity.ImLiveBroadcastRoom">
+        insert into im_live_broadcast_room(tenant_id_, speaker_id_, room_uid_, room_title_, live_start_time_,
+        live_end_time_, live_remark_, pre_template_, room_config_, live_state_, room_state_, created_by_, created_time_,
+        updated_by_, updated_time_)
+        values
+        <foreach collection="entities" item="entity" separator=",">
+            (#{entity.tenantId}, #{entity.speakerId}, #{entity.roomUid}, #{entity.roomTitle}, #{entity.liveStartTime},
+            #{entity.liveEndTime}, #{entity.liveRemark}, #{entity.preTemplate}, #{entity.roomConfig},
+            #{entity.liveState}, #{entity.roomState}, #{entity.createdBy}, #{entity.createdTime}, #{entity.updatedBy},
+            #{entity.updatedTime})
+        </foreach>
+    </insert>
+
+    <select id="queryPage" resultType="com.ym.mec.biz.dal.vo.ImLiveBroadcastRoomVo">
+        select a.id_ AS id,
+        a.tenant_id_ AS tenantId,
+        t.name_ AS tenantName,
+        t.logo_ AS tenantLogo,
+        a.room_uid_ AS roomUid,
+        a.room_title_ AS roomTitle,
+        a.live_remark_ AS liveRemark,
+        a.speaker_id_ AS speakerId,
+        b.real_name_ AS speakerName,
+        b.im_token_ as imToken,
+        b.avatar_ AS speakerPic,
+        a.live_start_time_ AS liveStartTime,
+        a.live_state_ AS liveState,
+        a.room_state_ AS roomState,
+        c.real_name_ AS createdByName,
+        a.pre_template_ AS preTemplate,
+        a.room_config_ AS roomConfig
+        from im_live_broadcast_room as a
+        left join tenant_info AS t on a.tenant_id_ = t.id_
+        left join sys_user AS b on a.speaker_id_ = b.id_
+        left join sys_user AS c on a.created_by_ = c.id_
+        <where>
+            a.room_state_ in(0, 2)
+            <if test="param.search != null ">
+                AND (
+                a.`id_` LIKE CONCAT('%', #{param.search},'%')
+                OR a.`room_title_` LIKE CONCAT('%', #{param.search},'%')
+                )
+            </if>
+            <if test="param.tenantId != null ">
+                AND a.tenant_id_ = #{param.tenantId}
+            </if>
+            <if test="param.roomUid != null">
+                and a.room_uid_ = #{param.roomUid}
+            </if>
+            <if test="param.liveState != null">
+                and a.live_state_ = #{param.liveState}
+            </if>
+            <if test="param.startTime != null">
+                <![CDATA[ AND a.live_start_time_  >= #{param.startTime} ]]>
+            </if>
+            <if test="param.endTime != null">
+                <![CDATA[ AND a.live_start_time_  <= #{param.endTime} ]]>
+            </if>
+
+        </where>
+
+    </select>
+
+</mapper>

+ 50 - 0
mec-biz/src/main/resources/config/mybatis/ImLiveBroadcastRoomMemberMapper.xml

@@ -0,0 +1,50 @@
+<?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.dao.ImLiveBroadcastRoomMemberDao">
+    <resultMap id="BaseResultMap" type="com.ym.mec.biz.dal.entity.ImLiveBroadcastRoomMember">
+        <id column="id_" jdbcType="INTEGER" property="id"/>
+        <result column="tenant_id_" jdbcType="INTEGER" property="tenantId"/>
+        <result column="room_uid_" jdbcType="VARCHAR" property="roomUid"/>
+        <result column="user_id_" jdbcType="INTEGER" property="userId"/>
+        <result column="join_time_" jdbcType="TIMESTAMP" property="joinTime"/>
+        <result column="total_time_" jdbcType="INTEGER" property="totalTime"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id
+        , tenant_id_, room_uid_, user_id_, join_time_, total_time_
+    </sql>
+
+    <insert id="insertBatch" keyColumn="id_" keyProperty="id" useGeneratedKeys="true"
+            parameterType="com.ym.mec.biz.dal.entity.ImLiveBroadcastRoomMember">
+        insert into im_live_broadcast_room_member(tenant_id_, room_uid_, user_id_, join_time_, total_time_)
+        values
+        <foreach collection="entities" item="entity" separator=",">
+            (#{entity.tenantId}, #{entity.roomUid}, #{entity.userId}, #{entity.joinTime}, #{entity.totalTime})
+        </foreach>
+    </insert>
+
+    <select id="queryMemberPage" resultType="com.ym.mec.biz.dal.vo.ImLiveBroadcastRoomMemberVo">
+        select i.room_uid_ as roomUid,
+        i.room_title_ as roomTitle,
+        a.user_id_ as studentId,
+        su.username_ as studentName,
+        su.phone_ as phone,
+        b.name_ as subName,
+        a.join_time_ as joinTime,
+        a.total_time_ as totalViewTime
+        from im_live_broadcast_room_member as a
+        left join im_live_broadcast_room as i on a.room_uid_ = i.room_uid_
+        left join sys_user as su on su.id_ = a.user_id_
+        left join student st on su.id_ = st.user_id_
+        left join subject as b on st.subject_id_list_ = b.id_
+        where a.room_uid_ = #{param.roomUid}
+        <if test="param.search != null ">
+            AND (
+            a.user_id_ LIKE CONCAT('%', #{param.search},'%')
+            OR su.username_ LIKE CONCAT('%', #{param.search},'%')
+            )
+        </if>
+    </select>
+
+</mapper>

+ 31 - 0
mec-biz/src/main/resources/config/mybatis/ImLiveRoomVideoMapper.xml

@@ -0,0 +1,31 @@
+<?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.dao.ImLiveRoomVideoDao">
+    <resultMap id="BaseResultMap" type="com.ym.mec.biz.dal.entity.ImLiveRoomVideo">
+        <id column="id_" jdbcType="INTEGER" property="id"/>
+        <result column="room_uid_" jdbcType="VARCHAR" property="roomUid"/>
+        <result column="record_id_" jdbcType="VARCHAR" property="recordId"/>
+        <result column="url_" jdbcType="VARCHAR" property="url"/>
+        <result column="start_time_" jdbcType="TIMESTAMP" property="startTime"/>
+        <result column="end_time_" jdbcType="TIMESTAMP" property="endTime"/>
+        <result column="type" jdbcType="INTEGER" property="type"/>
+        <result column="created_time_" jdbcType="TIMESTAMP" property="createdTime"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id_
+        , room_uid_, record_id_, url_, start_time_, end_time_, type, created_time_
+    </sql>
+
+    <insert id="insertBatch" keyColumn="id_" keyProperty="id" useGeneratedKeys="true"
+            parameterType="com.ym.mec.biz.dal.entity.ImLiveRoomVideo">
+        insert into im_live_room_video(room_uid_, record_id_, url_, start_time_, end_time_, type,
+        created_time_)
+        values
+        <foreach collection="entities" item="entity" separator=",">
+            (#{entity.roomUid}, #{entity.recordId}, #{entity.url}, #{entity.startTime},
+            #{entity.endTime}, #{entity.type}, #{entity.createdTime})
+        </foreach>
+    </insert>
+
+</mapper>

+ 64 - 0
mec-biz/src/main/resources/config/mybatis/MusicGroupMapper.xml

@@ -997,4 +997,68 @@
         </foreach>
         GROUP BY sr.user_id_
     </select>
+    <select id="queryHasSubCourseTimes" resultType="java.lang.String">
+        SELECT DISTINCT mgpc.music_group_id_ FROM music_group_payment_student_course_detail mgpscd
+        LEFT JOIN music_group_payment_calender mgpc ON mgpscd.music_group_payment_calender_id_ = mgpc.id_
+        LEFT JOIN music_group mg ON mg.id_ = mgpc.music_group_id_
+        WHERE mgpc.status_ = 'OVER' AND DATEDIFF(NOW(),mgpc.deadline_payment_date_) > 90 AND mg.status_ = 'PROGRESS'
+        AND mgpscd.used_course_minutes_ = 0
+        <if test="tenantId != null">
+            AND mgpc.tenant_id_ = #{tenantId}
+        </if>
+        <if test="organIds != null and organIds != ''">
+            AND FIND_IN_SET(mgpc.organ_id_,#{organIds})
+        </if>
+    </select>
+    <select id="countHasFreeCourseTimes" resultType="java.lang.Integer">
+        SELECT COUNT(mgpscd.user_id_)
+        FROM music_group_payment_student_course_detail mgpscd
+        LEFT JOIN music_group_payment_calender mgpc ON mgpc.id_ = mgpscd.music_group_payment_calender_id_
+        LEFT JOIN music_group mg ON mg.id_ = mgpc.music_group_id_
+        LEFT JOIN sys_user su ON su.id_ = mgpscd.user_id_
+        <include refid="queryHasFreeCourseTimesSql"/>
+    </select>
+    <resultMap id="HasFreeCourseTimesDto" type="com.ym.mec.biz.dal.dto.HasFreeCourseTimesDto">
+        <result property="userId" column="user_id_"/>
+        <result property="courseType" column="course_type_" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
+        <result property="musicGroupName" column="music_group_name_"/>
+        <result property="musicGroupId" column="music_group_id_"/>
+        <result property="username" column="username_"/>
+        <result property="freeCourseMinutes" column="free_course_minutes_"/>
+        <result property="totalCourseMinutes" column="total_course_minutes_"/>
+        <result property="usedCourseMinutes" column="used_course_minutes_"/>
+        <result property="organName" column="organ_name_"/>
+        <result property="organId" column="organ_id_"/>
+    </resultMap>
+    <sql id="queryHasFreeCourseTimesSql">
+        <where>
+            mgpscd.used_course_minutes_ &lt; mgpscd.total_course_minutes_ AND mgpscd.used_course_minutes_ > 0
+            AND mg.status_ = 'PROGRESS'
+            <if test="tenantId != null">
+                AND mgpscd.tenant_id_ = #{tenantId}
+            </if>
+            <if test="organId != null and organId != ''">
+                AND FIND_IN_SET(mg.organ_id_,#{organId})
+            </if>
+            <if test="search != null and search != ''">
+                AND (mgpscd.user_id_ = #{search}
+                OR su.username_ LIKE CONCAT('%' ,#{search}, '%' )
+                OR mg.id_ LIKE CONCAT('%' ,#{search}, '%' )
+                OR mg.name_ LIKE CONCAT('%' ,#{search}, '%' ))
+            </if>
+        </where>
+    </sql>
+    <select id="queryHasFreeCourseTimes" resultMap="HasFreeCourseTimesDto">
+        SELECT mg.id_ music_group_id_,mg.name_ music_group_name_,mgpscd.user_id_,mgpscd.total_course_minutes_,
+        mgpscd.used_course_minutes_,mgpscd.total_course_minutes_ - mgpscd.used_course_minutes_ free_course_minutes_,su.username_,
+        mgpscd.course_type_,o.name_ organ_name_,su.organ_id_
+        FROM music_group_payment_student_course_detail mgpscd
+        LEFT JOIN music_group_payment_calender mgpc ON mgpc.id_ = mgpscd.music_group_payment_calender_id_
+        LEFT JOIN music_group mg ON mg.id_ = mgpc.music_group_id_
+        LEFT JOIN sys_user su ON su.id_ = mgpscd.user_id_
+        LEFT JOIN organization o ON o.id_ = su.organ_id_
+        <include refid="queryHasFreeCourseTimesSql"/>
+        ORDER BY mgpscd.update_time_ DESC
+        <include refid="global.limit"/>
+    </select>
 </mapper>

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

@@ -554,7 +554,7 @@
 		CASE WHEN mgpcd.start_payment_date_ IS NULL THEN mgpc.start_payment_date_ ELSE mgpcd.start_payment_date_ END start_payment_date_mgpc_,
 		CASE WHEN mgpcd.deadline_payment_date_ IS NULL THEN mgpc.deadline_payment_date_ ELSE mgpcd.deadline_payment_date_ END deadline_payment_date_mgpc_,
 		CASE WHEN mgpc.status_ = 'OPEN' OR mgpcd.open_ = 1 THEN 1 ELSE 0 END open_,mgpc.payment_type_,mgpcd.payment_order_id_,mgpcd.payment_status_,mgpcd.pay_time_,
-		mgpcd.music_group_payment_calender_id_
+		mgpcd.music_group_payment_calender_id_,mgpc.current_total_amount_ expect_amount_
 		FROM music_group_payment_calender_detail mgpcd
 		LEFT JOIN sys_user su ON su.id_ = mgpcd.user_id_
 		LEFT JOIN student_registration sr ON sr.user_id_ = mgpcd.user_id_

+ 14 - 0
mec-biz/src/main/resources/config/mybatis/MusicGroupPaymentStudentCourseDetailMapper.xml

@@ -271,4 +271,18 @@
             AND user_id_ = #{userId}
         </if>
     </select>
+    <select id="checkCourseTimes" resultType="integer">
+        SELECT SUM(c.a) >= SUM(c.b) FROM (
+        SELECT COUNT(DISTINCT mgpscd.course_type_) a,COUNT(DISTINCT mgpscd.total_course_minutes_) b FROM music_group_payment_student_course_detail mgpscd
+        LEFT JOIN music_group_payment_calender mgpc ON mgpscd.music_group_payment_calender_id_ = mgpc.id_
+        WHERE mgpc.music_group_id_ = #{musicGroupId} AND mgpscd.used_course_minutes_ = 0
+        AND mgpscd.course_type_ IN
+        <foreach collection="courseTypes" item="courseType" open="(" close=")" separator=",">
+            #{courseType}
+        </foreach>
+        AND mgpscd.user_id_ IN
+        <foreach collection="studentIds" item="studentId" open="(" close=")" separator=",">
+            #{studentId}
+        </foreach>)c
+    </select>
 </mapper>

+ 0 - 2
mec-biz/src/main/resources/config/mybatis/OrganizationCourseUnitPriceSettingsMapper.xml

@@ -28,8 +28,6 @@
 
 	<!-- 向数据库增加一条记录 -->
 	<insert id="insert" parameterType="com.ym.mec.biz.dal.entity.OrganizationCourseUnitPriceSettings" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
-		<!-- <selectKey resultClass="int" keyProperty="id" > SELECT SEQ_WSDEFINITION_ID.nextval 
-			AS ID FROM DUAL </selectKey> -->
 		INSERT INTO organization_course_unit_price_settings
 		(id_,organ_id_,course_type_,charge_type_id_,unit_price_,create_time_,update_time_,tenant_id_)
 		VALUES(#{id},#{organId},#{courseType, typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{chargeTypeId},#{unitPrice},now(),now(),#{tenantId})

+ 22 - 3
mec-biz/src/main/resources/config/mybatis/QuestionnaireTopicMapper.xml

@@ -16,6 +16,9 @@
 		<result column="create_time_" property="createTime" />
 		<result column="update_time_" property="updateTime" />
         <result column="tenant_id_" property="tenantId"/>
+        <result column="login_flag_" property="loginFlag"/>
+        <result column="commit_type_" property="commitType"/>
+        <result column="template_type_" property="templateType"/>
 	</resultMap>
 	
 	<!-- 根据主键查询一条记录 -->
@@ -30,13 +33,23 @@
 	
 	<!-- 向数据库增加一条记录 -->
 	<insert id="insert" parameterType="com.ym.mec.biz.dal.entity.QuestionnaireTopic" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
-		INSERT INTO questionnaire_topic (title_,status_,creator_id_,create_time_,update_time_,again_commit_flag_,tenant_id_)
-		VALUES(#{title},#{status},#{creatorId},NOW(),NOW(),#{againCommitFlag},#{tenantId})
+		INSERT INTO questionnaire_topic (title_,status_,creator_id_,create_time_,
+		update_time_,again_commit_flag_,tenant_id_,login_flag_,commit_type_,template_type_)
+		VALUES(#{title},#{status},#{creatorId},NOW(),NOW(),#{againCommitFlag},#{tenantId},#{loginFlag},#{commitType},#{templateType})
 	</insert>
 	
 	<!-- 根据主键查询一条记录 -->
 	<update id="update" parameterType="com.ym.mec.biz.dal.entity.QuestionnaireTopic">
 		UPDATE questionnaire_topic <set>
+		<if test="templateType != null">
+			template_type_ = #{templateType},
+		</if>
+		<if test="loginFlag != null">
+			login_flag_ = #{loginFlag},
+		</if>
+		<if test="commitType != null">
+			commit_type_ = #{commitType},
+		</if>
 		<if test="tenantId != null">
 			tenant_id_ = #{tenantId},
 		</if>
@@ -69,13 +82,19 @@
 			<if test="status != null">
 				AND status_ = #{status}
 			</if>
+			<if test="loginFlag != null">
+				AND login_flag_ = #{loginFlag}
+			</if>
+			<if test="commitType != null">
+				AND commit_type_ = #{commitType}
+			</if>
 		</where>
 	</sql>
 	<!-- 分页查询 -->
 	<select id="queryPage" resultMap="QuestionnaireTopic" parameterType="map">
 		SELECT * FROM questionnaire_topic
 		<include refid="queryPageSql"/>
-		ORDER BY id_
+		ORDER BY id_ DESC
 		<include refid="global.limit"/>
 	</select>
 	

+ 39 - 14
mec-biz/src/main/resources/config/mybatis/QuestionnaireUserResultMapper.xml

@@ -32,15 +32,17 @@
 		SELECT qur.* FROM questionnaire_user_result qur
 		LEFT JOIN sys_user su ON su.id_ = qur.user_id_
 		<where>
-            qur.tenant_id_ = #{tenantId}
+			<if test="topicId != null">
+				AND qur.questionnaire_topic_id_ = #{topicId}
+			</if>
 			<if test="userId != null">
 				AND qur.user_id_ = #{userId}
 			</if>
 			<if test="activeId != null">
 				AND qur.active_id_ = #{activeId}
 			</if>
-			<if test="activeType != null and activeType != ''">
-				AND qur.active_type_ = #{activeType}
+			<if test="activeType != null">
+				AND qur.active_type_ = #{activeType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
 			</if>
 		</where>
 		ORDER BY su.organ_id_,qur.create_time_ DESC,qur.user_id_,qur.id_
@@ -98,25 +100,33 @@
 	</delete>
     <delete id="delByActiveIdAndUserId">
 		DELETE FROM questionnaire_user_result
-		WHERE active_type_ = #{activeType}
-		<if test="userId != null">
-		  AND user_id_ = #{userId}
-		</if>
-		<if test="activityId != null">
-		  AND active_id_ = #{activityId}
-		</if>
+		<where>
+			<if test="activeType != null">
+				AND active_type_ = #{userId,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
+			</if>
+			<if test="userId != null">
+				AND user_id_ = #{userId}
+			</if>
+			<if test="activityId != null">
+				AND active_id_ = #{activityId}
+			</if>
+			<if test="topicId != null">
+				AND questionnaire_topic_id_ = #{topicId}
+			</if>
+		</where>
 	</delete>
 
     <!-- 分页查询 -->
 	<select id="findResultCount" resultMap="QuestionnaireUserResultDto" parameterType="map">
-		SELECT qu1.*,qq.content_,GROUP_CONCAT(qqi.answer_value_ ORDER BY qqi.sort_) answer_value_,qq.type_
-		FROM (SELECT qu.user_id_ id_ FROM questionnaire_user_result qu
+		SELECT qu1.*,qq.content_,GROUP_CONCAT(qqi.answer_value_ ORDER BY qqi.sort_) answer_value_,qq.type_,qur.username_,qur.phone_
+		FROM (SELECT qu.user_id_,su.username_,su.phone_ FROM questionnaire_user_result qu
+		LEFT JOIN sys_user su ON su.id_ = qu.user_id_
 		WHERE qu.questionnaire_topic_id_ = #{topicId}
 		<if test="search != null and search != ''">
 			AND (qu.user_id_ = #{search} OR qu.additional_value_ LIKE CONCAT('%',#{search},'%'))
 		</if>
 		GROUP BY qu.user_id_ <include refid="global.limit"/>) qur
-		LEFT JOIN questionnaire_user_result qu1 ON qur.id_ = qu1.user_id_
+		LEFT JOIN questionnaire_user_result qu1 ON qur.user_id_ = qu1.user_id_
 		LEFT JOIN questionnaire_question qq ON qq.id_ = qu1.questionnaire_question_id_
 		LEFT JOIN questionnaire_question_item qqi ON FIND_IN_SET(qqi.id_,qu1.questionnaire_question_item_id_list_)
 		WHERE qu1.questionnaire_topic_id_ = #{topicId}
@@ -212,6 +222,21 @@
 		ORDER BY qu1.user_id_,qq.sort_
 	</select>
 
+	<select id="queryUserResult" resultMap="QuestionnaireUserResultDto">
+		SELECT qu1.*, qur.username_, qur.phone_, qq.content_,GROUP_CONCAT( qqi.answer_value_ ORDER BY qqi.sort_ ) answer_value_,qq.type_
+		FROM (SELECT qu.user_id_,su.username_,su.phone_
+		FROM questionnaire_user_result qu
+		LEFT JOIN sys_user su ON su.id_ = qu.user_id_
+		WHERE qu.questionnaire_topic_id_ = #{topicId} AND qu.user_id_ = #{userId}
+		GROUP BY qu.user_id_ ) qur
+		LEFT JOIN questionnaire_user_result qu1 ON qur.user_id_ = qu1.user_id_
+		LEFT JOIN questionnaire_question qq ON qq.id_ = qu1.questionnaire_question_id_
+		LEFT JOIN questionnaire_question_item qqi ON FIND_IN_SET( qqi.id_, qu1.questionnaire_question_item_id_list_ )
+		WHERE qu1.questionnaire_topic_id_ = #{topicId}
+		GROUP BY qu1.user_id_,qq.id_
+		ORDER BY qu1.user_id_,qq.sort_
+	</select>
+
 	<resultMap id="QuestionnaireResultDto" type="com.ym.mec.biz.dal.dto.QuestionnaireResultDto">
 		<result column="id_" property="userResultId" />
 		<result property="content" column="content_"/>
@@ -231,7 +256,7 @@
 	<select id="queryUserName" resultType="java.util.Map">
 		SELECT qur.user_id_ `key`,su.username_ `value` FROM questionnaire_user_result qur
 		LEFT JOIN sys_user su ON su.id_ = qur.user_id_
-		WHERE qur.user_id_ IS NOT NULL AND qur.active_type_ = #{activeType} AND su.username_ IS NOT NULL
+		WHERE qur.user_id_ IS NOT NULL AND qur.questionnaire_topic_id_ = #{topicId} AND su.username_ IS NOT NULL
 		GROUP BY qur.user_id_
 	</select>
 </mapper>

+ 9 - 2
mec-biz/src/main/resources/config/mybatis/StudentCloudCoachPaymentDetailsMapper.xml

@@ -39,7 +39,7 @@
 	<insert id="batchInsert">
 		INSERT INTO student_cloud_coach_payment_details (user_id_,payment_status_,create_time_,update_time_,tenant_id_,cloud_coach_payment_program_id_)VALUES
 		<foreach collection="userIds" separator="," item="userId">
-			(#{userId},#{paymentStatus},NOW(),NOW(),#{tenantId},#{cloudCoachPaymentProgramId})
+			(#{userId},0,NOW(),NOW(),#{tenantId},#{cloudCoachPaymentProgramId})
 		</foreach>
 	</insert>
 
@@ -64,7 +64,11 @@
 		update_time_ = NOW()
 		</set> WHERE id_ = #{id}
 	</update>
-	
+	<update id="updatePaymentStatus">
+		UPDATE student_cloud_coach_payment_details SET payment_status_ = 1,update_time_ = NOW()
+		WHERE cloud_coach_payment_program_id_ = #{cloudCoachPaymentProgramId}
+	</update>
+
 	<!-- 根据主键删除一条记录 -->
 	<delete id="delete" >
 		DELETE FROM student_cloud_coach_payment_details WHERE id_ = #{id} 
@@ -100,4 +104,7 @@
 	<select id="findByUserId" resultMap="StudentCloudCoachPaymentDetails">
 		SELECT * FROM student_cloud_coach_payment_details WHERE cloud_coach_payment_program_id_ = #{paymentId} AND user_id_ = #{userId} LIMIT 1
 	</select>
+	<select id="findUserByProgramId" resultType="java.lang.Integer">
+		SELECT user_id_ FROM student_cloud_coach_payment_details WHERE cloud_coach_payment_program_id_ = #{programId}
+	</select>
 </mapper>

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

@@ -197,7 +197,7 @@
                     #{userId}
                 </foreach>
             </if>
-            <if test="organId != null">
+            <if test="organId != null and organId != ''">
                 AND FIND_IN_SET(spo.organ_id_,#{organId})
             </if>
             <if test="orderStartDate != null">
@@ -227,7 +227,7 @@
             <if test='orderType != null and orderType.toString()=="2".toString()'>
                 AND spo.per_amount_ > 0
             </if>
-            <if test="routingOrganId != null">
+            <if test="routingOrganId != null and routingOrganId != ''">
                 AND FIND_IN_SET(spro.route_organ_id_,#{routingOrganId})
             </if>
             <if test="actualAmount != null">

+ 55 - 0
mec-biz/src/main/resources/config/mybatis/TenantPreJoinMapper.xml

@@ -55,4 +55,59 @@
             #{entity.provinceName})
         </foreach>
     </insert>
+
+    <resultMap id="TenantPreJoinVo" type="com.ym.mec.biz.dal.vo.TenantPreJoinVo" extends="BaseResultMap">
+        <result property="recommenderName" column="real_name_"/>
+    </resultMap>
+    <select id="queryPage" parameterType="map" resultMap="TenantPreJoinVo">
+        SELECT a.id_,
+        a.tsign_name_,
+        a.name_,
+        a.area_id_,
+        a.area_name_,
+        a.email_,
+        a.customer_service_phone_,
+        a.tsign_code_,
+        a.address_,
+        a.remark_,
+        a.enterprise_liable_name_,
+        a.enterprise_liable_phone_,
+        a.legal_person_id_front_pic_,
+        a.legal_person_id_reverse_pic_,
+        a.contacts_,
+        a.phone_,
+        a.tsign_pic_,
+        a.tax_register_pic_,
+        a.company_account_info_pic_,
+        a.logo_,
+        a.corporate_chops_,
+        a.corporate_finance_chops_,
+        a.state_,
+        a.created_time_,
+        a.province_id_,
+        a.province_name_,
+        a.recommender_,
+        b.real_name_
+        FROM tenant_pre_join as a
+        left join sys_user as b on a.recommender_ = b.id_
+        <where>
+            <if test="param.recommender != null">
+                AND a.recommender_ = #{param.recommender}
+            </if>
+            <if test="param.state != null">
+                AND state_ = #{param.state}
+            </if>
+            <if test="param.startTime != null">
+                AND created_time_ <![CDATA[ >= ]]> #{param.startTime}
+            </if>
+            <if test="param.endTime != null">
+                AND created_time_ <![CDATA[ <= ]]> #{param.endTime}
+            </if>
+            <if test="param.search != null ">
+                AND (tsign_name_ LIKE CONCAT('%', #{param.search},'%')
+                OR enterprise_liable_name_ LIKE CONCAT('%', #{param.search},'%')
+                OR contacts_ LIKE CONCAT('%', #{param.search},'%'))
+            </if>
+        </where>
+    </select>
 </mapper>

+ 160 - 109
mec-client-api/src/main/java/com/ym/mec/im/ImFeignService.java

@@ -1,121 +1,172 @@
 package com.ym.mec.im;
 
-import java.util.List;
-
+import com.ym.mec.common.config.FeignConfiguration;
+import com.ym.mec.common.entity.*;
+import com.ym.mec.im.entity.GroupModel;
+import com.ym.mec.im.fallback.ImFeignServiceFallback;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.http.MediaType;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
-
-import com.ym.mec.common.config.FeignConfiguration;
-import com.ym.mec.common.entity.ImGroupMessage;
-import com.ym.mec.common.entity.ImGroupModel;
-import com.ym.mec.common.entity.ImPrivateMessage;
-import com.ym.mec.common.entity.ImResult;
-import com.ym.mec.common.entity.ImUserModel;
-import com.ym.mec.im.entity.GroupModel;
-import com.ym.mec.im.fallback.ImFeignServiceFallback;
 import org.springframework.web.bind.annotation.RequestParam;
 
+import java.util.List;
+
 @FeignClient(name = "im-server", configuration = FeignConfiguration.class, fallback = ImFeignServiceFallback.class)
 public interface ImFeignService {
 
-	/**
-	 * 用户注册
-	 * @param userModel
-	 * @return
-	 */
-	@PostMapping(value = "user/register", consumes = MediaType.APPLICATION_JSON_VALUE)
-	ImResult register(@RequestBody ImUserModel userModel);
-
-	/**
-	 * 用户信息修改
-	 * @param userModel
-	 * @return
-	 */
-	@PostMapping(value = "user/update", consumes = MediaType.APPLICATION_JSON_VALUE)
-	void update(@RequestBody ImUserModel userModel);
-
-	/**
-	 * 创建群组
-	 * @param groupModel
-	 * @return
-	 */
-	@PostMapping(value = "group/create")
-	Object groupCreate(@RequestBody GroupModel groupModel);
-
-	/**
-	 * 批量创建群组
-	 * @param groupModels
-	 * @return
-	 */
-	@PostMapping(value = "group/batchCreate")
-	void groupBatchCreate(@RequestBody List<GroupModel> groupModels);
-
-	/**
-	 * 加入群组
-	 * @param groupModel
-	 * @return
-	 */
-	@PostMapping(value = "group/join")
-	Object groupJoin(@RequestBody GroupModel groupModel);
-
-	/**
-	 * 批量加入群组
-	 * @param groupModels
-	 * @return
-	 */
-	@PostMapping(value = "group/batchJoin")
-	Object groupBatchJoin(@RequestBody List<GroupModel> groupModels);
-
-	/**
-	 * 退出群组
-	 * @param groupModel
-	 * @return
-	 */
-	@PostMapping(value = "group/quit")
-	Object groupQuit(@RequestBody GroupModel groupModel);
-
-	/**
-	 * 解散群组
-	 * @param groupModel
-	 * @return
-	 */
-	@PostMapping(value = "group/dismiss")
-	Object groupDismiss(@RequestBody GroupModel groupModel);
-
-	/**
-	 * 批量解散群组
-	 * @param groupModels
-	 * @return
-	 */
-	@PostMapping(value = "group/batchDismiss")
-	Object groupBatchDismiss(@RequestBody List<ImGroupModel> groupModels);
-
-	/**
-	 * 批量退出群组
-	 * @param groupModels
-	 * @return
-	 */
-	@PostMapping(value = "group/batchQuit")
-	Object groupBatchQuit(@RequestBody List<GroupModel> groupModels);
-
-	/**
-	 * 发送私聊消息
-	 * @param privateMessage
-	 * @return
-	 */
-	@PostMapping(value = "private/send")
-	Object privateSend(@RequestBody ImPrivateMessage privateMessage);
-
-	@PostMapping(value = "group/send")
-	Object groupSend(@RequestBody ImGroupMessage imGroupMessage);
-
-	/**
-	 * 获取历史消息记录
-	 * @param date
-	 * @return
-	 */
-	@PostMapping(value = "history/get")
-	Object historyGet(@RequestParam("date") String date);
+    /**
+     * 用户注册
+     *
+     * @param userModel
+     * @return
+     */
+    @PostMapping(value = "user/register", consumes = MediaType.APPLICATION_JSON_VALUE)
+    ImResult register(@RequestBody ImUserModel userModel);
+
+    /**
+     * 用户信息修改
+     *
+     * @param userModel
+     * @return
+     */
+    @PostMapping(value = "user/update", consumes = MediaType.APPLICATION_JSON_VALUE)
+    void update(@RequestBody ImUserModel userModel);
+
+    /**
+     * 创建群组
+     *
+     * @param groupModel
+     * @return
+     */
+    @PostMapping(value = "group/create")
+    Object groupCreate(@RequestBody GroupModel groupModel);
+
+    /**
+     * 批量创建群组
+     *
+     * @param groupModels
+     * @return
+     */
+    @PostMapping(value = "group/batchCreate")
+    void groupBatchCreate(@RequestBody List<GroupModel> groupModels);
+
+    /**
+     * 加入群组
+     *
+     * @param groupModel
+     * @return
+     */
+    @PostMapping(value = "group/join")
+    Object groupJoin(@RequestBody GroupModel groupModel);
+
+    /**
+     * 批量加入群组
+     *
+     * @param groupModels
+     * @return
+     */
+    @PostMapping(value = "group/batchJoin")
+    Object groupBatchJoin(@RequestBody List<GroupModel> groupModels);
+
+    /**
+     * 退出群组
+     *
+     * @param groupModel
+     * @return
+     */
+    @PostMapping(value = "group/quit")
+    Object groupQuit(@RequestBody GroupModel groupModel);
+
+    /**
+     * 解散群组
+     *
+     * @param groupModel
+     * @return
+     */
+    @PostMapping(value = "group/dismiss")
+    Object groupDismiss(@RequestBody GroupModel groupModel);
+
+    /**
+     * 批量解散群组
+     *
+     * @param groupModels
+     * @return
+     */
+    @PostMapping(value = "group/batchDismiss")
+    Object groupBatchDismiss(@RequestBody List<ImGroupModel> groupModels);
+
+    /**
+     * 批量退出群组
+     *
+     * @param groupModels
+     * @return
+     */
+    @PostMapping(value = "group/batchQuit")
+    Object groupBatchQuit(@RequestBody List<GroupModel> groupModels);
+
+    /**
+     * 发送私聊消息
+     *
+     * @param privateMessage
+     * @return
+     */
+    @PostMapping(value = "private/send")
+    Object privateSend(@RequestBody ImPrivateMessage privateMessage);
+
+    @PostMapping(value = "group/send")
+    Object groupSend(@RequestBody ImGroupMessage imGroupMessage);
+
+    /**
+     * 获取历史消息记录
+     *
+     * @param date
+     * @return
+     */
+    @PostMapping(value = "history/get")
+    Object historyGet(@RequestParam("date") String date);
+
+    /**
+     * 创建直播房间
+     *
+     * @param roomId   直播间uid
+     * @param roomName 直播间名称
+     */
+    @PostMapping(value = "/liveRoom/create")
+    Object createLiveRoom(@RequestParam("roomId") String roomId, @RequestParam("roomName") String roomName);
+
+    /**
+     * 销毁直播房间
+     *
+     * @param roomId 直播间uid
+     */
+    @PostMapping(value = "/liveRoom/destroy")
+    Object destroyLiveRoom(@RequestParam("roomId") String roomId);
+
+    /**
+    * @description: 录制直播
+     * @param roomId
+    * @return void
+    * @author zx
+    * @date 2022/2/25 13:52
+    */
+    @PostMapping(value = "/liveRoom/startRecord")
+    void startRecord(@RequestParam("roomId") String roomId);
+
+    /**
+    * @description: 结束录制直播
+     * @param roomId
+    * @return void
+    * @author zx
+    * @date 2022/2/25 13:52
+    */
+    @PostMapping(value = "/liveRoom/stopRecord")
+    void stopRecord(@RequestParam("roomId") String roomId);
+
+    /**
+     * 向直播间发送文本消息
+     */
+    @PostMapping(value = "/liveRoom/publishRoomMsg", consumes = MediaType.APPLICATION_JSON_VALUE)
+    Object publishRoomMsg(@RequestBody ImRoomMessage message);
+
 }

+ 26 - 5
mec-client-api/src/main/java/com/ym/mec/im/fallback/ImFeignServiceFallback.java

@@ -2,13 +2,9 @@ package com.ym.mec.im.fallback;
 
 import java.util.List;
 
+import com.ym.mec.common.entity.*;
 import org.springframework.stereotype.Component;
 
-import com.ym.mec.common.entity.ImGroupMessage;
-import com.ym.mec.common.entity.ImGroupModel;
-import com.ym.mec.common.entity.ImPrivateMessage;
-import com.ym.mec.common.entity.ImResult;
-import com.ym.mec.common.entity.ImUserModel;
 import com.ym.mec.im.ImFeignService;
 import com.ym.mec.im.entity.GroupModel;
 
@@ -80,4 +76,29 @@ public class ImFeignServiceFallback implements ImFeignService {
     public Object historyGet(String date) {
         return null;
     }
+
+    @Override
+    public Object createLiveRoom(String roomId, String roomName) {
+        return null;
+    }
+
+    @Override
+    public Object destroyLiveRoom(String roomId) {
+        return null;
+    }
+
+    @Override
+    public void startRecord(String roomId) {
+
+    }
+
+    @Override
+    public Object publishRoomMsg(ImRoomMessage message) {
+        return null;
+    }
+
+    @Override
+    public void stopRecord(String roomId) {
+
+    }
 }

+ 15 - 4
mec-client-api/src/main/java/com/ym/mec/task/TaskRemoteService.java

@@ -1,10 +1,9 @@
 package com.ym.mec.task;
 
-import org.springframework.cloud.openfeign.FeignClient;
-import org.springframework.web.bind.annotation.GetMapping;
-
 import com.ym.mec.common.config.FeignConfiguration;
 import com.ym.mec.task.fallback.TaskRemoteServiceFallback;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
 
 @FeignClient(name = "web-server", contextId = "TaskRemoteService", configuration = { FeignConfiguration.class }, fallback = TaskRemoteServiceFallback.class)
 public interface TaskRemoteService {
@@ -242,5 +241,17 @@ public interface TaskRemoteService {
 
 	/** 查询老师协议签订状态 */
 	@GetMapping("task/queryTeacherContractSignStatus")
-	public void queryTeacherContractSignStatus();
+	void queryTeacherContractSignStatus();
+
+    /**
+     * 每分钟-查询是否有直播间需要创建
+     */
+    @GetMapping("task/createLiveRoom")
+    void createLiveRoom();
+
+    /**
+     * 每分钟-查询是否有直播间需要销毁
+     */
+    @GetMapping("task/destroyExpiredLiveRoom")
+    void destroyExpiredLiveRoom();
 }

+ 10 - 0
mec-client-api/src/main/java/com/ym/mec/task/fallback/TaskRemoteServiceFallback.java

@@ -294,4 +294,14 @@ public class TaskRemoteServiceFallback implements TaskRemoteService {
 	public void queryTeacherContractSignStatus() {
 		logger.error("查询老师协议签订状态失败");
 	}
+
+    @Override
+    public void createLiveRoom() {
+        logger.error("直播间创建失败");
+    }
+
+    @Override
+    public void destroyExpiredLiveRoom() {
+        logger.error("销毁直播间失败");
+    }
 }

+ 1 - 1
mec-im/src/main/java/com/ym/mec/im/BaseMessage.java → mec-common/common-core/src/main/java/com/ym/mec/common/entity/BaseMessage.java

@@ -1,4 +1,4 @@
-package com.ym.mec.im;
+package com.ym.mec.common.entity;
 
 import com.alibaba.fastjson.JSONObject;
 

+ 67 - 0
mec-common/common-core/src/main/java/com/ym/mec/common/entity/ImRoomMessage.java

@@ -0,0 +1,67 @@
+package com.ym.mec.common.entity;
+
+/**
+ * @author hgw
+ * Created by 2022-02-25
+ */
+public class ImRoomMessage extends BaseMessage {
+
+    //objectName 类型-将所有人强制踢出房间
+    public static final String FORCED_OFFLINE = "RC:ForcedOffline";
+
+    //objectName 类型-观看者退出房间
+    public static final String LOOKER_LOGIN_OUT = "RC:LookerLoginOut";
+
+    /**
+     * 消息类型
+     */
+    private String objectName;
+
+    /**
+     * 消息内容
+     */
+    private Object content;
+
+    /**
+     * 发送者id
+     */
+    private String fromUserId;
+
+    /**
+     * 发送到的房间uid
+     */
+    private String toChatroomId;
+
+    @Override
+    public String getObjectName() {
+        return objectName;
+    }
+
+    public void setObjectName(String objectName) {
+        this.objectName = objectName;
+    }
+
+    public Object getContent() {
+        return content;
+    }
+
+    public void setContent(Object content) {
+        this.content = content;
+    }
+
+    public String getFromUserId() {
+        return fromUserId;
+    }
+
+    public void setFromUserId(String fromUserId) {
+        this.fromUserId = fromUserId;
+    }
+
+    public String getToChatroomId() {
+        return toChatroomId;
+    }
+
+    public void setToChatroomId(String toChatroomId) {
+        this.toChatroomId = toChatroomId;
+    }
+}

+ 70 - 0
mec-common/common-core/src/main/java/com/ym/mec/common/entity/ImUserState.java

@@ -0,0 +1,70 @@
+package com.ym.mec.common.entity;
+
+import java.io.Serializable;
+
+/**
+ * @author hgw
+ * Created by 2022-02-18
+ */
+public class ImUserState implements Serializable {
+    /**
+     * 用户 Id
+     */
+    private String userid;
+    /**
+     * 状态:0:online 上线、1:offline 离线、2:logout 登出  3:退出直播间
+     */
+    private String status;
+    /**
+     * 操作系统:iOS、Android、Websocket、PC、MiniProgram(小程序),用户上线时同步
+     */
+    private String os;
+    /**
+     * 发生时间
+     */
+    private Long time;
+    /**
+     * 用户当前的 IP 地址及端口
+     */
+    private String clientIp;
+
+    public String getUserid() {
+        return userid;
+    }
+
+    public void setUserid(String userid) {
+        this.userid = userid;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public String getOs() {
+        return os;
+    }
+
+    public void setOs(String os) {
+        this.os = os;
+    }
+
+    public Long getTime() {
+        return time;
+    }
+
+    public void setTime(Long time) {
+        this.time = time;
+    }
+
+    public String getClientIp() {
+        return clientIp;
+    }
+
+    public void setClientIp(String clientIp) {
+        this.clientIp = clientIp;
+    }
+}

+ 117 - 115
mec-im/pom.xml

@@ -1,122 +1,124 @@
 <?xml version="1.0"?>
-<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+         xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.ym</groupId>
+        <artifactId>mec</artifactId>
+        <version>1.0</version>
+    </parent>
     <groupId>com.ym</groupId>
-    <artifactId>mec</artifactId>
+    <artifactId>mec-im</artifactId>
     <version>1.0</version>
-  </parent>
-  <groupId>com.ym</groupId>
-  <artifactId>mec-im</artifactId>
-  <version>1.0</version>
-  <name>mec-im</name>
-  <url>http://maven.apache.org</url>
-  <properties>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-  </properties>
-  <dependencies>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter-web</artifactId>
-    </dependency>
+    <name>mec-im</name>
+    <url>http://maven.apache.org</url>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <rongcloud.im.version>3.2.17</rongcloud.im.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
 
-		<dependency>
-			<groupId>org.springframework.cloud</groupId>
-			<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
-		</dependency>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter-data-jpa</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter-data-redis</artifactId>
-    </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
 
-    <dependency>
-      <groupId>mysql</groupId>
-      <artifactId>mysql-connector-java</artifactId>
-      <scope>runtime</scope>
-    </dependency>
-    <dependency>
-      <groupId>com.alibaba</groupId>
-      <artifactId>druid-spring-boot-starter</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.projectlombok</groupId>
-      <artifactId>lombok</artifactId>
-      <optional>true</optional>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter-test</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <!-- https://mvnrepository.com/artifact/commons-lang/commons-lang -->
-    <dependency>
-      <groupId>commons-lang</groupId>
-      <artifactId>commons-lang</artifactId>
-      <version>2.6</version>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter-aop</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.ym</groupId>
-      <artifactId>common-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.ym</groupId>
-      <artifactId>mec-auth-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.alibaba</groupId>
-      <artifactId>fastjson</artifactId>
-      <version>1.2.46</version>
-    </dependency>
-    <!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
-    <dependency>
-      <groupId>commons-codec</groupId>
-      <artifactId>commons-codec</artifactId>
-      <version>1.9</version>
-    </dependency>
-    <!-- https://mvnrepository.com/artifact/joda-time/joda-time -->
-    <dependency>
-      <groupId>joda-time</groupId>
-      <artifactId>joda-time</artifactId>
-      <version>2.8.1</version>
-    </dependency>
-    <dependency>
-      <groupId>com.ym</groupId>
-      <artifactId>mec-biz</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>cn.rongcloud.im</groupId>
-      <artifactId>server-sdk-java</artifactId>
-      <version>3.1.4</version>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.cloud</groupId>
-      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.netty</groupId>
-      <artifactId>netty-all</artifactId>
-    </dependency>
-  </dependencies>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/commons-lang/commons-lang -->
+        <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+            <version>2.6</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-aop</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ym</groupId>
+            <artifactId>common-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ym</groupId>
+            <artifactId>mec-auth-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.46</version>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+            <version>1.9</version>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/joda-time/joda-time -->
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+            <version>2.8.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.ym</groupId>
+            <artifactId>mec-biz</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>cn.rongcloud.im</groupId>
+            <artifactId>server-sdk-java</artifactId>
+            <version>${rongcloud.im.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-all</artifactId>
+        </dependency>
+    </dependencies>
 
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot-maven-plugin</artifactId>
-      </plugin>
-      <plugin>
-        <groupId>com.spotify</groupId>
-        <artifactId>docker-maven-plugin</artifactId>
-      </plugin>
-    </plugins>
-  </build>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>docker-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
 </project>

+ 1 - 0
mec-im/src/main/java/com/ym/config/IMProperties.java

@@ -14,4 +14,5 @@ public class IMProperties {
     private String appKey;
     private String secret;
     private String host;
+    private String rtcHost;
 }

+ 6 - 4
mec-im/src/main/java/com/ym/config/ResourceServerConfig.java

@@ -10,9 +10,11 @@ import org.springframework.security.oauth2.config.annotation.web.configuration.R
 public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
     @Override
     public void configure(HttpSecurity http) throws Exception {
-        http.authorizeRequests().antMatchers("/v2/api-docs","/user/register",
-                "/group/join","/group/create","/group/quit","/room/leave","/room/statusSync",
-                "/room/statusImMsg","/group/batchDismiss","/private/send","/group/send",
-                "/group/dismiss","/room/statusImMsg","/history/get").permitAll().anyRequest().authenticated().and().csrf().disable();
+        http.authorizeRequests().antMatchers("/v2/api-docs", "/user/register",
+                        "/group/join", "/group/create", "/group/quit", "/room/leave", "/room/statusSync",
+                        "/room/statusImMsg", "/group/batchDismiss", "/private/send", "/group/send",
+                        "/group/dismiss", "/room/statusImMsg", "/history/get", "/user/statusImUser", "/liveRoom/recordSync",
+                        "/liveRoom/publishRoomMsg","/liveRoom/destroy","/liveRoom/create","/liveRoom/startRecord","/liveRoom/stopRecord")
+                .permitAll().anyRequest().authenticated().and().csrf().disable();
     }
 }

+ 1 - 1
mec-im/src/main/java/com/ym/config/WebMvcConfig.java

@@ -57,7 +57,7 @@ public class WebMvcConfig implements WebMvcConfigurer {
 		registry.addInterceptor(tenantInterceptor).addPathPatterns("/**").excludePathPatterns("/v2/api-docs",
 				"/group/*","/room/statusSync",
 				"/room/statusImMsg","/private/*","/system/*",
-				"/room/statusImMsg","/history/get","/user/*","/push/*");
+				"/room/statusImMsg","/history/get","/user/*","/push/*","/liveRoom/recordSync");
 	}
 
 	@SuppressWarnings("rawtypes")

+ 65 - 0
mec-im/src/main/java/com/ym/controller/LiveRoomController.java

@@ -0,0 +1,65 @@
+package com.ym.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.ym.mec.common.entity.ImRoomMessage;
+import com.ym.pojo.IMApiResultInfo;
+import com.ym.pojo.RecordNotify;
+import com.ym.service.LiveRoomService;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+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.RestController;
+
+/**
+ * @author hgw
+ * Created by 2022-02-21
+ */
+@RestController
+@RequestMapping("/liveRoom")
+@Slf4j
+public class LiveRoomController {
+
+    @Autowired
+    private LiveRoomService liveRoomService;
+
+    @ApiOperation("创建直播房间")
+    @PostMapping(value = "/create")
+    public IMApiResultInfo createLiveRoom(String roomId, String roomName) throws Exception {
+        return liveRoomService.createLiveRoom(roomId, roomName);
+    }
+
+    @ApiOperation("销毁直播房间")
+    @PostMapping(value = "/destroy")
+    public IMApiResultInfo destroyLiveRoom(String roomId) throws Exception {
+        return liveRoomService.destroyLiveRoom(roomId);
+    }
+
+    @ApiOperation("向房间发送消息")
+    @PostMapping(value = "/publishRoomMsg")
+    public IMApiResultInfo publishRoomTextMsg(@RequestBody ImRoomMessage message) {
+        return liveRoomService.publishRoomMessage(message);
+    }
+
+    @ApiOperation("录制结果回调")
+    @RequestMapping(value = "/recordSync")
+    public void recordSync(@RequestBody String body) {
+        log.info("recordSync body:{}", body);
+        RecordNotify recordNotify = JSONObject.parseObject(body, RecordNotify.class);
+        liveRoomService.recordSync(recordNotify);
+    }
+
+    @ApiOperation("录制直播")
+    @RequestMapping(value = "/startRecord")
+    public void startRecord(String roomId) throws Exception {
+        liveRoomService.startRecord(roomId);
+    }
+
+    @ApiOperation("结束录制直播")
+    @RequestMapping(value = "/stopRecord")
+    public void stopRecord(String roomId) throws Exception {
+        liveRoomService.stopRecord(roomId);
+    }
+}

+ 26 - 6
mec-im/src/main/java/com/ym/controller/UserController.java

@@ -1,26 +1,46 @@
 package com.ym.controller;
 
+import com.alibaba.fastjson.JSONObject;
+import com.ym.common.BaseResponse;
+import com.ym.mec.biz.service.ImLiveBroadcastRoomService;
+import com.ym.mec.common.entity.ImUserState;
 import com.ym.service.UserService;
 import io.rong.models.user.UserModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
 
 @RestController
 @RequestMapping("/user")
 public class UserController {
-
+    private static final Logger log = LoggerFactory.getLogger(UserController.class);
+    @Autowired
+    private UserService userService;
     @Autowired
-    UserService userService;
+    private ImLiveBroadcastRoomService imLiveBroadcastRoomService;
 
     @RequestMapping(value = "/register", method = RequestMethod.POST)
     public Object register(@RequestBody UserModel userModel) throws Exception {
         return userService.register(userModel);
     }
+
     @RequestMapping(value = "/update", method = RequestMethod.POST)
     public Object update(@RequestBody UserModel userModel) throws Exception {
         return userService.update(userModel);
     }
+
+    /**
+     * 监听融云用户状态变更
+     *
+     * @param userState
+     */
+    @PostMapping(value = "/statusImUser")
+    public BaseResponse statusImUser(@RequestBody List<ImUserState> userState) {
+        log.info("statusImUser >>>>> : {}", JSONObject.toJSONString(userState));
+        imLiveBroadcastRoomService.opsRoom(userState);
+        return new BaseResponse<>();
+    }
 }

+ 1 - 1
mec-im/src/main/java/com/ym/pojo/ActionEnum.java → mec-im/src/main/java/com/ym/enums/ActionEnum.java

@@ -1,4 +1,4 @@
-package com.ym.pojo;
+package com.ym.enums;
 
 /**
  * Created by weiqinxiao on 2019/3/19.

+ 1 - 1
mec-im/src/main/java/com/ym/pojo/DeviceTypeEnum.java → mec-im/src/main/java/com/ym/enums/DeviceTypeEnum.java

@@ -1,4 +1,4 @@
-package com.ym.pojo;
+package com.ym.enums;
 
 public enum DeviceTypeEnum {
     Microphone,

+ 1 - 1
mec-im/src/main/java/com/ym/pojo/RoleEnum.java → mec-im/src/main/java/com/ym/enums/RoleEnum.java

@@ -1,4 +1,4 @@
-package com.ym.pojo;
+package com.ym.enums;
 
 import com.ym.common.ApiException;
 import com.ym.common.ErrorEnum;

+ 93 - 33
mec-im/src/main/java/com/ym/http/HttpHelper.java

@@ -2,7 +2,9 @@ package com.ym.http;
 
 import com.ym.config.IMProperties;
 import com.ym.utils.CodeUtil;
+import io.rong.util.GsonUtil;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
@@ -12,12 +14,12 @@ import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.ProtocolException;
-import java.net.URL;
+import java.net.*;
+import java.nio.charset.StandardCharsets;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
+import java.util.HashMap;
+import java.util.Map;
 
 @Slf4j
 @Component
@@ -31,7 +33,7 @@ public class HttpHelper {
 
     @Autowired
     IMProperties imProperties;
-    
+
     @PostConstruct
     private void init() {
         log.info("init HttpHelper");
@@ -69,7 +71,7 @@ public class HttpHelper {
 
     // 设置body体
     public void setBodyParameter(StringBuilder sb, HttpURLConnection conn)
-        throws IOException {
+            throws IOException {
         String str = sb.toString();
         log.info("Call server api with url: {}, data: {}", conn.getURL().toString(), str);
         DataOutputStream out = new DataOutputStream(conn.getOutputStream());
@@ -79,7 +81,7 @@ public class HttpHelper {
     }
 
     public HttpURLConnection createGetHttpConnection(String uri)
-        throws MalformedURLException, IOException {
+            throws MalformedURLException, IOException {
         URL url = new URL(uri);
         HttpURLConnection conn = (HttpURLConnection) url.openConnection();
         conn.setConnectTimeout(30000);
@@ -90,32 +92,23 @@ public class HttpHelper {
     public void setBodyParameter(String str, HttpURLConnection conn) throws IOException {
         log.info("Call IM server api with url: {}, data: {}", conn.getURL().toString(), str);
         DataOutputStream out = new DataOutputStream(conn.getOutputStream());
-        out.write(str.getBytes("utf-8"));
+        out.write(str.getBytes(StandardCharsets.UTF_8));
         out.flush();
         out.close();
     }
 
     public HttpURLConnection createWhiteBoardPostHttpConnection(String host, String uri, String contentType)
-        throws MalformedURLException, IOException, ProtocolException {
+            throws MalformedURLException, IOException, ProtocolException {
 
         URL url = new URL(host + uri);
         HttpURLConnection conn = (HttpURLConnection) url.openConnection();
-        conn.setUseCaches(false);
-        conn.setDoInput(true);
-        conn.setDoOutput(true);
-        conn.setRequestMethod("POST");
-        conn.setInstanceFollowRedirects(true);
-        conn.setConnectTimeout(30000);
-        conn.setReadTimeout(30000);
-
-        conn.setRequestProperty("Content-Type", contentType);
-
+        setConn(conn, contentType);
         return conn;
     }
 
     public HttpURLConnection createCommonPostHttpConnection(String host, String appKey,
-        String appSecret, String uri, String contentType)
-        throws MalformedURLException, IOException, ProtocolException {
+                                                            String appSecret, String uri, String contentType)
+            throws MalformedURLException, IOException, ProtocolException {
         String nonce = String.valueOf(Math.random() * 1000000);
         String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
         StringBuilder toSign = new StringBuilder(appSecret).append(nonce).append(timestamp);
@@ -145,8 +138,7 @@ public class HttpHelper {
     }
 
     public HttpURLConnection createCommonGetHttpConnection(String host, String appKey,
-        String appSecret, String uri, String contentType)
-        throws MalformedURLException, IOException, ProtocolException {
+                                                           String appSecret, String uri, String contentType) throws IOException {
         String nonce = String.valueOf(Math.random() * 1000000);
         String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
         StringBuilder toSign = new StringBuilder(appSecret).append(nonce).append(timestamp);
@@ -175,18 +167,16 @@ public class HttpHelper {
         return conn;
     }
 
-    public HttpURLConnection createIMGetHttpConnection(String uri, String contentType)
-        throws MalformedURLException, IOException, ProtocolException {
+    public HttpURLConnection createIMGetHttpConnection(String uri, String contentType) throws IOException {
         return createCommonGetHttpConnection(imProperties.getHost(),
-            imProperties.getAppKey(), imProperties.getSecret(), uri,
-            contentType);
+                imProperties.getAppKey(), imProperties.getSecret(), uri,
+                contentType);
     }
 
-    public HttpURLConnection createIMPostHttpConnection(String uri, String contentType)
-        throws MalformedURLException, IOException, ProtocolException {
+    public HttpURLConnection createIMPostHttpConnection(String uri, String contentType) throws IOException {
         return createCommonPostHttpConnection(imProperties.getHost(),
                 imProperties.getAppKey(), imProperties.getSecret(), uri,
-            contentType);
+                contentType);
     }
 
     public byte[] readInputStream(InputStream inStream) throws Exception {
@@ -202,6 +192,34 @@ public class HttpHelper {
         return data;
     }
 
+    public String returnResult(HttpURLConnection conn) throws Exception {
+        InputStream input;
+        String result;
+        try {
+            if (conn.getResponseCode() == 200 || conn.getResponseCode() == 201) {
+                input = conn.getInputStream();
+            } else {
+                input = conn.getErrorStream();
+            }
+            result = new String(readInputStream(input), StandardCharsets.UTF_8);
+        } catch (UnknownHostException e) {
+            result = getExceptionMessage("request:" + conn.getURL() + " ,UnknownHostException:" + e.getMessage());
+        } catch (SocketTimeoutException e) {
+            result = getExceptionMessage("request:" + conn.getURL() + " ,SocketTimeoutException:" + e.getMessage());
+        } catch (IOException e) {
+            result = getExceptionMessage("request:" + conn.getURL() + " ,IOException:" + e.getMessage());
+        }
+        log.info("IM server api response:{}", result);
+        return result;
+    }
+
+    private static String getExceptionMessage(String error) {
+        Map<String, Object> result = new HashMap<>();
+        result.put("code", 400);
+        result.put("msg", error);
+        return GsonUtil.toJson(result);
+    }
+
     public String returnResult(HttpURLConnection conn, String body) throws Exception, IOException {
         InputStream input = null;
         if (conn.getResponseCode() == 200) {
@@ -214,15 +232,49 @@ public class HttpHelper {
         return result;
     }
 
-    public HttpURLConnection createPostHttpConnection(String uri, String contentType)
-        throws IOException {
-
+    public HttpURLConnection createPostHttpConnection(String uri, String contentType) throws IOException {
         URL url = new URL(uri);
         HttpURLConnection conn = (HttpURLConnection) url.openConnection();
         if (conn == null) {
             log.info("open url connection fail, url={}", uri);
             return null;
         }
+        setConn(conn, contentType);
+        return conn;
+    }
+
+    private void setConn(HttpURLConnection conn, String contentType) throws ProtocolException {
+        conn.setUseCaches(false);
+        conn.setDoInput(true);
+        conn.setDoOutput(true);
+        conn.setRequestMethod("POST");
+        conn.setInstanceFollowRedirects(true);
+        conn.setConnectTimeout(30000);
+        conn.setReadTimeout(30000);
+        conn.setRequestProperty("Content-Type", contentType);
+    }
+
+    public HttpURLConnection createIMRtcPostHttpConnection(String uri, String contentType,String roomId)
+            throws IOException{
+        return createCommonRtcPostHttpConnection(imProperties.getRtcHost(),
+                imProperties.getAppKey(), imProperties.getSecret(), uri,
+                contentType,roomId);
+    }
+
+    public HttpURLConnection createCommonRtcPostHttpConnection(String host, String appKey,
+                                                               String appSecret, String uri, String contentType,String roomId)
+            throws IOException{
+        String nonce = String.valueOf(Math.random() * 1000000);
+        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
+        StringBuilder toSign = new StringBuilder(appSecret).append(nonce).append(timestamp);
+        String sign = CodeUtil.hexSHA1(toSign.toString());
+        uri = host + uri;
+        URL url = new URL(uri);
+        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+        if (conn == null) {
+            log.info("open url connectin fail, url={}", uri);
+            return null;
+        }
 
         conn.setUseCaches(false);
         conn.setDoInput(true);
@@ -231,6 +283,14 @@ public class HttpHelper {
         conn.setInstanceFollowRedirects(true);
         conn.setConnectTimeout(30000);
         conn.setReadTimeout(30000);
+
+        conn.setRequestProperty("App-Key", appKey);
+        conn.setRequestProperty("Nonce", nonce);
+        conn.setRequestProperty("Timestamp", timestamp);
+        conn.setRequestProperty("Signature", sign);
+        if(StringUtils.isNotEmpty(roomId)){
+            conn.setRequestProperty("Room-Id", roomId);
+        }
         conn.setRequestProperty("Content-Type", contentType);
         return conn;
     }

+ 131 - 17
mec-im/src/main/java/com/ym/mec/im/IMHelper.java

@@ -2,15 +2,21 @@ package com.ym.mec.im;
 
 import com.alibaba.fastjson.JSON;
 import com.ym.http.HttpHelper;
+import com.ym.mec.common.entity.BaseMessage;
+import com.ym.mec.common.exception.BizException;
 import com.ym.pojo.IMApiResultInfo;
 import com.ym.pojo.IMTokenInfo;
+import io.rong.util.GsonUtil;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Component;
 
 import java.net.HttpURLConnection;
 import java.net.URLEncoder;
+import java.util.List;
+import java.util.Objects;
 
 /**
  * Created by weiqinxiao on 2019/2/28.
@@ -26,8 +32,8 @@ public class IMHelper {
     /**
      * 获取 Token 方法
      *
-     * @param userId:用户 Id,最大长度 64 字节.是用户在 App 中的唯一标识码,必须保证在同一个 App 内不重复,重复的用户 Id 将被当作是同一用户。(必传)
-     * @param name:用户名称,最大长度 128 字节.用来在 Push 推送时显示用户的名称.用户名称,最大长度 128 字节.用来在 Push 推送时显示用户的名称。(必传)
+     * @param userId:用户        Id,最大长度 64 字节.是用户在 App 中的唯一标识码,必须保证在同一个 App 内不重复,重复的用户 Id 将被当作是同一用户。(必传)
+     * @param name:用户名称,最大长度   128 字节.用来在 Push 推送时显示用户的名称.用户名称,最大长度 128 字节.用来在 Push 推送时显示用户的名称。(必传)
      * @param portraitUri:用户头像 URI,最大长度 1024 字节.用来在 Push 推送时显示用户的头像。(必传)
      * @return TokenResult
      **/
@@ -64,8 +70,8 @@ public class IMHelper {
      * 内的群组数量没有限制.注:其实本方法是加入群组方法 /group/join 的别名。)
      *
      * @param userId:要加入群的用户 Id。(必传)
-     * @param groupId:创建群组 Id。(必传)
-     * @param groupName:群组 Id 对应的名称。(必传)
+     * @param groupId:创建群组   Id。(必传)
+     * @param groupName:群组   Id 对应的名称。(必传)
      * @return CodeSuccessResult
      **/
     public IMApiResultInfo createGroup(String[] userId, String groupId, String groupName)
@@ -107,8 +113,8 @@ public class IMHelper {
     /**
      * 将用户加入指定群组,用户将可以收到该群的消息,同一用户最多可加入 500 个群,每个群最大至 3000 人。
      *
-     * @param userId:要加入群的用户 Id,可提交多个,最多不超过 1000 个。(必传)
-     * @param groupId:要加入的群 Id。(必传)
+     * @param userId:要加入群的用户  Id,可提交多个,最多不超过 1000 个。(必传)
+     * @param groupId:要加入的群   Id。(必传)
      * @param groupName:要加入的群 Id 对应的名称。(必传)
      * @return CodeSuccessResult
      **/
@@ -149,12 +155,11 @@ public class IMHelper {
     }
 
 
-
     /**
      * 退出群组方法(将用户从群中移除,不再接收该群组的消息.)
      *
      * @param userId:要退出群的用户 Id.(必传)
-     * @param groupId:要退出的群 Id.(必传)
+     * @param groupId:要退出的群  Id.(必传)
      * @return CodeSuccessResult
      **/
     public IMApiResultInfo quit(String[] userId, String groupId) throws Exception {
@@ -191,7 +196,7 @@ public class IMHelper {
      * 解散群组方法。(将该群解散,所有用户都无法再接收该群的消息。)
      *
      * @param userId:操作解散群的用户 Id。(必传)
-     * @param groupId:要解散的群 Id。(必传)
+     * @param groupId:要解散的群   Id。(必传)
      * @return CodeSuccessResult
      **/
     public IMApiResultInfo dismiss(String userId, String groupId) throws Exception {
@@ -222,15 +227,15 @@ public class IMHelper {
     /**
      * 发送群组消息方法(以一个用户身份向群组发送消息,单条消息最大 128k.每秒钟最多发送 20 条消息,每次最多向 3 个群组发送,如:一次向 3 个群组发送消息,示为 3 条消息。)
      *
-     * @param fromUserId:发送人用户 Id 。(必传)
-     * @param toGroupId:接收群Id,提供多个本参数可以实现向多群发送消息,最多不超过 3 个群组。(必传)
-     * @param pushContent:定义显示的 Push 内容,如果 objectName 为融云内置消息类型时,则发送后用户一定会收到 Push 信息. 如果为自定义消息,则
-     * pushContent 为自定义消息显示的 Push 内容,如果不传则用户不会收到 Push 通知。(可选)
-     * @param pushData:针对 iOS 平台为 Push 通知时附加到 payload 中,Android 客户端收到推送消息时对应字段名为 pushData。(可选)
-     * @param isPersisted:当前版本有新的自定义消息,而老版本没有该自定义消息时,老版本客户端收到消息后是否进行存储,0 表示为不存储、 1 表示为存储,默认为 1
-     * 存储消息。(可选)
+     * @param fromUserId:发送人用户                                             Id 。(必传)
+     * @param toGroupId:接收群Id,提供多个本参数可以实现向多群发送消息,最多不超过                     3 个群组。(必传)
+     * @param pushContent:定义显示的                                            Push 内容,如果 objectName 为融云内置消息类型时,则发送后用户一定会收到 Push 信息. 如果为自定义消息,则
+     *                                                                     pushContent 为自定义消息显示的 Push 内容,如果不传则用户不会收到 Push 通知。(可选)
+     * @param pushData:针对                                                  iOS 平台为 Push 通知时附加到 payload 中,Android 客户端收到推送消息时对应字段名为 pushData。(可选)
+     * @param isPersisted:当前版本有新的自定义消息,而老版本没有该自定义消息时,老版本客户端收到消息后是否进行存储,0   表示为不存储、 1 表示为存储,默认为 1
+     *                                                                     存储消息。(可选)
      * @param isCounted:当前版本有新的自定义消息,而老版本没有该自定义消息时,老版本客户端收到消息后是否进行未读消息计数,0 表示为不计数、 1 表示为计数,默认为 1
-     * 计数,未读消息数增加 1。(可选)
+     *                                                                     计数,未读消息数增加 1。(可选)
      * @return CodeSuccessResult
      **/
     public IMApiResultInfo publishMessage(String fromUserId, String toGroupId, BaseMessage message) throws Exception {
@@ -332,4 +337,113 @@ public class IMHelper {
 
         return JSON.parseObject(httpHelper.returnResult(conn, body), IMApiResultInfo.class);
     }
+
+    /**
+     * 创建聊天室
+     *
+     * @param chatRoomId:   要创建的聊天室 Id,长度不超过 64 字节
+     * @param chatRoomName: 聊天室的名称,每次可创建多个聊天室。
+     * @return IMApiResultInfo
+     * @throws Exception
+     */
+    public IMApiResultInfo createChatRoom(String chatRoomId, String chatRoomName) throws Exception {
+        if (chatRoomId == null) {
+            throw new BizException("房间Uid不能为空");
+        }
+
+        if (chatRoomName == null) {
+            throw new BizException("房间名称不能为空");
+        }
+
+        StringBuilder sb = new StringBuilder();
+        chatRoomId = "[" + chatRoomId + "]";
+        sb.append("&chatroom").append(URLEncoder.encode(chatRoomId, UTF8));
+        sb.append("=");
+        sb.append(URLEncoder.encode(chatRoomName, UTF8));
+        String body = sb.toString();
+        if (body.indexOf("&") == 0) {
+            body = body.substring(1);
+        }
+
+        HttpURLConnection conn = httpHelper
+                .createIMPostHttpConnection("/chatroom/create.json", "application/x-www-form-urlencoded");
+        httpHelper.setBodyParameter(body, conn);
+
+        return (IMApiResultInfo) GsonUtil.fromJson(httpHelper.returnResult(conn), IMApiResultInfo.class);
+    }
+
+
+    /**
+     * 销毁聊天室
+     *
+     * @param chatroomIds 聊天室 ID 列表(必传)
+     * @return
+     */
+    public IMApiResultInfo deleteChrm(List<String> chatroomIds)
+            throws Exception {
+        if (chatroomIds == null) {
+            throw new BizException("房间Uid不能为空");
+        }
+        StringBuilder sb = new StringBuilder();
+        for (String child : chatroomIds) {
+            sb.append("&chatroomId=").append(URLEncoder.encode(child, UTF8));
+        }
+        String body = sb.toString();
+        if (body.indexOf("&") == 0) {
+            body = body.substring(1);
+        }
+        HttpURLConnection conn = httpHelper.createIMPostHttpConnection("/chatroom/destroy.json", "application/x-www-form-urlencoded");
+        httpHelper.setBodyParameter(body, conn);
+
+        return (IMApiResultInfo) GsonUtil.fromJson(httpHelper.returnResult(conn), IMApiResultInfo.class);
+
+    }
+
+    /**
+     * 发送房间消息
+     *
+     * @param fromUserId   发送人id
+     * @param toChatroomId 房间uid
+     * @param message      发送的消息
+     */
+    public IMApiResultInfo publishRoomMessage(String fromUserId, String toChatroomId, BaseMessage message) throws Exception {
+        String[] toChatroomIds = new String[1];
+        toChatroomIds[0] = toChatroomId;
+        return publishRoomMessage(fromUserId, toChatroomIds, message);
+    }
+
+    public IMApiResultInfo publishRoomMessage(String fromUserId, String[] toChatroomIds, BaseMessage message) throws Exception {
+        if (StringUtils.isBlank(fromUserId)) {
+            throw new BizException("发送人不能为空");
+        }
+        if (Objects.isNull(toChatroomIds)) {
+            throw new BizException("房间Uid不能为空");
+        }
+        if (Objects.isNull(message)) {
+            throw new BizException("消息不能为空");
+        }
+
+        StringBuilder sb = new StringBuilder();
+        sb.append("&fromUserId=").append(URLEncoder.encode(fromUserId, UTF8));
+
+        for (String child : toChatroomIds) {
+            sb.append("&toChatroomId=").append(URLEncoder.encode(child, UTF8));
+        }
+
+        String msgStr = GsonUtil.toJson(message);
+        log.info("publish msg: {}", msgStr);
+        sb.append("&objectName=").append(URLEncoder.encode(message.getObjectName(), UTF8));
+        sb.append("&content=").append(URLEncoder.encode(msgStr, UTF8));
+
+        String body = sb.toString();
+        if (body.indexOf("&") == 0) {
+            body = body.substring(1);
+        }
+
+        HttpURLConnection conn = httpHelper
+                .createIMPostHttpConnection("/message/chatroom/publish.json", "application/x-www-form-urlencoded");
+        httpHelper.setBodyParameter(body, conn);
+
+        return (IMApiResultInfo) GsonUtil.fromJson(httpHelper.returnResult(conn), IMApiResultInfo.class);
+    }
 }

Some files were not shown because too many files changed in this diff