Browse Source

Merge remote-tracking branch 'origin/master'

周箭河 5 năm trước cách đây
mục cha
commit
91436efe4a
37 tập tin đã thay đổi với 1420 bổ sung69 xóa
  1. 0 1
      mec-auth/mec-auth-api/src/main/java/com/ym/mec/auth/api/entity/SysUser.java
  2. 50 0
      mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/web/controller/UserController.java
  3. 8 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleComplaintsDao.java
  4. 33 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleDao.java
  5. 8 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleEvaluateDao.java
  6. 15 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleStudentPaymentDao.java
  7. 7 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleTeacherSalaryDao.java
  8. 44 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/CourseScheduleComplaintsDto.java
  9. 10 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/CourseScheduleEndDto.java
  10. 85 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/CourseScheduleRateDto.java
  11. 22 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/ExportTeacherSalaryDto.java
  12. 37 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/TeacherRemarkCommitDto.java
  13. 20 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/CourseSchedule.java
  14. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/CourseScheduleEvaluate.java
  15. 4 4
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysUserCashAccount.java
  16. 10 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/Teacher.java
  17. 39 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/GroupCourseScheduleQueryInfo.java
  18. 27 0
      mec-biz/src/main/java/com/ym/mec/biz/service/CourseScheduleService.java
  19. 21 0
      mec-biz/src/main/java/com/ym/mec/biz/service/GroupCourseScheduleService.java
  20. 142 1
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleServiceImpl.java
  21. 4 4
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/GroupClassServiceImpl.java
  22. 45 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/GroupCourseScheduleServiceImpl.java
  23. 35 31
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/PracticeGroupServiceImpl.java
  24. 5 5
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/TeacherAttendanceServiceImpl.java
  25. 6 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/TeacherServiceImpl.java
  26. 12 0
      mec-biz/src/main/resources/config/mybatis/CourseScheduleComplaintsMapper.xml
  27. 9 3
      mec-biz/src/main/resources/config/mybatis/CourseScheduleEvaluateMapper.xml
  28. 87 4
      mec-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml
  29. 16 0
      mec-biz/src/main/resources/config/mybatis/CourseScheduleStudentPaymentMapper.xml
  30. 13 2
      mec-biz/src/main/resources/config/mybatis/CourseScheduleTeacherSalaryMapper.xml
  31. 1 1
      mec-biz/src/main/resources/config/mybatis/PracticeGroupMapper.xml
  32. 5 1
      mec-biz/src/main/resources/config/mybatis/TeacherMapper.xml
  33. 2 1
      mec-im/src/main/java/com/ym/service/Impl/RoomServiceImpl.java
  34. 27 5
      mec-teacher/src/main/java/com/ym/mec/teacher/controller/TeacherCourseScheduleController.java
  35. 141 0
      mec-util/src/main/java/com/ym/mec/util/idcard/IdcardInfoExtractor.java
  36. 414 0
      mec-util/src/main/java/com/ym/mec/util/idcard/IdcardValidator.java
  37. 5 5
      mec-web/src/main/java/com/ym/mec/web/controller/ExportController.java

+ 0 - 1
mec-auth/mec-auth-api/src/main/java/com/ym/mec/auth/api/entity/SysUser.java

@@ -36,7 +36,6 @@ public class SysUser implements Serializable{
 	@ApiModelProperty(value = "随机盐",required = false)
 	private String salt;
 
-	/** 简介 */
 	@ApiModelProperty(value = "手机号",required = false)
 	private String phone;
 

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

@@ -6,6 +6,7 @@ import com.ym.mec.auth.service.SysUserRoleService;
 import com.ym.mec.auth.service.SysUserService;
 import com.ym.mec.auth.web.controller.queryInfo.SysUserQueryInfo;
 import com.ym.mec.common.controller.BaseController;
+import com.ym.mec.common.exception.BizException;
 import com.ym.mec.common.security.AuthUser;
 import com.ym.mec.common.security.SecurityConstants;
 import com.ym.mec.common.security.SecurityUtils;
@@ -134,6 +135,34 @@ public class UserController extends BaseController {
 		}
 	}
 
+
+	@ApiOperation(value = "修改手机号")
+	@PostMapping(value = "/updatePhone")
+	public Object updatePhone(String oldPhone, String authCode, String newPhone) {
+		if (StringUtils.isEmpty(oldPhone) || StringUtils.isEmpty(authCode) || StringUtils.isEmpty(newPhone)) {
+			return failed("参数校验异常");
+		}
+		if(oldPhone.equals(newPhone)){
+			return failed("新旧手机号一致");
+		}
+		SysUser sysUser = sysUserService.queryByPhone(oldPhone);
+		if (sysUser == null) {
+			return failed("用户不存在");
+		}
+		SysUser newSysUser = sysUserService.queryByPhone(newPhone);
+		if (newSysUser != null) {
+			return failed("手机号被占用");
+		}
+		if (smsCodeService.verifyValidCode(newPhone, authCode)) {
+			sysUser.setPhone(newPhone);
+			sysUser.setUpdateTime(new Date());
+			sysUserService.update(sysUser);
+			return succeed();
+		} else {
+			return failed("验证码错误");
+		}
+	}
+
 	@ApiOperation(value = "修改密码")
 	@PostMapping(value = "/updatePassword2", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
 	@ApiImplicitParams({ @ApiImplicitParam(name = "mobile", value = "手机号", required = true, dataType = "String"),
@@ -171,6 +200,27 @@ public class UserController extends BaseController {
 		return failed();
 	}
 
+	@ApiOperation(value = "校验用户手机号和密码")
+	@GetMapping(value = "/checkUser")
+	public Object checkUser(String phone,String password) {
+		if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(password)){
+			throw new BizException("请录入用户名和密码");
+		}
+		AuthUser user = SecurityUtils.getUser();
+		if (user != null) {
+			SysUser sysUser = sysUserService.get(user.getUserId());
+			if(!sysUser.getPhone().equals(phone)){
+				return failed("手机号校验失败");
+			}
+			if(new BCryptPasswordEncoder().matches(password,sysUser.getPassword())){
+				return succeed();
+			}else {
+				return failed("密码校验失败");
+			}
+		}
+		return failed();
+	}
+
 	@ApiOperation(value = "获取用户角色列表")
 	@GetMapping("/getRole")
 	@PreAuthorize("@pcs.hasPermissions('user/getRole')")

+ 8 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleComplaintsDao.java

@@ -1,5 +1,6 @@
 package com.ym.mec.biz.dal.dao;
 
+import com.ym.mec.biz.dal.dto.CourseScheduleComplaintsDto;
 import com.ym.mec.biz.dal.entity.CourseScheduleComplaints;
 import com.ym.mec.common.dal.BaseDAO;
 import org.apache.ibatis.annotations.Param;
@@ -25,5 +26,11 @@ public interface CourseScheduleComplaintsDao extends BaseDAO<Long, CourseSchedul
      * @describe 根据课程编号批量获取投诉记录
      */
     List<CourseScheduleComplaints> findByCourseScheduleIds(@Param("ids") List<Long> ids);
-	
+
+    /**
+     * 获取课程的学员评价
+     * @param courseScheduleId
+     * @return
+     */
+    List<CourseScheduleComplaintsDto> findByCourseScheduleId(Long courseScheduleId);
 }

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

@@ -481,6 +481,16 @@ public interface CourseScheduleDao extends BaseDAO<Long, CourseSchedule> {
     List<TeacherClassCourseSchudeleDto> queryTeacherClassCourseSchedule(Map<String, Object> params);
 
     /**
+     * @describe 获取教师指定乐团下的课程
+     * @author Joburgess
+     * @date 2020/3/8
+     * @param params
+     * @return java.util.List<com.ym.mec.biz.dal.dto.TeacherClassCourseSchudeleDto>
+     */
+    List<TeacherClassCourseSchudeleDto> findTeacherGroupCourses(Map<String, Object> params);
+    int countTeacherGroupCourses(Map<String, Object> params);
+
+    /**
      * @param params:
      * @return java.util.List<com.ym.mec.biz.dal.dto.TeacherClassCourseSchudeleDto>
      * @describe 查询老师指定班级历史排课信息
@@ -1279,4 +1289,27 @@ public interface CourseScheduleDao extends BaseDAO<Long, CourseSchedule> {
      */
     List<GroupCourseTimesDto> findGroupsCourseTimesInfo(@Param("groupIds") List<String> groupIds,
                                                         @Param("groupType") GroupType groupType);
+
+    /**
+     * 获取当前课程声部
+     * @param courseScheduleId
+     * @return
+     */
+    String getSubjectNameById(Long courseScheduleId);
+
+    /**
+     * 教师端中间页网络教室课程进度列表
+     * @param groupId
+     * @param groupType
+     * @return
+     */
+    List<CourseScheduleRateDto> findCourseRate(@Param("groupId") String groupId, @Param("groupType") String groupType);
+
+    /**
+     * 获取最后一次已结束的课程
+     * @param groupId
+     * @param groupType
+     * @return
+     */
+    CourseSchedule getLastEndCourse(@Param("groupId") String groupId, @Param("groupType") String groupType);
 }

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

@@ -47,4 +47,12 @@ public interface CourseScheduleEvaluateDao extends BaseDAO<Long, CourseScheduleE
      * @return
      */
     CourseScheduleEvaluate findById(@Param("id") Integer id);
+
+    /**
+     * 获取当前课程教师的评价列表
+     * @param teacherId
+     * @param courseScheduleId
+     * @return
+     */
+    List<CourseScheduleEvaluate> findByCourseAndTeacher(@Param("teacherId") Integer teacherId, @Param("courseScheduleId") Long courseScheduleId);
 }

+ 15 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleStudentPaymentDao.java

@@ -1,5 +1,6 @@
 package com.ym.mec.biz.dal.dao;
 
+import com.ym.mec.biz.dal.dto.BasicUserDto;
 import com.ym.mec.biz.dal.dto.StudentAttendanceStatisticsResponse;
 import com.ym.mec.biz.dal.dto.VipGroupGiveCourseSortDto;
 import com.ym.mec.biz.dal.entity.CourseSchedule;
@@ -221,4 +222,18 @@ public interface CourseScheduleStudentPaymentDao extends BaseDAO<Long, CourseSch
      */
     int deleteByGroup(@Param("groupId") String groupId,
                       @Param("groupType")GroupType groupType);
+
+    /**
+     * 获取当前课程的学员列表
+     * @param courseScheduleId
+     * @return
+     */
+    List<BasicUserDto> findStudents(Long courseScheduleId);
+
+    /**
+     * 获取课程的学员编号列表
+     * @param courseScheduleIds
+     * @return
+     */
+    List<Map<Integer,String>> getStudentIdMap(@Param("courseScheduleIds") List<Long> courseScheduleIds);
 }

+ 7 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleTeacherSalaryDao.java

@@ -361,4 +361,11 @@ public interface CourseScheduleTeacherSalaryDao extends BaseDAO<Long, CourseSche
 	 * @return
 	 */
     Boolean isTeacher(@Param("groupId") Integer groupId, @Param("userId") Integer userId);
+
+	/**
+	 * 统计老师授课次数
+	 * @param userId
+	 * @return
+	 */
+	Integer countTeacherGiveLesson(Integer userId);
 }

+ 44 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/CourseScheduleComplaintsDto.java

@@ -0,0 +1,44 @@
+package com.ym.mec.biz.dal.dto;
+
+public class CourseScheduleComplaintsDto{
+
+    private String username;
+
+    private String reason;
+
+    private Integer score;
+
+    private String avatar;
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getReason() {
+        return reason;
+    }
+
+    public void setReason(String reason) {
+        this.reason = reason;
+    }
+
+    public Integer getScore() {
+        return score;
+    }
+
+    public void setScore(Integer score) {
+        this.score = score;
+    }
+
+    public String getAvatar() {
+        return avatar;
+    }
+
+    public void setAvatar(String avatar) {
+        this.avatar = avatar;
+    }
+}

+ 10 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/CourseScheduleEndDto.java

@@ -31,6 +31,16 @@ public class CourseScheduleEndDto extends CourseSchedule {
 
     private Date signOutTime;
 
+    private String studentId;
+
+    public String getStudentId() {
+        return studentId;
+    }
+
+    public void setStudentId(String studentId) {
+        this.studentId = studentId;
+    }
+
     public String getSubjectName() {
         return subjectName;
     }

+ 85 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/CourseScheduleRateDto.java

@@ -0,0 +1,85 @@
+package com.ym.mec.biz.dal.dto;
+
+
+public class CourseScheduleRateDto {
+    private String classDate;
+
+    private Long courseScheduleId;
+
+    private String startClassTime;
+
+    private String endClassTime;
+
+    private String teachingContent;
+
+    private String comment;
+
+    private String courseStatus;
+
+    private Boolean isDefault = false;
+
+    public Boolean getIsDefault() {
+        return isDefault;
+    }
+
+    public void setIsDefault(Boolean aDefault) {
+        isDefault = aDefault;
+    }
+
+    public Long getCourseScheduleId() {
+        return courseScheduleId;
+    }
+
+    public void setCourseScheduleId(Long courseScheduleId) {
+        this.courseScheduleId = courseScheduleId;
+    }
+
+    public String getCourseStatus() {
+        return courseStatus;
+    }
+
+    public void setCourseStatus(String courseStatus) {
+        this.courseStatus = courseStatus;
+    }
+
+    public String getClassDate() {
+        return classDate;
+    }
+
+    public void setClassDate(String classDate) {
+        this.classDate = classDate;
+    }
+
+    public String getStartClassTime() {
+        return startClassTime;
+    }
+
+    public void setStartClassTime(String startClassTime) {
+        this.startClassTime = startClassTime;
+    }
+
+    public String getEndClassTime() {
+        return endClassTime;
+    }
+
+    public void setEndClassTime(String endClassTime) {
+        this.endClassTime = endClassTime;
+    }
+
+    public String getTeachingContent() {
+        return teachingContent;
+    }
+
+    public void setTeachingContent(String teachingContent) {
+        this.teachingContent = teachingContent;
+    }
+
+    public String getComment() {
+        return comment;
+    }
+
+    public void setComment(String comment) {
+        this.comment = comment;
+    }
+}
+

+ 22 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/ExportTeacherSalaryDto.java

@@ -68,6 +68,12 @@ public class ExportTeacherSalaryDto{
     //签退时间
     private String signOutTime;
 
+    //签到时间
+    private String studentSignInTime;
+
+    //签退时间
+    private String studentSignOutTime;
+
     //主辅	上课地点	应到学员
     private String teacherRole;
 
@@ -86,6 +92,22 @@ public class ExportTeacherSalaryDto{
     //应到学员
     private int studentNum;
 
+    public String getStudentSignInTime() {
+        return studentSignInTime;
+    }
+
+    public void setStudentSignInTime(String studentSignInTime) {
+        this.studentSignInTime = studentSignInTime;
+    }
+
+    public String getStudentSignOutTime() {
+        return studentSignOutTime;
+    }
+
+    public void setStudentSignOutTime(String studentSignOutTime) {
+        this.studentSignOutTime = studentSignOutTime;
+    }
+
     public String getVipActiveName() {
         return vipActiveName;
     }

+ 37 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/TeacherRemarkCommitDto.java

@@ -0,0 +1,37 @@
+package com.ym.mec.biz.dal.dto;
+
+import com.ym.mec.biz.dal.entity.CourseScheduleEvaluate;
+
+import java.util.List;
+
+public class TeacherRemarkCommitDto {
+    private Long courseScheduleId;
+
+    private String teachingContent;
+
+    private List<CourseScheduleEvaluate> courseScheduleEvaluates;
+
+    public Long getCourseScheduleId() {
+        return courseScheduleId;
+    }
+
+    public void setCourseScheduleId(Long courseScheduleId) {
+        this.courseScheduleId = courseScheduleId;
+    }
+
+    public String getTeachingContent() {
+        return teachingContent;
+    }
+
+    public void setTeachingContent(String teachingContent) {
+        this.teachingContent = teachingContent;
+    }
+
+    public List<CourseScheduleEvaluate> getCourseScheduleEvaluates() {
+        return courseScheduleEvaluates;
+    }
+
+    public void setCourseScheduleEvaluates(List<CourseScheduleEvaluate> courseScheduleEvaluates) {
+        this.courseScheduleEvaluates = courseScheduleEvaluates;
+    }
+}

+ 20 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/CourseSchedule.java

@@ -145,6 +145,26 @@ public class CourseSchedule {
 
 	private YesOrNoEnum isCallNames;
 
+	private String teachingContent;
+
+	private String note;
+
+	public String getTeachingContent() {
+		return teachingContent;
+	}
+
+	public void setTeachingContent(String teachingContent) {
+		this.teachingContent = teachingContent;
+	}
+
+	public String getNote() {
+		return note;
+	}
+
+	public void setNote(String note) {
+		this.note = note;
+	}
+
 	public YesOrNoEnum getIsCallNames() {
 		return isCallNames;
 	}

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/CourseScheduleEvaluate.java

@@ -59,9 +59,20 @@ public class CourseScheduleEvaluate {
     @ApiModelProperty(value = "报告版本")
     private Integer version;
 
+    private String studentIdList;
+
     @ApiModelProperty(value = "报告提交或查看Url")
     private String reportLink;
 
+    public String getStudentIdList() {
+        return studentIdList;
+    }
+
+    public void setStudentIdList(String studentIdList) {
+        this.studentIdList = studentIdList;
+    }
+
+
 
     public Integer getIsPushed() {
         return isPushed;

+ 4 - 4
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysUserCashAccount.java

@@ -23,19 +23,19 @@ public class SysUserCashAccount {
 	
 	/** 账户可用余额 */
 	@ApiModelProperty(value = "账户可用余额",required = false)
-	private BigDecimal balance;
+	private BigDecimal balance = new BigDecimal(0);
 	
 	/** 冻结金额 */
 	@ApiModelProperty(value = "冻结金额",required = false)
-	private BigDecimal frozenAmount;
+	private BigDecimal frozenAmount = new BigDecimal(0);
 	
 	/** 保证金余额 */
 	@ApiModelProperty(value = "保证金余额",required = false)
-	private BigDecimal marginBalance;
+	private BigDecimal marginBalance = new BigDecimal(0);
 	
 	/** 课程余额余额 */
 	@ApiModelProperty(value = "课程余额",required = false)
-	private BigDecimal courseBalance;
+	private BigDecimal courseBalance = new BigDecimal(0);
 	
 	/** 账户状态(0,冻结,1,正常;-1,注销;) */
 	@ApiModelProperty(value = "账户状态",required = false)

+ 10 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/Teacher.java

@@ -112,6 +112,16 @@ public class Teacher extends SysUser {
 
 	private List<School> teacherSchools;
 
+	private Integer lectureNum;
+
+	public Integer getLectureNum() {
+		return lectureNum;
+	}
+
+	public void setLectureNum(Integer lectureNum) {
+		this.lectureNum = lectureNum;
+	}
+
 	public Integer getTeacherOrganId() {
 		return teacherOrganId;
 	}

+ 39 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/page/GroupCourseScheduleQueryInfo.java

@@ -0,0 +1,39 @@
+package com.ym.mec.biz.dal.page;
+
+import com.ym.mec.biz.dal.enums.GroupType;
+import com.ym.mec.common.page.QueryInfo;
+
+/**
+ * @Author Joburgess
+ * @Date 2020/3/8
+ */
+public class GroupCourseScheduleQueryInfo extends QueryInfo {
+
+    private Integer teacherId;
+    private String groupId;
+    private GroupType groupType;
+
+    public Integer getTeacherId() {
+        return teacherId;
+    }
+
+    public void setTeacherId(Integer teacherId) {
+        this.teacherId = teacherId;
+    }
+
+    public String getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(String groupId) {
+        this.groupId = groupId;
+    }
+
+    public GroupType getGroupType() {
+        return groupType;
+    }
+
+    public void setGroupType(GroupType groupType) {
+        this.groupType = groupType;
+    }
+}

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

@@ -450,4 +450,31 @@ public interface CourseScheduleService extends BaseService<Long, CourseSchedule>
 	 */
     void cleanAttendance(String courseScheduleIds);
 
+	/**
+	 * 教师端中间页课程评价数据获取
+	 * @param courseScheduleId
+	 * @return
+	 */
+	Object teacherCourseRemarkInfo(Long courseScheduleId);
+
+	/**
+	 * 教师端中间页课程评价数据提交
+	 * @param teacherRemarkCommitDto
+	 * @return
+	 */
+	void teacherCourseRemarkCommit(TeacherRemarkCommitDto teacherRemarkCommitDto);
+
+	/**
+	 * 教师端中间页网络教室头部详情
+	 * @param courseScheduleId
+	 * @return
+	 */
+    Object teacherCourseHeadInfo(Long courseScheduleId);
+
+	/**
+	 * 教师端中间页网络教室课程进度列表
+	 * @param courseScheduleId
+	 * @return
+	 */
+	Object teacherCourseRates(Long courseScheduleId);
 }

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

@@ -0,0 +1,21 @@
+package com.ym.mec.biz.service;
+
+import com.ym.mec.biz.dal.page.GroupCourseScheduleQueryInfo;
+import com.ym.mec.common.page.PageInfo;
+
+/**
+ * @Author Joburgess
+ * @Date 2020/3/8
+ */
+public interface GroupCourseScheduleService {
+
+    /**
+     * @describe 获取课程组下指定教师的课表
+     * @author Joburgess
+     * @date 2020/3/8
+     * @param groupCourseScheduleQueryInfo: 教师编号
+     * @return com.ym.mec.common.page.PageInfo
+     */
+    PageInfo findGroupCourses(GroupCourseScheduleQueryInfo groupCourseScheduleQueryInfo);
+
+}

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

@@ -59,6 +59,8 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
     @Autowired
     private CourseScheduleComplaintsDao courseScheduleComplaintsDao;
     @Autowired
+    private CourseScheduleEvaluateDao courseScheduleEvaluateDao;
+    @Autowired
     private SysConfigDao sysConfigDao;
     @Autowired
     private StudentAttendanceDao studentAttendanceDao;
@@ -2558,7 +2560,7 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 						if (teacherDefaultPracticeGroupSalaryList != null && teacherDefaultPracticeGroupSalaryList.size() > 0) {
 							ts.setExpectSalary(teacherDefaultPracticeGroupSalaryList.get(0).getMainTeacherSalary());
 						} else {
-							ts.setExpectSalary(new BigDecimal(30));
+							throw new BizException("请设置老师 的网管课课酬");
 						}
 					}
 					insertCourseScheduleTeacherSalaryList.add(ts);
@@ -3523,6 +3525,7 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
             List<TeacherAttendance> teacherAttendances = teacherAttendanceDao.findTeacherIdByCourseSchedule(courseScheduleIds);
             Map<Long, List<TeacherAttendance>> courseTeacherAttendanceMap = teacherAttendances.stream().collect(Collectors.groupingBy(TeacherAttendance::getCourseScheduleId));
             Map<Integer, Long> studentNumCourseMap = MapUtil.convertIntegerMap(studentAttendanceDao.countStudentAttendancesByCourses(courseScheduleIds));
+            Map<Long, String> studentIdMap = MapUtil.convertIntegerMap(courseScheduleStudentPaymentDao.getStudentIdMap(courseScheduleIds));
             List<Group> groups=new ArrayList<>();
             groups.add(null);
             List<Integer> teacherIds=new ArrayList<>();
@@ -3550,6 +3553,7 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
                 }
                 result.setTeacherName(nameIdMap.get(result.getActualTeacherId()));
                 result.setSubjectName(classGroupSubjectNameMap.get(result.getId()));
+                result.setStudentId(studentIdMap.get(result.getId()));
                 List<TeacherAttendance> courseTeacherAttendances = courseTeacherAttendanceMap.get(result.getId());
                 if(!CollectionUtils.isEmpty(courseTeacherAttendances)){
                     TeacherAttendance teacherAttendance=courseTeacherAttendances.get(0);
@@ -3838,4 +3842,141 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
         teacherAttendanceDao.batchCleanCourseTeacherSignInfo(courseScheduleId);
         studentAttendanceDao.deleteByCourseSchedules(courseScheduleId);
     }
+
+	@Override
+	public Object teacherCourseRemarkInfo(Long courseScheduleId) {
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if (null == user) {
+			throw new BizException("获取用户信息失败");
+		}
+		if(courseScheduleId == null){
+			throw new BizException("参数校验失败");
+		}
+		Map<String,Object> resultMap = new HashMap<>(7);
+		//获取课程详情
+		CourseSchedule schedule = courseScheduleDao.get(courseScheduleId);
+		resultMap.put("courseScheduleName",schedule.getName());
+		resultMap.put("courseScheduleClassDate",schedule.getClassDate());
+		resultMap.put("courseScheduleStartClassTime",schedule.getStartClassTime());
+		resultMap.put("courseScheduleEndClassTime",schedule.getEndClassTime());
+		resultMap.put("courseScheduleContent",schedule.getTeachingContent());
+		//获取当前课程的声部
+		resultMap.put("subjectName",courseScheduleDao.getSubjectNameById(courseScheduleId));
+		//获取学员评论详情
+		resultMap.put("studentRemark",courseScheduleComplaintsDao.findByCourseScheduleId(courseScheduleId));
+		//获取当前课程的学员列表
+		resultMap.put("students",courseScheduleStudentPaymentDao.findStudents(courseScheduleId));
+		//获取当前课程老师的评价列表
+		resultMap.put("teacherRemark",courseScheduleEvaluateDao.findByCourseAndTeacher(user.getId(),courseScheduleId));
+		return resultMap;
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public void teacherCourseRemarkCommit(TeacherRemarkCommitDto teacherRemarkCommitDt) {
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if (null == user) {
+			throw new BizException("获取用户信息失败");
+		}
+		Long courseScheduleId = teacherRemarkCommitDt.getCourseScheduleId();
+		CourseSchedule schedule = courseScheduleDao.get(courseScheduleId);
+		if(schedule == null){
+			throw new BizException("课程不存在");
+		}
+		if(StringUtils.isNotEmpty(schedule.getTeachingContent())){
+			throw new BizException("您已提交过课程评价,请勿重复提交");
+		}
+		//是否提交过评论
+		List<CourseScheduleEvaluate> byCourseAndTeacher = courseScheduleEvaluateDao.findByCourseAndTeacher(user.getId(), courseScheduleId);
+		if(byCourseAndTeacher != null && byCourseAndTeacher.size() > 0){
+			throw new BizException("您已提交过课程评价,请勿重复提交");
+		}
+		//修改教学内容
+		if(StringUtils.isNotEmpty(teacherRemarkCommitDt.getTeachingContent())){
+			schedule.setTeachingContent(teacherRemarkCommitDt.getTeachingContent());
+			schedule.setUpdateTime(new Date());
+			courseScheduleDao.update(schedule);
+		}
+		List<CourseScheduleEvaluate> courseScheduleEvaluates = teacherRemarkCommitDt.getCourseScheduleEvaluates();
+		if(courseScheduleEvaluates != null || courseScheduleEvaluates.size() > 0){
+			courseScheduleEvaluates.forEach(e->{
+				e.setMusicGroupId(schedule.getMusicGroupId());
+				e.setClassGroupId(schedule.getClassGroupId());
+				e.setTeacherId(user.getId());
+				e.setCourseScheduleId(courseScheduleId);
+				e.setIsPushed(0);
+				courseScheduleEvaluateDao.insert(e);
+			});
+		}
+	}
+
+	@Override
+	public Object teacherCourseHeadInfo(Long courseScheduleId) {
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if (null == user) {
+			throw new BizException("获取用户信息失败");
+		}
+		CourseSchedule schedule = courseScheduleDao.get(courseScheduleId);
+		if(schedule == null){
+			throw new BizException("课程不存在");
+		}
+		GroupType groupType = schedule.getGroupType();
+		Map<String,Object> resultMap = new HashMap<>(8);
+		Teacher teacher;
+		switch (groupType){
+			case PRACTICE:
+				PracticeGroup practiceGroup = practiceGroupDao.get(Long.parseLong(schedule.getMusicGroupId()));
+				resultMap.put("groupName",practiceGroup.getName());
+				resultMap.put("startTime",practiceGroup.getCoursesStartDate());
+				resultMap.put("endTime",practiceGroup.getCoursesExpireDate());
+				resultMap.put("groupStatus",practiceGroup.getGroupStatus().getCode());
+				teacher = teacherDao.get(practiceGroup.getUserId());
+				resultMap.put("groupTeacher",teacher.getRealName());
+				resultMap.put("teacherIntroduction",teacher.getIntroduction());
+				resultMap.put("teacherAvatar",teacher.getAvatar());
+				//统计授课次数
+				resultMap.put("teacherGiveLesson",courseScheduleTeacherSalaryDao.countTeacherGiveLesson(practiceGroup.getUserId()));
+				break;
+			case VIP:
+				VipGroup vipGroup = vipGroupDao.get(Long.parseLong(schedule.getMusicGroupId()));
+				resultMap.put("groupName",vipGroup.getName());
+				resultMap.put("startTime",vipGroup.getCourseStartDate());
+				resultMap.put("endTime",vipGroup.getCoursesExpireDate());
+				resultMap.put("groupStatus",vipGroup.getStatus().getCode());
+				teacher = teacherDao.get(vipGroup.getUserId());
+				resultMap.put("groupTeacher",teacher.getRealName());
+				resultMap.put("teacherIntroduction",teacher.getIntroduction());
+				resultMap.put("teacherAvatar",teacher.getAvatar());
+				//统计授课次数
+				resultMap.put("teacherGiveLesson",courseScheduleTeacherSalaryDao.countTeacherGiveLesson(vipGroup.getUserId()));
+				break;
+			default:
+				throw new BizException("课程类型错误");
+		}
+		return resultMap;
+	}
+
+	@Override
+	public Object teacherCourseRates(Long courseScheduleId) {
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if (null == user) {
+			throw new BizException("获取用户信息失败");
+		}
+		CourseSchedule schedule = courseScheduleDao.get(courseScheduleId);
+		if(schedule == null){
+			throw new BizException("课程不存在");
+		}
+		//获取课程列表
+		List<CourseScheduleRateDto> courseScheduleRateDtos = courseScheduleDao.findCourseRate(schedule.getMusicGroupId(),schedule.getGroupType().getCode());
+		//获取最近一次已结束的课程
+		CourseSchedule courseSchedule = courseScheduleDao.getLastEndCourse(schedule.getMusicGroupId(),schedule.getGroupType().getCode());
+		//标记当前课程的上一节课
+		for (CourseScheduleRateDto e:courseScheduleRateDtos) {
+			if(e.getCourseScheduleId().equals(courseSchedule.getId())){
+				e.setIsDefault(true);
+				break;
+			}
+		}
+		return courseScheduleRateDtos;
+	}
 }

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

@@ -125,16 +125,16 @@ public class GroupClassServiceImpl implements GroupClassService {
                 throw new BizException("指定的课程组不存在");
             }
             List<StudentPaymentOrder> orders = studentPaymentOrderDao.findOrderByGroup(practiceGroup.getId().toString(), GroupType.PRACTICE, DealStatusEnum.SUCCESS);
-            if(CollectionUtils.isEmpty(orders)){
+            if(CollectionUtils.isEmpty(orders)&&Objects.nonNull(refundAmount)){
                 throw new BizException("未获取到订单");
             }
-            if(refundAmount.compareTo(orders.get(0).getExpectAmount())>0){
-                throw new BizException("退款不可大于购买金额");
-            }
             if(!practiceGroup.getGroupStatus().equals(GroupStatusEnum.NORMAL)||practiceGroup.getCoursesExpireDate().before(now)){
                 throw new BizException("当前课程组不可关闭");
             }
             if(Objects.nonNull(refundAmount)&&refundAmount.compareTo(BigDecimal.ZERO)>0){
+                if(refundAmount.compareTo(orders.get(0).getExpectAmount())>0){
+                    throw new BizException("退款不可大于购买金额");
+                }
                 sysUserCashAccountService.updateBalance(practiceGroup.getStudentId(), refundAmount, PlatformCashAccountDetailTypeEnum.REFUNDS, "后团关闭网管课");
             }
             cleanGroupInfo(groupId.toString(), GroupType.PRACTICE);

+ 45 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/GroupCourseScheduleServiceImpl.java

@@ -0,0 +1,45 @@
+package com.ym.mec.biz.service.impl;
+
+import com.ym.mec.biz.dal.dao.CourseScheduleDao;
+import com.ym.mec.biz.dal.page.GroupCourseScheduleQueryInfo;
+import com.ym.mec.biz.service.GroupCourseScheduleService;
+import com.ym.mec.common.page.PageInfo;
+import com.ym.mec.util.collection.MapUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Author Joburgess
+ * @Date 2020/3/8
+ */
+@Service
+public class GroupCourseScheduleServiceImpl implements GroupCourseScheduleService {
+
+    @Autowired
+    private CourseScheduleDao courseScheduleDao;
+
+    @Override
+    public PageInfo findGroupCourses(GroupCourseScheduleQueryInfo queryInfo) {
+        PageInfo pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
+        Map<String, Object> params = new HashMap<>();
+        MapUtil.populateMap(params, queryInfo);
+
+        List dataList = null;
+        int count = courseScheduleDao.countTeacherGroupCourses(params);
+        if (count > 0) {
+            pageInfo.setTotal(count);
+            params.put("offset", pageInfo.getOffset());
+            dataList = courseScheduleDao.findTeacherGroupCourses(params);
+        }
+        if (count == 0) {
+            dataList = new ArrayList<>();
+        }
+        pageInfo.setRows(dataList);
+        return pageInfo;
+    }
+}

+ 35 - 31
mec-biz/src/main/java/com/ym/mec/biz/service/impl/PracticeGroupServiceImpl.java

@@ -214,16 +214,16 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
     @Override
     public Map<String, Object> checkCanApplyFreePracticeGroup(Integer userId) {
         Map<String,Object> result=new HashMap<>();
-        int recordNum = practiceLessonApplyDao.checkUserIsApply(userId);
-        LocalDateTime now=LocalDateTime.now();
-        if(recordNum>0){
-            LocalDateTime applyExpireDateTime=LocalDateTime.parse("2020-02-29 00:00:00", DateUtil.dateTimeFormatter);
-            result.put("canApply", now.compareTo(applyExpireDateTime)<=0?1:0);
-        }else{
-            LocalDateTime applyExpireDateTime=LocalDateTime.parse("2020-02-22 20:00:00", DateUtil.dateTimeFormatter);
-            result.put("canApply", now.compareTo(applyExpireDateTime)<=0?1:0);
-        }
-
+//        int recordNum = practiceLessonApplyDao.checkUserIsApply(userId);
+//        LocalDateTime now=LocalDateTime.now();
+//        if(recordNum>0){
+//            LocalDateTime applyExpireDateTime=LocalDateTime.parse("2020-02-29 00:00:00", DateUtil.dateTimeFormatter);
+//            result.put("canApply", now.compareTo(applyExpireDateTime)<=0?1:0);
+//        }else{
+//            LocalDateTime applyExpireDateTime=LocalDateTime.parse("2020-02-22 20:00:00", DateUtil.dateTimeFormatter);
+//            result.put("canApply", now.compareTo(applyExpireDateTime)<=0?1:0);
+//        }
+        result.put("canApply", 1);
         return result;
     }
 
@@ -1655,24 +1655,24 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
             return result;
         }
 
-        int recordNum = practiceLessonApplyDao.checkUserIsApply(practiceGroup.getStudentId());
-        if(recordNum>0){
-            LocalDateTime nowDateTime=LocalDateTime.now();
-            LocalDateTime applyExpireDateTime=LocalDateTime.parse("2020-02-29 00:00:00", DateUtil.dateTimeFormatter);
-            if(nowDateTime.compareTo(applyExpireDateTime)>0){
-                result.put("status", "APPLY_DATE_OVERFLOW");
-                result.put("info", "预约失败,超出可预约时间范围。");
-                return result;
-            }
-        }else{
-            LocalDateTime nowDateTime=LocalDateTime.now();
-            LocalDateTime applyExpireDateTime=LocalDateTime.parse("2020-02-22 20:00:00", DateUtil.dateTimeFormatter);
-            if(nowDateTime.compareTo(applyExpireDateTime)>0){
-                result.put("status", "APPLY_DATE_OVERFLOW");
-                result.put("info", "预约失败,超出可预约时间范围。");
-                return result;
-            }
-        }
+//        int recordNum = practiceLessonApplyDao.checkUserIsApply(practiceGroup.getStudentId());
+//        if(recordNum>0){
+//            LocalDateTime nowDateTime=LocalDateTime.now();
+//            LocalDateTime applyExpireDateTime=LocalDateTime.parse("2020-02-29 00:00:00", DateUtil.dateTimeFormatter);
+//            if(nowDateTime.compareTo(applyExpireDateTime)>0){
+//                result.put("status", "APPLY_DATE_OVERFLOW");
+//                result.put("info", "预约失败,超出可预约时间范围。");
+//                return result;
+//            }
+//        }else{
+//            LocalDateTime nowDateTime=LocalDateTime.now();
+//            LocalDateTime applyExpireDateTime=LocalDateTime.parse("2020-02-22 20:00:00", DateUtil.dateTimeFormatter);
+//            if(nowDateTime.compareTo(applyExpireDateTime)>0){
+//                result.put("status", "APPLY_DATE_OVERFLOW");
+//                result.put("info", "预约失败,超出可预约时间范围。");
+//                return result;
+//            }
+//        }
 
         List<Date> allCourseDates = new ArrayList<>();
         allCourseDates.add(practiceGroup.getFirstCourseTime());
@@ -1861,8 +1861,8 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
         classGroupTeacherSalary.setClassGroupId(classGroup.getId());
         classGroupTeacherSalary.setTeacherRole(TeachTypeEnum.BISHOP);
         classGroupTeacherSalary.setUserId(practiceGroup.getUserId());
-        classGroupTeacherSalary.setSalary(new BigDecimal(practiceCourseSalaryConfig.getParanValue(Integer.class)));
-        classGroupTeacherSalary.setOnlineClassesSalary(new BigDecimal(practiceCourseSalaryConfig.getParanValue(Integer.class)));
+        classGroupTeacherSalary.setSalary(new BigDecimal(practiceCourseSalaryConfig.getParanValue()));
+        classGroupTeacherSalary.setOnlineClassesSalary(new BigDecimal(practiceCourseSalaryConfig.getParanValue()));
         classGroupTeacherSalary.setGroupType(GroupType.PRACTICE);
         classGroupTeacherSalary.setCreateTime(now);
         classGroupTeacherSalary.setUpdateTime(now);
@@ -3083,8 +3083,9 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
         sysUserExpendCashAccountDetail.setBalance(sysUserCashAccount.getBalance());
         sysUserExpendCashAccountDetail.setAttribute(order.getTransNo());
         sysUserExpendCashAccountDetail.setChannel(studentPaymentOrder.getPaymentChannel());
+
         if(studentPaymentOrder.getComAmount() != null){
-            sysUserExpendCashAccountDetail.setComAmount(studentPaymentOrder.getComAmount().negate());
+            sysUserIncomeCashAccountDetail.setComAmount(studentPaymentOrder.getComAmount().negate());
         }
         if(studentPaymentOrder.getPerAmount() != null){
             sysUserExpendCashAccountDetail.setPerAmount(studentPaymentOrder.getPerAmount().negate());
@@ -3098,6 +3099,9 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
             order.setVersion(order.getVersion()+1);
             order.setMemo("支付成功,在重新支付时,用户选择取消");
             studentPaymentOrderDao.update(order);
+
+            sysUserCashAccountService.updateBalance(order.getUserId(), order.getActualAmount(), PlatformCashAccountDetailTypeEnum.REFUNDS, "支付成功,用户取消,退还余额");
+
             return;
         }
         ClassGroup classGroup = classGroupDao.findByMusicGroupAndType(order.getMusicGroupId(), GroupType.PRACTICE.getCode());

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

@@ -268,7 +268,7 @@ public class TeacherAttendanceServiceImpl extends BaseServiceImpl<Long, TeacherA
 		Date classStartDateTime = DateUtil.stringToDate(classDate + " " + startClassTime, DateUtil.EXPANDED_DATE_TIME_FORMAT);
 		Date classEndDateTime = DateUtil.stringToDate(classDate + " " + endClassTime, DateUtil.EXPANDED_DATE_TIME_FORMAT);
 //		Date classEndDateAdd60Minutes = DateUtil.addMinutes(classEndDateTime, 60);
-		Date classEndDateCut10Minutes = DateUtil.addMinutes(classEndDateTime, -10);
+//		Date classEndDateCut10Minutes = DateUtil.addMinutes(classEndDateTime, -10);
 //		Date add20Minutes = DateUtil.addMinutes(classStartDateTime, advanceSignMinutes * -1);
 //		Date add60Minutes = DateUtil.addMinutes(classStartDateTime, -60);
 		//签到
@@ -287,10 +287,10 @@ public class TeacherAttendanceServiceImpl extends BaseServiceImpl<Long, TeacherA
 			boolean isSign = false;
 			if(yesOrNoEnum == YesOrNoEnum.YES){
 				isSign = true;
-			}else if(DateUtil.minutesBetween(date,classStartDateTime) >= 0){
+			}else if(DateUtil.minutesBetween(date,classStartDateTime) > 0){
 				//正常签到范围(开始之前)
 				isSign = true;
-			}else if(DateUtil.minutesBetween(classStartDateTime,date) > 0){
+			}else if(DateUtil.minutesBetween(classStartDateTime,date) >= 0){
 				//异常签到范围(开始之后)
 				isSign = true;
 				teacherAttendance.setSignInStatus(YesOrNoEnum.NO);
@@ -310,7 +310,7 @@ public class TeacherAttendanceServiceImpl extends BaseServiceImpl<Long, TeacherA
 		}
 		//签退
 		if(SignStatusEnum.SIGN_OUT.equals(signStatus)){
-			if(DateUtil.minutesBetween(classEndDateCut10Minutes,date) >= 0){
+			if(DateUtil.minutesBetween(classEndDateTime,date) >= 0){
 				teacherAttendance.setSignOutStatus(YesOrNoEnum.YES);
 				List<CourseSchedule> courseSchedules = new ArrayList<>();
 				CourseSchedule cs = courseSchedule;
@@ -356,7 +356,7 @@ public class TeacherAttendanceServiceImpl extends BaseServiceImpl<Long, TeacherA
 					}
 				}
 				//异常签退时间段,并且没有签退状态
-			}else if(DateUtil.minutesBetween(classStartDateTime,date) >= 0 && DateUtil.minutesBetween(date,classEndDateCut10Minutes) > 0){
+			}else if(DateUtil.minutesBetween(classStartDateTime,date) >= 0 && DateUtil.minutesBetween(date,classEndDateTime) > 0){
 				teacherAttendance.setSignOutStatus(YesOrNoEnum.NO);
 			}else {
 				return;

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

@@ -19,6 +19,7 @@ import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.service.impl.BaseServiceImpl;
 import com.ym.mec.im.ImFeignService;
 import com.ym.mec.util.collection.MapUtil;
+import com.ym.mec.util.idcard.IdcardValidator;
 
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -462,6 +463,11 @@ public class TeacherServiceImpl extends BaseServiceImpl<Integer, Teacher>  imple
 				&& StringUtils.isNotBlank(teacher.getIdcardHandImg())) {
 			throw new BizException("已实名认证,不能重复操作");
 		}
+		
+		IdcardValidator validator = new IdcardValidator();
+		if (validator.isValidatedAllIdcard(idcardNo) == false) {
+			throw new BizException("身份证校验失败");
+		}
 
 		Date date = new Date();
 

+ 12 - 0
mec-biz/src/main/resources/config/mybatis/CourseScheduleComplaintsMapper.xml

@@ -106,4 +106,16 @@
 		</foreach>
 		AND status_!='REJECT' AND score_ &lt;= 2
 	</select>
+	<resultMap id="CourseScheduleComplaintsDtoMap" type="com.ym.mec.biz.dal.dto.CourseScheduleComplaintsDto">
+		<result property="username" column="username_"/>
+		<result property="reason" column="reason_"/>
+		<result property="score" column="score_"/>
+		<result property="avatar" column="avatar_"/>
+	</resultMap>
+	<select id="findByCourseScheduleId" resultMap="CourseScheduleComplaintsDtoMap">
+		SELECT su.username_,csc.reason_,csc.score_,su.avatar_
+		FROM course_schedule_complaints csc
+		LEFT JOIN sys_user su ON su.id_ = csc.user_id_
+		WHERE csc.course_schedule_id_ = #{courseScheduleId}
+	</select>
 </mapper>

+ 9 - 3
mec-biz/src/main/resources/config/mybatis/CourseScheduleEvaluateMapper.xml

@@ -18,15 +18,16 @@
         <result column="song_" jdbcType="VARCHAR" property="song"/>
         <result column="teaching_material_" jdbcType="VARCHAR" property="teachingMaterial"/>
         <result column="version_" jdbcType="INTEGER" property="version"/>
+		<result column="student_id_list_" jdbcType="VARCHAR" property="studentIdList"/>
     </resultMap>
     <insert id="insert" parameterType="com.ym.mec.biz.dal.entity.CourseScheduleEvaluate" useGeneratedKeys="true"
             keyColumn="id" keyProperty="id">
-        insert into course_schedule_evaluate (music_group_id_, class_group_id_, course_schedule_id_,
+        INSERT INTO course_schedule_evaluate (music_group_id_, class_group_id_, course_schedule_id_,
                                               teacher_id_, item_, comment_,
-                                              create_time_,version_)
+                                              create_time_,student_id_list_,version_)
         values (#{musicGroupId,jdbcType=VARCHAR}, #{classGroupId,jdbcType=INTEGER}, #{courseScheduleId,jdbcType=BIGINT},
                 #{teacherId,jdbcType=INTEGER}, #{item,jdbcType=VARCHAR}, #{comment,jdbcType=LONGVARCHAR},
-                #{createTime,jdbcType=TIMESTAMP},#{version,jdbcType=INTEGER})
+                NOW(),#{studentIdList},#{version,jdbcType=INTEGER})
     </insert>
 
     <update id="update" parameterType="com.ym.mec.biz.dal.entity.CourseScheduleEvaluate">
@@ -126,4 +127,9 @@
         LEFT JOIN subject s on s.id_ = pg.subject_id_
         WHERE cse.id_ = #{id}
     </select>
+
+    <select id="findByCourseAndTeacher" resultMap="CourseScheduleEvaluate">
+        SELECT * FROM course_schedule_evaluate cse
+        WHERE cse.teacher_id_ = #{teacherId} AND cse.course_schedule_id_ = #{courseScheduleId}
+    </select>
 </mapper>

+ 87 - 4
mec-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml

@@ -31,6 +31,8 @@
         <result column="schoole_name_" property="schoolName"/>
         <result column="class_group_name_" property="classGroupName"/>
         <result column="class_group_type_" property="classGroupType"/>
+        <result column="teaching_content_" property="teachingContent"/>
+        <result column="note_" property="note"/>
     </resultMap>
 
     <resultMap type="com.ym.mec.biz.dal.dto.Mapper" id="Mapper">
@@ -122,6 +124,8 @@
                name_,
                student_num_,
                leave_student_num_,
+               teaching_content_,
+               note_,
                schoole_id_
         FROM course_schedule
         WHERE id_ = #{id}
@@ -143,17 +147,25 @@
         </selectKey>
         -->
         INSERT INTO course_schedule
-        (id_,group_type_,music_group_id_,class_group_id_,status_,subsidy_,class_date_,start_class_time_,end_class_time_,teacher_id_,actual_teacher_id_,create_time_,update_time_,type_,name_,teach_mode_,student_num_,leave_student_num_,schoole_id_,is_lock_)
-        VALUES(#{id},#{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{musicGroupId},#{classGroupId},#{status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{subsidy},#{classDate},#{startClassTime},#{endClassTime},#{teacherId},#{teacherId},now(),now(),#{type,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{name},#{teachMode,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{studentNum},#{leaveStudentNum},#{schoolId},#{isLock})
+        (id_,group_type_,music_group_id_,class_group_id_,status_,subsidy_,class_date_,start_class_time_,end_class_time_,teacher_id_,actual_teacher_id_,create_time_,update_time_,type_,name_,teach_mode_,student_num_,leave_student_num_,schoole_id_,is_lock_,note_,teaching_content_)
+        VALUES(#{id},#{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{musicGroupId},#{classGroupId},#{status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{subsidy},#{classDate},#{startClassTime},#{endClassTime},#{teacherId},#{teacherId},now(),now(),
+        #{type,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{name},#{teachMode,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{studentNum},#{leaveStudentNum},#{schoolId},#{isLock},#{note},#{teachingContent})
     </insert>
 
     <insert id="batchAddCourseSchedules" parameterType="java.util.List" useGeneratedKeys="true" keyColumn="id"
             keyProperty="id">
         INSERT INTO course_schedule
-        (group_type_,music_group_id_,class_group_id_,status_,subsidy_,class_date_,start_class_time_,end_class_time_,teacher_id_,actual_teacher_id_,create_time_,update_time_,type_,name_,teach_mode_,student_num_,leave_student_num_,schoole_id_,is_lock_)
+        (group_type_,music_group_id_,class_group_id_,status_,subsidy_,class_date_,start_class_time_,end_class_time_,
+        teacher_id_,actual_teacher_id_,create_time_,update_time_,type_,name_,teach_mode_,student_num_,leave_student_num_,
+        schoole_id_,is_lock_,note_,teaching_content_)
         VALUE
         <foreach collection="list" item="course" separator=",">
-            (#{course.groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{course.musicGroupId},#{course.classGroupId},#{course.status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{course.subsidy},#{course.classDate},#{course.startClassTime},#{course.endClassTime},#{course.teacherId},#{course.teacherId},now(),now(),#{course.type,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{course.name},#{course.teachMode,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{course.studentNum},#{course.leaveStudentNum},#{course.schoolId},#{course.isLock})
+            (#{course.groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{course.musicGroupId},
+            #{course.classGroupId},#{course.status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+            #{course.subsidy},#{course.classDate},#{course.startClassTime},#{course.endClassTime},#{course.teacherId},
+            #{course.teacherId},now(),now(),#{course.type,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+            #{course.name},#{course.teachMode,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{course.studentNum},
+            #{course.leaveStudentNum},#{course.schoolId},#{course.isLock},#{course.note},#{course.teachingContent})
         </foreach>
     </insert>
 
@@ -161,6 +173,12 @@
     <update id="update" parameterType="com.ym.mec.biz.dal.entity.CourseSchedule">
         UPDATE course_schedule
         <set>
+            <if test="note != null">
+                note_ = #{note},
+            </if>
+            <if test="teachingContent != null">
+                teaching_content_ = #{teachingContent},
+            </if>
             <if test="classDate != null">
                 class_date_ = #{classDate},
             </if>
@@ -1205,6 +1223,41 @@
         <include refid="global.limit"/>
     </select>
 
+    <sql id="teacherGroupCourseQueryCondition">
+        <where>
+            cs.actual_teacher_id_=#{teacherId}
+            AND cs.music_group_id_ = #{groupId}
+            AND cs.group_type_ = #{groupType}
+        </where>
+    </sql>
+
+    <select id="findTeacherGroupCourses" resultMap="teacherClassCourseSchedule">
+        SELECT
+            cs.class_group_id_,
+            cs.id_ course_schedule_id_,
+            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.name_ course_schedule_name_,
+            cs.student_num_,
+            cs.leave_student_num_,
+            cs.type_,
+            cs.status_,
+            cs.actual_teacher_id_,
+            cs.teach_mode_
+        FROM course_schedule cs
+        <include refid="teacherGroupCourseQueryCondition"/>
+        ORDER BY CONCAT( cs.class_date_, ' ', cs.start_class_time_ )
+        <include refid="global.limit"/>
+    </select>
+
+    <select id="countTeacherGroupCourses" resultMap="teacherClassCourseSchedule">
+        SELECT
+            COUNT(cs.id_)
+        FROM course_schedule cs
+        <include refid="teacherGroupCourseQueryCondition"/>
+    </select>
+
     <select id="queryTeacherHistoryClassCourseSchedule" resultMap="teacherClassCourseSchedule">
         SELECT
         cs.class_group_id_,
@@ -2592,6 +2645,36 @@
     <select id="findGroupNotStartCourses" resultMap="CourseSchedule">
         SELECT * FROM course_schedule WHERE group_type_=#{groupType, typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler} AND music_group_id_ = #{groupId} AND CONCAT(class_date_, ' ', start_class_time_)>NOW()
     </select>
+    <select id="getSubjectNameById" resultType="java.lang.String">
+        SELECT GROUP_CONCAT(DISTINCT s.name_) FROM course_schedule cs
+        LEFT JOIN class_group cg ON cs.class_group_id_ = cg.id_
+        LEFT JOIN `subject` s ON FIND_IN_SET(s.id_,cg.subject_id_list_)
+        WHERE cs.id_ = #{courseScheduleId}
+        GROUP BY cg.id_
+    </select>
+    <resultMap id="CourseScheduleRateDtoMap" type="com.ym.mec.biz.dal.dto.CourseScheduleRateDto">
+        <result property="teachingContent" column=""/>
+        <result property="classDate" column="class_date_"/>
+        <result property="startClassTime" column="start_class_time_"/>
+        <result property="comment" column="comment_"/>
+        <result property="endClassTime" column="end_class_time_"/>
+        <result property="courseStatus" column="status_"/>
+        <result property="courseScheduleId" column="id_"/>
+    </resultMap>
+    <select id="findCourseRate" resultMap="CourseScheduleRateDtoMap">
+        SELECT cs.class_date_,cs.start_class_time_,cs.end_class_time_,cs.id_,
+        cs.teaching_content_,GROUP_CONCAT(cse.comment_ SEPARATOR ";") comment_,cs.status_
+        FROM course_schedule cs
+        LEFT JOIN course_schedule_evaluate cse ON cs.id_ = cse.course_schedule_id_
+        WHERE cs.music_group_id_ = #{groupId} AND cs.group_type_ = #{groupType}
+        GROUP BY cs.id_
+        ORDER BY cs.class_date_,cs.start_class_time_ DESC
+    </select>
+    <select id="getLastEndCourse" resultMap="CourseSchedule">
+        SELECT cs.id_ FROM course_schedule cs
+        WHERE cs.music_group_id_ = #{groupId} AND cs.group_type_ = #{groupType} AND NOW() > CONCAT(cs.class_date_,' ',cs.end_class_time_)
+        ORDER BY cs.class_date_,cs.end_class_time_ ASC LIMIT 1
+    </select>
 
     <resultMap id="GroupCourseTimesDto" type="com.ym.mec.biz.dal.dto.GroupCourseTimesDto">
         <result property="groupId" column="group_id_"/>

+ 16 - 0
mec-biz/src/main/resources/config/mybatis/CourseScheduleStudentPaymentMapper.xml

@@ -286,6 +286,22 @@
 	<select id="countStudentNum" resultType="java.lang.Integer">
 		SELECT COUNT(id_) FROM course_schedule_student_payment WHERE course_schedule_id_ = #{courseScheduleId}
 	</select>
+    <select id="findStudents" resultMap="com.ym.mec.biz.dal.dao.MusicGroupDao.BasicUserDto">
+		SELECT su.id_ user_id_,su.username_,su.avatar_ head_url_,su.gender_
+		FROM course_schedule_student_payment cssp
+		LEFT JOIN sys_user su ON su.id_ = cssp.user_id_
+		WHERE cssp.course_schedule_id_ = #{courseScheduleId}
+		GROUP BY su.id_
+	</select>
+	<select id="getStudentIdMap" resultType="java.util.Map">
+		SELECT cssp.course_schedule_id_ 'key',GROUP_CONCAT(DISTINCT cssp.user_id_) 'value'
+		FROM course_schedule_student_payment cssp
+		WHERE cssp.course_schedule_id_ IN
+		<foreach collection="courseScheduleIds" item="scheduleId" open="(" close=")" separator=",">
+			#{scheduleId}
+		</foreach>
+		GROUP BY cssp.course_schedule_id_
+	</select>
 
 	<delete id="deleteStudentCourseSchedule">
 		DELETE FROM course_schedule_student_payment WHERE user_id_ = #{userId} AND course_schedule_id_ IN

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

@@ -524,6 +524,8 @@
 	<resultMap id="ExportTeacherSalaryDtoMap" type="com.ym.mec.biz.dal.dto.ExportTeacherSalaryDto">
 		<result property="signOutTime" column="signOutTime"/>
 		<result property="signInTime" column="signInTime"/>
+		<result property="studentSignInTime" column="studentSignInTime"/>
+		<result property="studentSignOutTime" column="studentSignOutTime"/>
 		<result property="teacherName" column="teacherName"/>
 		<result property="groupName" column="groupName"/>
 		<result property="studentNum" column="studentNum"/>
@@ -596,10 +598,12 @@
 		CASE WHEN ta.sign_out_status_=0 THEN '异常' WHEN ta.sign_out_status_ = 1 THEN '正常' END signOutStatus,
 		ROUND((UNIX_TIMESTAMP(ta.sign_out_time_)-UNIX_TIMESTAMP(ta.sign_in_time_))/60) currentTime,
 		ta.sign_in_time_ signInTime,ta.sign_out_time_ signOutTime,COUNT(sp.id_) studentNum,
-		vg.online_classes_unit_price_,vg.offline_classes_unit_price_
+		vg.online_classes_unit_price_,vg.offline_classes_unit_price_,
+		GROUP_CONCAT(sa.sign_in_time_) studentSignInTime,GROUP_CONCAT(sa.sign_out_time_) studentSignOutTime
 		FROM course_schedule_teacher_salary ts
 		LEFT JOIN course_schedule cs ON ts.course_schedule_id_ = cs.id_
 		LEFT JOIN `teacher_attendance` ta ON ta.`teacher_id_` = ts.`user_id_` AND ta.`course_schedule_id_` = ts.`course_schedule_id_`
+		LEFT JOIN `student_attendance` sa ON sa.course_schedule_id_ = ts.course_schedule_id_
 		LEFT JOIN class_group cg ON cs.class_group_id_ = cg.id_
 		LEFT JOIN sys_user u ON ts.user_id_= u.id_
 		LEFT JOIN teacher t ON t.id_ = ts.user_id_
@@ -629,10 +633,12 @@
 		CASE WHEN ta.sign_in_status_ = 0 THEN '异常' WHEN ta.sign_in_status_ = 1 THEN '正常' END signInStatus,
 		CASE WHEN ta.sign_out_status_= 0 THEN '异常' WHEN ta.sign_out_status_ = 1 THEN '正常' END signOutStatus,
 		ROUND((UNIX_TIMESTAMP(ta.sign_out_time_)-UNIX_TIMESTAMP(ta.sign_in_time_))/60) currentTime,
-		ta.sign_in_time_ signInTime,ta.sign_out_time_ signOutTime,COUNT(sp.id_) studentNum
+		ta.sign_in_time_ signInTime,ta.sign_out_time_ signOutTime,COUNT(sp.id_) studentNum,
+		GROUP_CONCAT(sa.sign_in_time_) studentSignInTime,GROUP_CONCAT(sa.sign_out_time_) studentSignOutTime
 		FROM course_schedule_teacher_salary ts
 		LEFT JOIN course_schedule cs ON ts.course_schedule_id_ = cs.id_
 		LEFT JOIN `teacher_attendance` ta ON ta.`teacher_id_` = ts.`user_id_` AND ta.`course_schedule_id_` = ts.`course_schedule_id_`
+		LEFT JOIN `student_attendance` sa ON sa.course_schedule_id_ = ts.course_schedule_id_
 		LEFT JOIN class_group cg ON cs.class_group_id_ = cg.id_
 		LEFT JOIN sys_user u ON ts.user_id_= u.id_
 		LEFT JOIN teacher t ON t.id_ = ts.user_id_
@@ -657,4 +663,9 @@
 		SELECT COUNT(DISTINCT csts.user_id_) FROM class_group_teacher_mapper csts
 		WHERE csts.class_group_id_ = #{groupId} AND csts.user_id_ = #{userId}
 	</select>
+    <select id="countTeacherGiveLesson" resultType="java.lang.Integer">
+		SELECT COUNT(DISTINCT csts.id_) FROM course_schedule_teacher_salary csts
+		LEFT JOIN course_schedule cs ON cs.id_ = csts.course_schedule_id_
+		WHERE NOW() >= CONCAT(cs.class_date_ ,' ',cs.end_class_time_) AND csts.user_id_ = #{userId}
+	</select>
 </mapper>

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

@@ -125,7 +125,7 @@
 		SELECT * FROM practice_group WHERE user_id_=#{userId} AND (courses_start_date_ BETWEEN DATE_FORMAT(#{startDate},'%Y-%m-%d') AND DATE_FORMAT(#{endDate},'%Y-%m-%d'))
 	</select>
     <select id="countUserPracticeApplyRecord" resultType="int">
-		SELECT COUNT(*) FROM class_group_student_mapper WHERE group_type_='PRACTICE' AND user_id_=#{userId}
+		SELECT COUNT(*) FROM practice_group WHERE student_id_=#{userId} AND group_status_='NORMAL' AND buy_months_ IS NULL;
     </select>
     <select id="countPracticeGroupByOrgan" resultType="java.lang.Integer">
 		SELECT count(*) FROM practice_group pg

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

@@ -33,6 +33,7 @@
         <result column="idcard_hand_img_" property="idcardHandImg"/>
         <result column="update_time_" property="updateTime"/>
         <result column="create_time_" property="createTime"/>
+        <result column="lecture_num_" property="lectureNum"/>
 
         <result column="username_" property="username"/>
         <result column="password_" property="password"/>
@@ -57,7 +58,7 @@
     <select id="get" resultMap="Teacher">
         SELECT t.id_,t.organ_id_ teacher_organ_id_,t.job_type_,t.job_nature_,t.is_probation_period_,t.education_background_,t.graduate_school_,t.graduate_school_,
         t.technical_titles_,t.work_unit_,t.subject_id_,t.entry_date_,t.certificate_type_,t.certificate_num_,t.flow_organ_range_,t.update_time_,
-        t.create_time_,t.introduction_,t.demission_date_,t.is_support_course_schedule_rewards_rules_,t.is_support_extra_practice_lesson_,
+        t.create_time_,t.introduction_,t.demission_date_,t.is_support_course_schedule_rewards_rules_,t.is_support_extra_practice_lesson_,t.lecture_num_,
         su.real_name_,su.password_,su.salt_,su.phone_,su.avatar_,
         su.lock_flag_,su.del_flag_,su.wx_openid_,su.qq_openid_,su.user_type_,
         su.gender_,su.nation_,su.birthdate_,su.email_,su.im_token_,su.username_,su.organ_id_
@@ -93,6 +94,9 @@
     <update id="update" parameterType="com.ym.mec.biz.dal.entity.Teacher">
         UPDATE teacher
         <set>
+            <if test="lectureNum != null">
+                lecture_num_ = #{lectureNum},
+            </if>
             <if test="graduateSchool != null">
                 graduate_school_ = #{graduateSchool},
             </if>

+ 2 - 1
mec-im/src/main/java/com/ym/service/Impl/RoomServiceImpl.java

@@ -1131,6 +1131,7 @@ public class RoomServiceImpl implements RoomService {
     @Override
     @Transactional(rollbackFor = Exception.class)
     public boolean statusSync(String roomId,String userId) throws Exception {
+        log.info("statusSync: roomId={}, userId={}", roomId, userId);
         List<RoomMember> byRidAndUid = roomMemberDao.findByRidAndUid(roomId, userId);
         if(byRidAndUid.size() > 0){
 //            SysUser sysUser = sysUserFeignService.queryUserById(Integer.parseInt(userId));
@@ -1159,7 +1160,7 @@ public class RoomServiceImpl implements RoomService {
             }
 
             int userRole = roomMemberList.get(0).getRole();
-            log.info("leaveRoom: roomId={}, role={}", roomId, RoleEnum.getEnumByValue(userRole));
+            log.info("statusSync: roomId={}, role={}", roomId, RoleEnum.getEnumByValue(userRole));
 
             if (userRole == RoleEnum.RoleTeacher.getValue() || userRole == RoleEnum.RoleAssistant.getValue()) {
                 if (isUserDisplay(roomList.get(0), userId)) {

+ 27 - 5
mec-teacher/src/main/java/com/ym/mec/teacher/controller/TeacherCourseScheduleController.java

@@ -1,5 +1,6 @@
 package com.ym.mec.teacher.controller;
 
+import com.ym.mec.biz.dal.dto.TeacherRemarkCommitDto;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
@@ -14,11 +15,7 @@ import java.util.Objects;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
@@ -253,4 +250,29 @@ public class TeacherCourseScheduleController extends BaseController {
         return succeed(scheduleService.endFindCourseSchedules(queryInfo));
     }
 
+    @ApiOperation(value = "教师端中间页课程评价数据获取")
+    @GetMapping("/teacherCourseRemarkInfo")
+    public Object teacherCourseRemarkInfo(Long courseScheduleId){
+        return succeed(scheduleService.teacherCourseRemarkInfo(courseScheduleId));
+    }
+
+    @ApiOperation(value = "教师端中间页课程评价数据提交")
+    @PostMapping("/teacherCourseRemarkCommit")
+    public Object teacherCourseRemarkCommit(@RequestBody TeacherRemarkCommitDto teacherRemarkCommitDto){
+        scheduleService.teacherCourseRemarkCommit(teacherRemarkCommitDto);
+        return succeed();
+    }
+
+    @ApiOperation(value = "教师端中间页网络教室头部详情")
+    @GetMapping("/teacherCourseHeadInfo")
+    public Object teacherCourseHeadInfo(Long courseScheduleId){
+        return succeed(scheduleService.teacherCourseHeadInfo(courseScheduleId));
+    }
+
+    @ApiOperation(value = "教师端中间页网络教室课程进度列表")
+    @GetMapping("/teacherCourseRates")
+    public Object teacherCourseRates(Long courseScheduleId){
+        return succeed(scheduleService.teacherCourseRates(courseScheduleId));
+    }
+
 }

+ 141 - 0
mec-util/src/main/java/com/ym/mec/util/idcard/IdcardInfoExtractor.java

@@ -0,0 +1,141 @@
+package com.ym.mec.util.idcard;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Properties;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import com.ym.mec.util.exception.UtilException;
+
+public class IdcardInfoExtractor {
+	// 省份
+	private String province;
+
+	private String provinceCode;
+
+	// 城市
+	private String cityCode;
+
+	private String city;
+
+	// 区县
+	private String regionCode;
+
+	private String region;
+
+	// 性别(1,男 0,女)
+	private int gender;
+
+	// 出生日期
+	private Date birthday;
+
+	private static Properties idCardCodeTable;
+
+	static {
+		if (idCardCodeTable == null) {
+			idCardCodeTable = new Properties();
+		}
+		try {
+			idCardCodeTable.load(IdcardInfoExtractor.class.getClassLoader().getResourceAsStream("idcard/idcardCodeTable.properties"));
+		} catch (IOException e) {
+			throw new UtilException("银行卡信息查询接口异常", e);
+		}
+	}
+
+	private IdcardValidator validator = null;
+
+	/**  
+	 * 通过构造方法初始化各个成员属性  
+	 */
+	public IdcardInfoExtractor(String idcard, boolean isCheck) {
+		validator = new IdcardValidator();
+		if (isCheck) {
+			if (validator.isValidatedAllIdcard(idcard) == false) {
+				return;
+			}
+		}
+		if (idcard.length() == 15) {
+			idcard = validator.convertIdcarBy15bit(idcard);
+		}
+		// 获取省份
+		provinceCode = idcard.substring(0, 2) + "0000";
+		province = idCardCodeTable.getProperty(provinceCode);
+
+		cityCode = idcard.substring(0, 4) + "00";
+		city = idCardCodeTable.getProperty(cityCode);
+
+		regionCode = idcard.substring(0, 6);
+		region = idCardCodeTable.getProperty(regionCode);
+
+		// 获取性别
+		String id17 = idcard.substring(16, 17);
+		if (Integer.parseInt(id17) % 2 == 0) {
+			this.gender = 0;
+		} else {
+			this.gender = 1;
+		}
+
+		// 获取出生日期
+		String birthday = idcard.substring(6, 14);
+		Date birthdate = null;
+		try {
+			birthdate = new SimpleDateFormat("yyyyMMdd").parse(birthday);
+		} catch (ParseException e) {
+			throw new RuntimeException("身份证信息错误");
+		}
+		this.birthday = birthdate;
+
+	}
+
+	/**  
+	 * @return the province  
+	 */
+	public String getProvince() {
+		return province;
+	}
+
+	public String getProvinceCode() {
+		return provinceCode;
+	}
+
+	public String getCityCode() {
+		return cityCode;
+	}
+
+	public String getRegionCode() {
+		return regionCode;
+	}
+
+	public int getGender() {
+		return gender;
+	}
+
+	/**  
+	 * @return the birthday  
+	 */
+	public Date getBirthday() {
+		return birthday;
+	}
+
+	public String getCity() {
+		return city;
+	}
+
+	public String getRegion() {
+		return region;
+	}
+
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+	public static void main(String[] args) {
+		IdcardInfoExtractor extractor = new IdcardInfoExtractor("421125198708123013", true);
+		System.out.println(extractor);
+	}
+
+}

+ 414 - 0
mec-util/src/main/java/com/ym/mec/util/idcard/IdcardValidator.java

@@ -0,0 +1,414 @@
+package com.ym.mec.util.idcard;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.regex.Pattern;
+
+import com.ym.mec.util.exception.UtilException;
+
+public class IdcardValidator {
+	/** 
+	 * 省,直辖市代码表: { 11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古", 
+	 * 21:"辽宁",22:"吉林",23:"黑龙江",31:"上海",32:"江苏", 
+	 * 33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南", 
+	 * 42:"湖北",43:"湖南",44:"广东",45:"广西",46:"海南",50:"重庆", 
+	 * 51:"四川",52:"贵州",53:"云南",54:"西藏",61:"陕西",62:"甘肃", 
+	 * 63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门",91:"国外"} 
+	 */
+	protected String codeAndCity[][] = { { "11", "北京" }, { "12", "天津" }, { "13", "河北" }, { "14", "山西" }, { "15", "内蒙古" }, { "21", "辽宁" }, { "22", "吉林" },
+			{ "23", "黑龙江" }, { "31", "上海" }, { "32", "江苏" }, { "33", "浙江" }, { "34", "安徽" }, { "35", "福建" }, { "36", "江西" }, { "37", "山东" }, { "41", "河南" },
+			{ "42", "湖北" }, { "43", "湖南" }, { "44", "广东" }, { "45", "广西" }, { "46", "海南" }, { "50", "重庆" }, { "51", "四川" }, { "52", "贵州" }, { "53", "云南" },
+			{ "54", "西藏" }, { "61", "陕西" }, { "62", "甘肃" }, { "63", "青海" }, { "64", "宁夏" }, { "65", "新疆" }, { "71", "台湾" }, { "81", "香港" }, { "82", "澳门" },
+			{ "91", "国外" } };
+
+	private String cityCode[] = { "11", "12", "13", "14", "15", "21", "22", "23", "31", "32", "33", "34", "35", "36", "37", "41", "42", "43", "44", "45", "46",
+			"50", "51", "52", "53", "54", "61", "62", "63", "64", "65", "71", "81", "82", "91" };
+
+	// 每位加权因子
+	private int power[] = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
+
+	/** 
+	 * 验证所有的身份证的合法性 
+	 *  
+	 * @param idcard 
+	 * @return 
+	 */
+	public boolean isValidatedAllIdcard(String idcard) {
+		if (idcard.length() == 15) {
+			idcard = this.convertIdcarBy15bit(idcard);
+		}
+		return this.isValidate18Idcard(idcard);
+	}
+
+	/** 
+	 * <p> 
+	 * 判断18位身份证的合法性 
+	 * </p> 
+	 * 根据〖中华人民共和国国家标准GB11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。 
+	 * 排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。 
+	 * <p> 
+	 * 顺序码: 表示在同一地址码所标识的区域范围内,对同年、同月、同 日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配 给女性。 
+	 * </p> 
+	 * <p> 
+	 * 1.前1、2位数字表示:所在省份的代码; 2.第3、4位数字表示:所在城市的代码; 3.第5、6位数字表示:所在区县的代码; 
+	 * 4.第7~14位数字表示:出生年、月、日; 5.第15、16位数字表示:所在地的派出所的代码; 
+	 * 6.第17位数字表示性别:奇数表示男性,偶数表示女性; 
+	 * 7.第18位数字是校检码:也有的说是个人信息码,一般是随计算机的随机产生,用来检验身份证的正确性。校检码可以是0~9的数字,有时也用x表示。 
+	 * </p> 
+	 * <p> 
+	 * 第十八位数字(校验码)的计算方法为: 1.将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7 9 10 5 8 4 
+	 * 2 1 6 3 7 9 10 5 8 4 2 
+	 * </p> 
+	 * <p> 
+	 * 2.将这17位数字和系数相乘的结果相加。 
+	 * </p> 
+	 * <p> 
+	 * 3.用加出来和除以11,看余数是多少? 
+	 * </p> 
+	 * 4.余数只可能有0 1 2 3 4 5 6 7 8 9 10这11个数字。其分别对应的最后一位身份证的号码为1 0 X 9 8 7 6 5 4 3 
+	 * 2。 
+	 * <p> 
+	 * 5.通过上面得知如果余数是2,就会在身份证的第18位数字上出现罗马数字的Ⅹ。如果余数是10,身份证的最后一位号码就是2。 
+	 * </p> 
+	 *  
+	 * @param idcard 
+	 * @return 
+	 */
+	public boolean isValidate18Idcard(String idcard) {
+		// 非18位为假
+		if (idcard.length() != 18) {
+			return false;
+		}
+		// 获取前17位
+		String idcard17 = idcard.substring(0, 17);
+		// 获取第18位
+		String idcard18Code = idcard.substring(17, 18);
+		char c[] = null;
+		String checkCode = "";
+		// 是否都为数字
+		if (isDigital(idcard17)) {
+			c = idcard17.toCharArray();
+		} else {
+			return false;
+		}
+
+		if (null != c) {
+			int bit[] = new int[idcard17.length()];
+
+			bit = converCharToInt(c);
+
+			int sum17 = 0;
+
+			sum17 = getPowerSum(bit);
+
+			// 将和值与11取模得到余数进行校验码判断
+			checkCode = getCheckCodeBySum(sum17);
+			if (null == checkCode) {
+				return false;
+			}
+			// 将身份证的第18位与算出来的校码进行匹配,不相等就为假
+			if (!idcard18Code.equalsIgnoreCase(checkCode)) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/** 
+	 * 验证15位身份证的合法性,该方法验证不准确,最好是将15转为18位后再判断,该类中已提供。 
+	 *  
+	 * @param idcard 
+	 * @return 
+	 */
+	public boolean isValidate15Idcard(String idcard) {
+		// 非15位为假
+		if (idcard.length() != 15) {
+			return false;
+		}
+
+		// 是否全都为数字
+		if (isDigital(idcard)) {
+			String provinceid = idcard.substring(0, 2);
+			String birthday = idcard.substring(6, 12);
+			int year = Integer.parseInt(idcard.substring(6, 8));
+			int month = Integer.parseInt(idcard.substring(8, 10));
+			int day = Integer.parseInt(idcard.substring(10, 12));
+
+			// 判断是否为合法的省份
+			boolean flag = false;
+			for (String id : cityCode) {
+				if (id.equals(provinceid)) {
+					flag = true;
+					break;
+				}
+			}
+			if (!flag) {
+				return false;
+			}
+			// 该身份证生出日期在当前日期之后时为假
+			Date birthdate = null;
+			try {
+				birthdate = new SimpleDateFormat("yyMMdd").parse(birthday);
+			} catch (ParseException e) {
+				e.printStackTrace();
+			}
+			if (birthdate == null || new Date().before(birthdate)) {
+				return false;
+			}
+
+			// 判断是否为合法的年份
+			GregorianCalendar curDay = new GregorianCalendar();
+			int curYear = curDay.get(Calendar.YEAR);
+			int year2bit = Integer.parseInt(String.valueOf(curYear).substring(2));
+
+			// 判断该年份的两位表示法,小于50的和大于当前年份的,为假
+			if ((year < 50 && year > year2bit)) {
+				return false;
+			}
+
+			// 判断是否为合法的月份
+			if (month < 1 || month > 12) {
+				return false;
+			}
+
+			// 判断是否为合法的日期
+			boolean mflag = false;
+			curDay.setTime(birthdate); // 将该身份证的出生日期赋于对象curDay
+			switch (month) {
+			case 1:
+			case 3:
+			case 5:
+			case 7:
+			case 8:
+			case 10:
+			case 12:
+				mflag = (day >= 1 && day <= 31);
+				break;
+			case 2: // 公历的2月非闰年有28天,闰年的2月是29天。
+				if (curDay.isLeapYear(curDay.get(Calendar.YEAR))) {
+					mflag = (day >= 1 && day <= 29);
+				} else {
+					mflag = (day >= 1 && day <= 28);
+				}
+				break;
+			case 4:
+			case 6:
+			case 9:
+			case 11:
+				mflag = (day >= 1 && day <= 30);
+				break;
+			}
+			if (!mflag) {
+				return false;
+			}
+		} else {
+			return false;
+		}
+		return true;
+	}
+
+	/** 
+	 * 将15位的身份证转成18位身份证 
+	 *  
+	 * @param idcard 
+	 * @return 
+	 */
+	public String convertIdcarBy15bit(String idcard) {
+		String idcard17 = null;
+		// 非15位身份证
+		if (idcard.length() != 15) {
+			return null;
+		}
+
+		if (isDigital(idcard)) {
+			// 获取出生年月日
+			String birthday = idcard.substring(6, 12);
+			Date birthdate = null;
+			try {
+				birthdate = new SimpleDateFormat("yyMMdd").parse(birthday);
+			} catch (ParseException e) {
+				throw new UtilException("日期转换出错", e);
+			}
+			Calendar cday = Calendar.getInstance();
+			cday.setTime(birthdate);
+			String year = String.valueOf(cday.get(Calendar.YEAR));
+
+			idcard17 = idcard.substring(0, 6) + year + idcard.substring(8);
+
+			char c[] = idcard17.toCharArray();
+			String checkCode = "";
+
+			if (null != c) {
+				int bit[] = new int[idcard17.length()];
+
+				// 将字符数组转为整型数组
+				bit = converCharToInt(c);
+				int sum17 = 0;
+				sum17 = getPowerSum(bit);
+
+				// 获取和值与11取模得到余数进行校验码
+				checkCode = getCheckCodeBySum(sum17);
+				// 获取不到校验位
+				if (null == checkCode) {
+					return null;
+				}
+
+				// 将前17位与第18位校验码拼接
+				idcard17 += checkCode;
+			}
+		} else { // 身份证包含数字
+			return null;
+		}
+		return idcard17;
+	}
+
+	/** 
+	 * 15位和18位身份证号码的基本数字和位数验校 
+	 *  
+	 * @param idcard 
+	 * @return 
+	 */
+	public boolean isIdcard(String idcard) {
+		return idcard == null || "".equals(idcard) ? false : Pattern.matches("(^\\d{15}$)|(\\d{17}(?:\\d|x|X)$)", idcard);
+	}
+
+	/** 
+	 * 15位身份证号码的基本数字和位数验校 
+	 *  
+	 * @param idcard 
+	 * @return 
+	 */
+	public boolean is15Idcard(String idcard) {
+		return idcard == null || "".equals(idcard) ? false : Pattern.matches("^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$", idcard);
+	}
+
+	/** 
+	 * 18位身份证号码的基本数字和位数验校 
+	 *  
+	 * @param idcard 
+	 * @return 
+	 */
+	public boolean is18Idcard(String idcard) {
+		return Pattern.matches("^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([\\d|x|X]{1})$", idcard);
+	}
+
+	/** 
+	 * 数字验证 
+	 *  
+	 * @param str 
+	 * @return 
+	 */
+	public boolean isDigital(String str) {
+		return str == null || "".equals(str) ? false : str.matches("^[0-9]*$");
+	}
+
+	/** 
+	 * 将身份证的每位和对应位的加权因子相乘之后,再得到和值 
+	 *  
+	 * @param bit 
+	 * @return 
+	 */
+	public int getPowerSum(int[] bit) {
+
+		int sum = 0;
+
+		if (power.length != bit.length) {
+			return sum;
+		}
+
+		for (int i = 0; i < bit.length; i++) {
+			for (int j = 0; j < power.length; j++) {
+				if (i == j) {
+					sum = sum + bit[i] * power[j];
+				}
+			}
+		}
+		return sum;
+	}
+
+	/** 
+	 * 将和值与11取模得到余数进行校验码判断 
+	 *  
+	 * @param checkCode 
+	 * @param sum17 
+	 * @return 校验位 
+	 */
+	public String getCheckCodeBySum(int sum17) {
+		String checkCode = null;
+		switch (sum17 % 11) {
+		case 10:
+			checkCode = "2";
+			break;
+		case 9:
+			checkCode = "3";
+			break;
+		case 8:
+			checkCode = "4";
+			break;
+		case 7:
+			checkCode = "5";
+			break;
+		case 6:
+			checkCode = "6";
+			break;
+		case 5:
+			checkCode = "7";
+			break;
+		case 4:
+			checkCode = "8";
+			break;
+		case 3:
+			checkCode = "9";
+			break;
+		case 2:
+			checkCode = "x";
+			break;
+		case 1:
+			checkCode = "0";
+			break;
+		case 0:
+			checkCode = "1";
+			break;
+		}
+		return checkCode;
+	}
+
+	/** 
+	 * 将字符数组转为整型数组 
+	 *  
+	 * @param c 
+	 * @return 
+	 * @throws NumberFormatException 
+	 */
+	public int[] converCharToInt(char[] c) throws NumberFormatException {
+		int[] a = new int[c.length];
+		int k = 0;
+		for (char temp : c) {
+			a[k++] = Integer.parseInt(String.valueOf(temp));
+		}
+		return a;
+	}
+
+	public static void main(String[] args) throws Exception {
+
+		String idcard15 = "";
+		String idcard18 = "";
+		IdcardValidator iv = new IdcardValidator();
+		boolean flag = false;
+		flag = iv.isValidate18Idcard(idcard18);
+		System.out.println(flag);
+
+		flag = iv.isValidate15Idcard(idcard15);
+		System.out.println(flag);
+
+		System.out.println(iv.convertIdcarBy15bit(idcard15));
+		flag = iv.isValidate18Idcard(iv.convertIdcarBy15bit(idcard15));
+		System.out.println(flag);
+
+		System.out.println(iv.isValidatedAllIdcard(idcard18));
+
+	}
+}

+ 5 - 5
mec-web/src/main/java/com/ym/mec/web/controller/ExportController.java

@@ -82,12 +82,12 @@ public class ExportController extends BaseController {
             HSSFWorkbook workbook = POIUtil.exportExcel(new String[]{"课时编号", "老师编号", "老师姓名", "老师分部", "工作类别",
                     "课程分部", "课程班名称", "乐团模式", "vip活动名称", "阶梯奖励名称","线上课/线下课", "线上课单价", "线下课单价",
                     "课程类别", "课时时长", "实际上课时长", "上课日期",
-                    "上课时间", "签到状态", "签退状态", "签到时间", "签退时间",
-                    "主辅", "上课地点", "应到学员","课时课酬","阶梯奖励"}, new String[]{
+                    "上课时间", "教师签到状态", "教师签退状态", "教师签到时间", "教师签退时间",
+                    "主辅", "上课地点", "应到学员", "学员签到时间", "学员签退时间","课时课酬","阶梯奖励"}, new String[]{
                     "courseScheduleId", "teacherId", "teacherName", "teacherOrganName", "jobType",
                     "courseScheduleOrganName", "groupName", "changeType", "vipActiveName","activeName", "teachMode", "onlineClassesUnitPrice", "offlineClassesUnitPrice",
                     "courseScheduleType","signCourseScheduleTime","currentTime","classDate","courseScheduleStartTime","signInStatus",
-                    "signOutStatus","signInTime","signOutTime","teacherRole","address","studentNum","price","rewards"}, rows);
+                    "signOutStatus","signInTime","signOutTime","teacherRole","address","studentNum","studentSignInTime","studentSignOutTime","price","rewards"}, rows);
             response.setContentType("application/octet-stream");
             response.setHeader("Content-Disposition", "attachment;filename=lender-" + DateUtil.getDate(new Date()) + ".xls");
             response.flushBuffer();
@@ -256,9 +256,9 @@ public class ExportController extends BaseController {
         List<CourseScheduleEndDto> rows = scheduleService.endFindCourseSchedules(queryInfo).getRows();
         try {
             HSSFWorkbook workbook = POIUtil.exportExcel(new String[]{"分部名称", "课程编号", "开始时间", "结束时间", "班级名称", "班级声部", "课程名称", "课程类型", "教学模式",
-                    "教学点", "课程状态", "是否点名", "指导老师", "签到时间", "签退时间","签到备注"}, new String[]{
+                    "教学点", "课程状态", "是否点名", "指导老师", "学员编号", "签到时间", "签退时间","签到备注"}, new String[]{
                     "organName", "id", "startClassTime", "endClassTime", "classGroupName","subjectName", "name",
-                    "groupType.desc", "teachMode.msg", "schoolName", "status.msg", "isCallNames.msg", "teacherName", "signInTime",
+                    "groupType.desc", "teachMode.msg", "schoolName", "status.msg", "isCallNames.msg", "teacherName", "studentId", "signInTime",
                     "signOutTime","remark"}, rows);
             response.setContentType("application/octet-stream");
             response.setHeader("Content-Disposition", "attachment;filename=lender-" + DateUtil.getDate(new Date()) + ".xls");