Browse Source

Merge branch 'master' into test

# Conflicts:
#	mec-im/src/main/java/com/ym/controller/RoomController.java
Joburgess 4 năm trước cách đây
mục cha
commit
db2be2ba4e

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

@@ -1477,6 +1477,8 @@ public interface CourseScheduleDao extends BaseDAO<Long, CourseSchedule> {
      */
     CourseSchedule findFirstCourseWithGroup(@Param("groupId") String groupId,
                                             @Param("groupType") GroupType groupType);
+    CourseSchedule findLastCourseWithGroup(@Param("groupId") String groupId,
+                                            @Param("groupType") GroupType groupType);
 
     List<CourseSchedule> findClassGroupLastTeacher(@Param("classGroupIds") List<Integer> classGroupIds);
 

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

@@ -21,6 +21,9 @@ public interface StudentCourseHomeworkDao extends BaseDAO<Long, StudentCourseHom
     @Select("SELECT COUNT(*) FROM student_course_homework WHERE course_homework_id_=#{courseHomeworkID} AND attachments_ IS NOT NULL")
     int countCompletedStudentNum(Long courseHomeworkID);
 
+    @Select("SELECT COUNT(user_id_) FROM student_course_homework WHERE course_schedule_id_=#{courseId}")
+    int countHomeworkStudentNumWithCourse(Long courseId);
+
     /**
      * @Author: Joburgess
      * @Date: 2019/9/18

+ 13 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/TeacherPersonalAttendanceDto.java

@@ -1,6 +1,7 @@
 package com.ym.mec.biz.dal.dto;
 
 import com.ym.mec.biz.dal.entity.CourseSchedule;
+import com.ym.mec.biz.dal.enums.CourseStatusEnum;
 import io.swagger.annotations.ApiModelProperty;
 
 /**
@@ -27,6 +28,10 @@ public class TeacherPersonalAttendanceDto {
     @ApiModelProperty(value = "课程类型",required = false)
     private CourseSchedule.CourseScheduleType type;
 
+    /** 课程状态 */
+    @ApiModelProperty(value = "课程状态",required = false)
+    private CourseStatusEnum courseStatus;
+
     /** 班级名称 */
     @ApiModelProperty(value = "班级名称",required = false)
     private String name;
@@ -43,6 +48,14 @@ public class TeacherPersonalAttendanceDto {
     @ApiModelProperty(value = "备注",required = false)
     private String remark;
 
+    public CourseStatusEnum getCourseStatus() {
+        return courseStatus;
+    }
+
+    public void setCourseStatus(CourseStatusEnum courseStatus) {
+        this.courseStatus = courseStatus;
+    }
+
     public Integer getSignInStatus() {
         return signInStatus;
     }

+ 12 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/StudentAttendance.java

@@ -47,8 +47,12 @@ public class StudentAttendance {
 	@ApiModelProperty(value = "学生姓名",required = false)
 	private String username;
 
+	//学员头像
 	private String avatar;
 
+	//老师头像
+	private String teacherAvatar;
+
 	/**  */
 	@ApiModelProperty(value = "声部列表",required = false)
 	private String subjectName;
@@ -86,6 +90,14 @@ public class StudentAttendance {
 	@ApiModelProperty(value = "缴费状态")
 	private String paymentStatus = "PAID_COMPLETED";
 
+	public String getTeacherAvatar() {
+		return teacherAvatar;
+	}
+
+	public void setTeacherAvatar(String teacherAvatar) {
+		this.teacherAvatar = teacherAvatar;
+	}
+
 	public YesOrNoEnum getVisitFlag() {
 		return visitFlag;
 	}

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/page/RepairStudentQueryInfo.java

@@ -34,6 +34,9 @@ public class RepairStudentQueryInfo extends QueryInfo {
     @ApiModelProperty(value = "特权减免金额",required = false)
     private BigDecimal exemptionAmount;
 
+    @ApiModelProperty(value = "是否有减免金额0-否 1-是",required = false)
+    private Integer hasExemptionAmount;
+
 
     public Integer getSubjectId() {
         return subjectId;
@@ -122,4 +125,12 @@ public class RepairStudentQueryInfo extends QueryInfo {
     public void setExemptionAmount(BigDecimal exemptionAmount) {
         this.exemptionAmount = exemptionAmount;
     }
+
+    public Integer getHasExemptionAmount() {
+        return hasExemptionAmount;
+    }
+
+    public void setHasExemptionAmount(Integer hasExemptionAmount) {
+        this.hasExemptionAmount = hasExemptionAmount;
+    }
 }

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

@@ -4959,8 +4959,8 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
     	if(practiceGroup == null){
 			throw new BizException("课程组不存在");
 		}
-    	if(!GroupStatusEnum.NORMAL.equals(practiceGroup.getGroupStatus())){
-    		throw new BizException("非进行中课程组不可编辑");
+		if(!GroupStatusEnum.NORMAL.equals(practiceGroup.getGroupStatus())&&!GroupStatusEnum.FINISH.equals(practiceGroup.getGroupStatus())){
+			throw new BizException("非正常状态课程组不可编辑");
 		}
 		if(courseStartDate.after(coursesExpireDate)){
 			throw new BizException("课程组有效结束时间不能早于课程组有效开始时间");
@@ -4981,6 +4981,7 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 //				throw new BizException("课程结束时间不得早于,{}", DateUtil.dateToString(courseExpiredDateTemp, "yyyy年MM月dd日"));
 //			}
 //		}
+		Date now = new Date();
 		CoursesGroupModifyLog coursesGroupModifyLog = new CoursesGroupModifyLog();
 		coursesGroupModifyLog.setGroupId(practiceGroupId);
 		coursesGroupModifyLog.setGroupType(PRACTICE.getCode());
@@ -4988,7 +4989,10 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 		coursesGroupModifyLog.setPreviousGroup(JSONObject.toJSONString(practiceGroup));
 		practiceGroup.setCoursesStartDate(courseStartDate);
 		practiceGroup.setCoursesExpireDate(DateUtil.addSeconds(DateUtil.addDays(coursesExpireDate, 1),-1));
-		practiceGroup.setUpdateTime(new Date());
+		if(practiceGroup.getCoursesExpireDate().compareTo(now)>=0||DateUtil.isSameDay(practiceGroup.getCoursesExpireDate(), now)){
+			practiceGroup.setGroupStatus(GroupStatusEnum.NORMAL);
+		}
+		practiceGroup.setUpdateTime(now);
 		practiceGroupDao.update(practiceGroup);
 		coursesGroupModifyLog.setCurrentGroup(JSONObject.toJSONString(practiceGroup));
 		coursesGroupModifyLogDao.insert(coursesGroupModifyLog);

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

@@ -109,6 +109,8 @@ public class StudentManageServiceImpl implements StudentManageService {
     private CourseScheduleDao courseScheduleDao;
     @Autowired
     private SysUserContractsDao sysUserContractsDao;
+    @Autowired
+    private StudentCourseHomeworkDao studentCourseHomeworkDao;
 
     @Override
     public PageInfo<StudentManageListDto> findStudentsByOrganId(StudentManageQueryInfo queryInfo) {
@@ -713,6 +715,7 @@ public class StudentManageServiceImpl implements StudentManageService {
             sum.put("truantNum", 0);
         }
         sum.put("homeworkNum", studentManageDao.countHomeworkNum(courseScheduleId));
+        sum.put("homeworkStudentNum", studentCourseHomeworkDao.countHomeworkStudentNumWithCourse(courseScheduleId.longValue()));
         sum.put("repliedNum", studentManageDao.countRepliedNum(courseScheduleId));
         return sum;
     }

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

@@ -3196,15 +3196,20 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 		if (vipGroupList != null && vipGroupList.size() > 0) {
 			Date date = new Date();
 			for (VipGroup vipGroup : vipGroupList) {
+				if(Objects.nonNull(vipGroup.getCoursesExpireDate())&&vipGroup.getCoursesExpireDate().compareTo(date)<0&&!DateUtil.isSameDay(vipGroup.getCoursesExpireDate(), date)){
+					continue;
+				}
 				vipGroup.setStatus(VipGroupStatusEnum.FINISHED);
 				vipGroup.setUpdateTime(date);
 			}
 			vipGroupDao.batchUpdate(vipGroupList);
-			Set<Long> collect = vipGroupList.stream().map(e -> e.getId()).collect(Collectors.toSet());
-			Set<Integer> classGroupIds = classGroupDao.queryClassGroupIds(collect);
-			//解散群
-			for (Integer classGroupId : classGroupIds) {
-				imGroupService.cancel(classGroupId.longValue());
+			Set<Long> collect = vipGroupList.stream().filter(v->VipGroupStatusEnum.FINISHED.equals(v.getStatus())).map(e -> e.getId()).collect(Collectors.toSet());
+			if(!CollectionUtils.isEmpty(collect)){
+				Set<Integer> classGroupIds = classGroupDao.queryClassGroupIds(collect);
+				//解散群
+				for (Integer classGroupId : classGroupIds) {
+					imGroupService.cancel(classGroupId.longValue());
+				}
 			}
 		}
 		List<VipGroup> normalVipGroupList = vipGroupDao.queryNormalStatusList();

+ 28 - 0
mec-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml

@@ -2954,10 +2954,38 @@
         FROM course_schedule cs
         WHERE cs.group_type_ = #{groupType, typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
           AND cs.music_group_id_ = #{groupId}
+            AND cs.del_flag_ = 0
         ORDER BY CONCAT(cs.class_date_, ' ', cs.start_class_time_)
         LIMIT 1
     </select>
 
+    <select id="findLastCourseWithGroup" resultMap="CourseSchedule">
+        SELECT cs.id_,
+               cs.group_type_,
+               cs.music_group_id_,
+               cs.class_group_id_,
+               cs.status_,
+               cs.subsidy_,
+               cs.class_date_,
+               CONCAT(cs.class_date_, ' ', cs.start_class_time_) start_class_time_,
+               CONCAT(cs.class_date_, ' ', cs.end_class_time_)   end_class_time_,
+               cs.teacher_id_,
+               cs.actual_teacher_id_,
+               cs.create_time_,
+               cs.update_time_,
+               cs.teach_mode_,
+               cs.type_,
+               cs.name_,
+               cs.student_num_,
+               cs.leave_student_num_,
+               cs.schoole_id_
+        FROM course_schedule cs
+        WHERE cs.group_type_ = #{groupType, typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
+          AND cs.music_group_id_ = #{groupId}
+        ORDER BY CONCAT(cs.class_date_, ' ', cs.start_class_time_) DESC
+        LIMIT 1
+    </select>
+
     <select id="findClassGroupLastTeacher" resultMap="CourseSchedule">
         SELECT *
         FROM course_schedule

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

@@ -15,6 +15,7 @@
         <result column="user_id_" property="userId"/>
         <result column="username_" property="username"/>
         <result column="avatar_" property="avatar"/>
+        <result column="teacher_avatar_" property="teacherAvatar"/>
         <result column="subject_name_" property="subjectName"/>
         <result column="phone_" property="phone"/>
         <result column="teacher_id_" property="teacherId"/>
@@ -494,7 +495,7 @@
     <select id="findStudentAttendance" resultMap="StudentAttendance">
         SELECT cssp.id_,cssp.course_schedule_id_,cssp.user_id_,cssp.group_type_,cssp.music_group_id_,sa.sign_in_time_,sa.sign_out_time_,
                CASE WHEN sa.status_ IS NULL THEN 'TRUANT' ELSE sa.status_ END status_,
-        su.username_,su.phone_,su.avatar_,cs.teach_mode_,cs.type_ course_type_,o.name_ organ_name_,tu.real_name_ teacher_name_,tu.avatar_,
+        su.username_,su.phone_,su.avatar_,cs.teach_mode_,cs.type_ course_type_,o.name_ organ_name_,tu.real_name_ teacher_name_,tu.avatar_ teacher_avatar_,
         cs.name_ course_schedule_name_,cs.status_ course_status_,
         cs.actual_teacher_id_ teacher_id_,cs.class_date_ ,cs.start_class_time_,cs.end_class_time_ ,cs.new_course_id_,
         CASE WHEN sa.visit_flag_ IS NULL THEN 0 ELSE sa.visit_flag_ END visitFlag
@@ -510,7 +511,7 @@
     </select>
     <sql id="findStudentAttendanceSql">
         <where>
-            cs.status_ = 'OVER' AND cs.del_flag_ = 0 AND (cs.new_course_id_ IS NULL OR cs.new_course_id_ = cs.id_)
+            cs.del_flag_ = 0
             <if test="visitFlag != null">
                 <if test="visitFlag == 1">
                     AND sa.visit_flag_ = 1

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

@@ -289,7 +289,7 @@
     </select>
     <select id="countStudentCourseHomeworks" resultType="java.lang.Integer">
         SELECT COUNT(id_)
-        FROM course_schedule_student_payment
+        FROM student_course_homework
         WHERE course_schedule_id_ = #{search}
     </select>
     <resultMap id="StudentCourseHomeworkDtoMap" type="com.ym.mec.biz.dal.dto.StudentCourseHomeworkDto">
@@ -306,13 +306,13 @@
     <select id="findStudentCourseHomeworks" resultMap="StudentCourseHomeworkDtoMap">
         SELECT sch.id_ student_course_homework_id_,sch.attachments_,sch.is_replied_,sch.is_view_,
         sch.update_time_,cssp.user_id_,su.username_,su.phone_,s.name_ subject_name_
-        FROM course_schedule_student_payment cssp
-        LEFT JOIN student_course_homework sch ON sch.course_schedule_id_ = cssp.course_schedule_id_ AND cssp.user_id_ =
-        sch.user_id_ AND sch.status_ = 1
+        FROM student_course_homework sch
+        LEFT JOIN course_schedule_student_payment cssp ON sch.course_schedule_id_ = cssp.course_schedule_id_ AND cssp.user_id_ =
+        sch.user_id_
         LEFT JOIN sys_user su ON cssp.user_id_ = su.id_
         LEFT JOIN student_registration sr ON cssp.music_group_id_ = sr.music_group_id_ AND cssp.user_id_ = sr.user_id_
         LEFT JOIN `subject` s ON s.id_ = sr.actual_subject_id_
-        WHERE cssp.course_schedule_id_ = #{search}
+        WHERE sch.course_schedule_id_ = #{search}
         ORDER BY sch.id_ DESC
         <include refid="global.limit"/>
     </select>

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

@@ -209,9 +209,12 @@
             <if test="studentInstrumentId != null">
                 AND sr.student_instrument_id_ = #{studentInstrumentId}
             </if>
-            <if test="exemptionAmount != null">
+            <if test="hasExemptionAmount != null and hasExemptionAmount ==1">
                 AND sr.exemption_amount_ > #{exemptionAmount}
             </if>
+            <if test="hasExemptionAmount != null and hasExemptionAmount ==0">
+                AND sr.exemption_amount_ = 0
+            </if>
         </where>
     </sql>
     <select id="queryCount" resultType="int">

+ 3 - 8
mec-biz/src/main/resources/config/mybatis/TeacherAttendanceMapper.xml

@@ -217,6 +217,7 @@
         <result column="start_class_time_" property="startClassTime"/>
         <result column="class_date_" property="classDate"/>
         <result column="type_" property="type" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
+        <result column="course_status_" property="courseStatus" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
         <result column="name_" property="name"/>
         <result column="sign_in_status_" property="signInStatus"/>
         <result column="sign_out_status_" property="signOutStatus"/>
@@ -280,7 +281,7 @@
     </sql>
     <sql id="queryTeacherAttendancesCondition">
         <where>
-            cs.del_flag_ = 0 AND cs.status_ = 'OVER' AND (cs.new_course_id_ IS NULL OR cs.new_course_id_=cs.id_)
+            cs.del_flag_ = 0
             <if test="search != null and search != ''">
                 AND (su.id_ = #{search} OR su.real_name_ LIKE CONCAT('%',#{search},'%') OR cs.id_ = #{search} OR cs.name_ LIKE CONCAT('%',#{search},'%'))
             </if>
@@ -317,18 +318,12 @@
             <if test="jobNature != null">
                 AND t.job_nature_ = #{jobNature,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
             </if>
-            <if test="attendanceStatus == 'ERR_ATTENDANCE'">
-                AND (ta.sign_in_status_ = 0 OR ta.sign_out_status_ = 0) AND (ta.sign_in_time_ IS NOT NULL OR ta.sign_out_time_ IS NOT NULL) AND ta.dispose_content_ IS NULL
-            </if>
-            <if test="attendanceStatus == 'NO_ATTENDANCE'">
-                AND ta.sign_out_time_ IS NULL AND ta.sign_in_time_ IS NULL AND ta.dispose_content_ IS NULL
-            </if>
         </where>
     </sql>
 
     <select id="getTeacherPersonalAttendances" parameterType="map" resultMap="teacherPersonalAttendance">
         SELECT
-            cs.class_date_,cs.start_class_time_,cs.name_,cs.type_,
+            cs.class_date_,cs.start_class_time_,cs.name_,cs.type_,cs.status_ course_status_,
             IF(ta.sign_in_status_ IS NULL,3,ta.sign_in_status_) sign_in_status_,
             IF(ta.sign_out_status_ IS NULL,3,ta.sign_out_status_) sign_out_status_,
             ta.remark_,cs.id_,cs.end_class_time_

+ 10 - 7
mec-im/src/main/java/com/ym/controller/RoomController.java

@@ -53,6 +53,7 @@ public class RoomController{
 
     @RequestMapping(value = "/sendImPlayMidiMessage", method = RequestMethod.POST)
     public Object sendImPlayMidiMessage(@RequestBody PlayMidiMessageData playMidiMessageData) throws Exception {
+        log.info("sendImPlayMidiMessage: {}",JSONObject.toJSON(playMidiMessageData));
         roomService.sendImPlayMidiMessage(playMidiMessageData);
         return new BaseResponse<>();
     }
@@ -170,16 +171,10 @@ public class RoomController{
         return new BaseResponse<>(roomService.controlDevice(data));
     }
 
-    @ApiOperation(value = "学员麦克风、摄像头等开关批量控制")
-    @RequestMapping(value = "/device/batchControl", method = RequestMethod.POST)
-    public Object batchControlDevice(@RequestBody ReqDeviceControlData data)throws Exception {
-        log.info("batchControl: {}",JSONObject.toJSON(data));
-        return new BaseResponse<>(roomService.batchControlDevice(data));
-    }
-
     @ApiOperation(value = "学员伴奏下载状态回调")
     @RequestMapping(value = "adjustExamSong", method = RequestMethod.POST)
     public Object adjustExamSong(@RequestBody ExamSongData examSongData) throws Exception {
+        log.info("adjustExamSong: {}",JSONObject.toJSON(examSongData));
         roomService.adjustExamSong(examSongData.getRoomId(),examSongData.getStatus(),examSongData.getExamSongId());
         return new BaseResponse<>();
     }
@@ -191,9 +186,17 @@ public class RoomController{
         return new BaseResponse<>();
     }
 
+    @ApiOperation(value = "学员麦克风、摄像头等开关批量控制")
+    @RequestMapping(value = "/device/batchControl", method = RequestMethod.POST)
+    public Object batchControlDevice(@RequestBody ReqDeviceControlData data)throws Exception {
+        log.info("batchControl: {}",JSONObject.toJSON(data));
+        return new BaseResponse<>(roomService.batchControlDevice(data));
+    }
+
     @RequestMapping(value = "/device/sync", method = RequestMethod.POST)
     public Object syncDeviceState(@RequestBody ReqDeviceControlData data)
             throws Exception {
+        log.info("syncDeviceState: {}",JSONObject.toJSON(data));
         return new BaseResponse<>(roomService.syncDeviceState(data));
     }
 

+ 49 - 12
mec-web/src/main/java/com/ym/mec/web/controller/VipGroupManageController.java

@@ -2,17 +2,13 @@ package com.ym.mec.web.controller;
 
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
-import com.ym.mec.biz.dal.dao.ClassGroupDao;
-import com.ym.mec.biz.dal.dao.EmployeeDao;
-import com.ym.mec.biz.dal.dao.TeacherDao;
+import com.ym.mec.biz.dal.dao.*;
 import com.ym.mec.biz.dal.dto.ClassDateAdjustDto;
 import com.ym.mec.biz.dal.dto.VipGroupApplyBaseInfoDto;
 import com.ym.mec.biz.dal.dto.VipGroupApplyDto;
 import com.ym.mec.biz.dal.entity.*;
 import com.ym.mec.biz.dal.entity.StudentApplyRefunds.StudentApplyRefundsStatus;
-import com.ym.mec.biz.dal.enums.AuditStatusEnum;
-import com.ym.mec.biz.dal.enums.ClassGroupTypeEnum;
-import com.ym.mec.biz.dal.enums.VipGroupStatusEnum;
+import com.ym.mec.biz.dal.enums.*;
 import com.ym.mec.biz.dal.page.VipGroupAttendanceQueryInfo;
 import com.ym.mec.biz.dal.page.VipGroupQueryInfo;
 import com.ym.mec.biz.dal.page.VipGroupSalaryQueryInfo;
@@ -21,6 +17,7 @@ import com.ym.mec.biz.service.*;
 import com.ym.mec.common.controller.BaseController;
 import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.exception.BizException;
+import com.ym.mec.util.date.DateUtil;
 import com.yonge.log.model.AuditLogAnnotation;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -56,6 +53,12 @@ public class VipGroupManageController extends BaseController {
     private EmployeeDao employeeDao;
     @Autowired
     private ClassGroupDao classGroupDao;
+    @Autowired
+    private ImGroupMemberService imGroupMemberService;
+    @Autowired
+    private ImUserFriendService imUserFriendService;
+    @Autowired
+    private ImGroupService imGroupService;
 
     @Autowired
     private StudentApplyRefundsService studentApplyRefundsService;
@@ -64,6 +67,12 @@ public class VipGroupManageController extends BaseController {
     private StudentPaymentOrderService studentPaymentOrderService;
     @Autowired
     private CourseScheduleTeacherSalaryService courseScheduleTeacherSalaryService;
+    @Autowired
+    private ClassGroupStudentMapperDao classGroupStudentMapperDao;
+    @Autowired
+    private CourseScheduleDao courseScheduleDao;
+    @Autowired
+    private CourseScheduleTeacherSalaryDao courseScheduleTeacherSalaryDao;
 
     @GetMapping("/teacherSalarySettlement")
     public Object teacherSalarySettlement(){
@@ -80,22 +89,50 @@ public class VipGroupManageController extends BaseController {
             if(Objects.isNull(oldVipGroup)){
                 throw new BizException("此课程组不存在");
             }
-            if(!VipGroupStatusEnum.PROGRESS.equals(oldVipGroup.getStatus())&&!VipGroupStatusEnum.PAUSE.equals(oldVipGroup.getStatus())){
+            if(!VipGroupStatusEnum.PROGRESS.equals(oldVipGroup.getStatus())&&!VipGroupStatusEnum.FINISHED.equals(oldVipGroup.getStatus())&&!VipGroupStatusEnum.PAUSE.equals(oldVipGroup.getStatus())){
                 throw new BizException("此课程组状态暂不支持修改");
             }
         }
+        ClassGroup classGroup = classGroupDao.findByMusicGroupAndType(oldVipGroup.getId().toString(), ClassGroupTypeEnum.VIP.getCode());
+        if(Objects.isNull(classGroup)){
+            throw new BizException("课程信息错误");
+        }
         if(Objects.isNull(oldVipGroup.getVipGroupActivityId())){
-            if(VipGroupStatusEnum.PROGRESS.equals(vipGroup.getStatus())&&oldVipGroup.getStatus().getCode()>VipGroupStatusEnum.PROGRESS.getCode()){
+            if(VipGroupStatusEnum.PROGRESS.equals(vipGroup.getStatus())&&!VipGroupStatusEnum.FINISHED.equals(oldVipGroup.getStatus())&&oldVipGroup.getStatus().getCode()>VipGroupStatusEnum.PROGRESS.getCode()){
                 throw new BizException("此课程组状态暂不支持修改");
             }
-            ClassGroup classGroup = classGroupDao.findByMusicGroupAndType(oldVipGroup.getId().toString(), ClassGroupTypeEnum.VIP.getCode());
-            if(Objects.isNull(classGroup)){
-                throw new BizException("课程信息错误");
-            }
             if(classGroup.getStudentNum()<3){
                 throw new BizException("班级人数未达到3人");
             }
         }
+        Date now = new Date();
+        if(VipGroupStatusEnum.FINISHED.equals(oldVipGroup.getStatus())&&(vipGroup.getCoursesExpireDate().compareTo(now)>=0|| DateUtil.isSameDay(vipGroup.getCoursesExpireDate(), now))){
+            vipGroup.setStatus(VipGroupStatusEnum.PROGRESS);
+
+            Map<Integer,String> userRoleMap = new HashMap<>();
+            if(Objects.nonNull(vipGroup.getEducationalTeacherId())){
+                userRoleMap.put(vipGroup.getEducationalTeacherId(),"乐团主管");
+            }
+
+            CourseSchedule lastCourse = courseScheduleDao.findLastCourseWithGroup(vipGroup.getId().toString(), GroupType.VIP);
+            if(Objects.isNull(lastCourse)){
+                userRoleMap.put(vipGroup.getUserId(),"指导老师");
+            }else{
+                userRoleMap.put(lastCourse.getActualTeacherId(),"指导老师");
+            }
+
+            List<ClassGroupStudentMapper> classGroupStudents = classGroupStudentMapperDao.findByClassGroup(classGroup.getId());
+            if(!CollectionUtils.isEmpty(classGroupStudents)){
+                //生成学生单课缴费信息
+                for (ClassGroupStudentMapper classGroupStudent : classGroupStudents) {
+                    userRoleMap.put(classGroupStudent.getUserId(),null);
+                }
+            }
+
+            imGroupService.create(classGroup.getId().longValue(), null, classGroup.getName(), classGroup.getName(), vipGroup.getName(), null, null, GroupType.VIP.getCode());
+            imGroupMemberService.join(classGroup.getId().longValue(), userRoleMap);
+            imUserFriendService.refreshGroupImUserFriend(classGroup.getMusicGroupId(),classGroup.getGroupType());
+        }
         vipGroupService.update(vipGroup);
         return succeed();
     }