瀏覽代碼

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

周箭河 5 年之前
父節點
當前提交
c2139b98f9
共有 72 個文件被更改,包括 2011 次插入523 次删除
  1. 3 0
      cms/src/main/resources/config/mybatis/SysNewsInformationMapper.xml
  2. 2 2
      mec-auth/mec-auth-api/src/main/java/com/ym/mec/auth/api/entity/SysRole.java
  3. 7 0
      mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/config/WebMvcConfig.java
  4. 1 1
      mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/core/filter/PhoneLoginAuthenticationFilter.java
  5. 1 1
      mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/core/filter/UsernameAuthenticationFilter.java
  6. 7 1
      mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/core/handler/BaseAuthenticationFailureEvenHandler.java
  7. 16 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/ClassGroupDao.java
  8. 10 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleDao.java
  9. 16 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/MusicGroupDao.java
  10. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TeacherAttendanceDao.java
  11. 12 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TeacherDao.java
  12. 18 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/VipGroupDao.java
  13. 22 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/CourseScheduleDto.java
  14. 34 11
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/EmployeeDto.java
  15. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/VipGroupCourseSchduleRecordDto.java
  16. 44 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/VipGroupManageDetailDto.java
  17. 58 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/VipGroupSalaryBaseInfo.java
  18. 24 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/VipGroupSalaryDto.java
  19. 5 3
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/CourseSchedule.java
  20. 14 3
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/MusicGroup.java
  21. 1 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/MusicGroupSubjectPlan.java
  22. 34 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/TeacherAttendance.java
  23. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/VipGroup.java
  24. 4 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/VipGroupStatusEnum.java
  25. 35 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/CourseScheduleQueryInfo.java
  26. 20 4
      mec-biz/src/main/java/com/ym/mec/biz/service/ContractService.java
  27. 9 0
      mec-biz/src/main/java/com/ym/mec/biz/service/CourseScheduleService.java
  28. 21 0
      mec-biz/src/main/java/com/ym/mec/biz/service/TeacherService.java
  29. 13 2
      mec-biz/src/main/java/com/ym/mec/biz/service/VipGroupService.java
  30. 21 5
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ClassGroupServiceImpl.java
  31. 252 51
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ContractServiceImpl.java
  32. 32 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleServiceImpl.java
  33. 5 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/DemoGroupServiceImpl.java
  34. 3 2
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/EmployeeServiceImpl.java
  35. 1 7
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/MusicGroupServiceImpl.java
  36. 35 9
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/TeacherAttendanceServiceImpl.java
  37. 55 7
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/TeacherServiceImpl.java
  38. 64 9
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/VipGroupServiceImpl.java
  39. 11 11
      mec-biz/src/main/resources/config/contracts/courses.ftl
  40. 14 14
      mec-biz/src/main/resources/config/contracts/goods.ftl
  41. 202 216
      mec-biz/src/main/resources/config/contracts/register.ftl
  42. 16 4
      mec-biz/src/main/resources/config/mybatis/ClassGroupMapper.xml
  43. 46 8
      mec-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml
  44. 4 3
      mec-biz/src/main/resources/config/mybatis/CourseScheduleTeacherSalaryMapper.xml
  45. 1 1
      mec-biz/src/main/resources/config/mybatis/DemoGroupMapper.xml
  46. 32 47
      mec-biz/src/main/resources/config/mybatis/EmployeeMapper.xml
  47. 13 0
      mec-biz/src/main/resources/config/mybatis/MusicGroupMapper.xml
  48. 1 1
      mec-biz/src/main/resources/config/mybatis/OrganizationMapper.xml
  49. 16 5
      mec-biz/src/main/resources/config/mybatis/TeacherAttendanceMapper.xml
  50. 11 0
      mec-biz/src/main/resources/config/mybatis/TeacherMapper.xml
  51. 48 12
      mec-biz/src/main/resources/config/mybatis/VipGroupMapper.xml
  52. 1 1
      mec-education/src/main/java/com/ym/mec/education/EducationApplication.java
  53. 8 0
      mec-education/src/main/java/com/ym/mec/education/config/WebMvcConfig.java
  54. 15 0
      mec-education/src/main/java/com/ym/mec/education/controller/CourseScheduleController.java
  55. 53 49
      mec-education/src/main/java/com/ym/mec/education/service/impl/TeacherServiceImpl.java
  56. 1 1
      mec-education/src/main/resources/application.yml
  57. 2 0
      mec-eureka/src/main/resources/application.yml
  58. 8 0
      mec-im/src/main/java/com/ym/config/WebMvcConfig.java
  59. 7 0
      mec-student/src/main/java/com/ym/mec/student/config/WebMvcConfig.java
  60. 30 0
      mec-student/src/main/java/com/ym/mec/student/controller/ContractsController.java
  61. 1 1
      mec-student/src/main/java/com/ym/mec/student/controller/StudentDemoGroupController.java
  62. 7 0
      mec-task/src/main/java/com/ym/mec/task/config/WebMvcConfig.java
  63. 7 0
      mec-teacher/src/main/java/com/ym/mec/teacher/config/WebMvcConfig.java
  64. 70 0
      mec-teacher/src/main/java/com/ym/mec/teacher/controller/OrderController.java
  65. 209 0
      mec-teacher/src/main/java/com/ym/mec/teacher/controller/TaskController.java
  66. 45 19
      mec-teacher/src/main/java/com/ym/mec/teacher/controller/TeacherController.java
  67. 11 7
      mec-teacher/src/main/java/com/ym/mec/teacher/controller/TeacherCourseScheduleController.java
  68. 131 0
      mec-util/src/main/java/com/ym/mec/util/money/MoneyUtil.java
  69. 7 0
      mec-web/src/main/java/com/ym/mec/web/config/WebMvcConfig.java
  70. 43 2
      mec-web/src/main/java/com/ym/mec/web/controller/VipGroupManageController.java
  71. 1 1
      mec-web/src/main/java/com/ym/mec/web/controller/student/StudentAttendanceController.java
  72. 7 0
      mec-workflow/src/main/java/com/ym/mec/workfow/config/WebMvcConfig.java

+ 3 - 0
cms/src/main/resources/config/mybatis/SysNewsInformationMapper.xml

@@ -29,6 +29,9 @@
 			<if test="title != null">
 				and title_ like '%' #{title} '%'
 			</if>
+			<if test="search != null">
+				and title_ like '%' #{search} '%'
+			</if>
 		</where>
 	</sql>
 	

+ 2 - 2
mec-auth/mec-auth-api/src/main/java/com/ym/mec/auth/api/entity/SysRole.java

@@ -1,11 +1,11 @@
 package com.ym.mec.auth.api.entity;
 
-import com.ym.mec.auth.api.enums.YesOrNoEnum;
 import io.swagger.annotations.ApiModelProperty;
-import org.apache.commons.lang3.builder.ToStringBuilder;
 
 import java.util.List;
 
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
 /**
  * 对应数据库表(sys_role):
  */

+ 7 - 0
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/config/WebMvcConfig.java

@@ -9,6 +9,7 @@ import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
 import java.util.Date;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Primary;
@@ -57,6 +58,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
 		objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
 		// 序列化BigDecimal时不使用科学计数法输出
 		objectMapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
+		objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
+			@Override
+			public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
+				jsonGenerator.writeString(StringUtils.EMPTY);
+			}
+		});
 		// 日期和时间格式化
 		JavaTimeModule javaTimeModule = new JavaTimeModule();
 		javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

+ 1 - 1
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/core/filter/PhoneLoginAuthenticationFilter.java

@@ -57,7 +57,7 @@ public class PhoneLoginAuthenticationFilter extends AbstractAuthenticationProces
 		String clientId = request.getParameter(clientIdParameter);
 
 		if (userInfo == null) {
-			throw new UsernameNotFoundException("用户名或密码错误");
+			throw new UsernameNotFoundException("404.9");
 		}
 	
 		if (userInfo.getSysUser().getUserType() != SysUserType.SYSTEM && !StringUtils.equalsIgnoreCase(clientId, userInfo.getSysUser().getUserType().getCode())) {

+ 1 - 1
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/core/filter/UsernameAuthenticationFilter.java

@@ -68,7 +68,7 @@ public class UsernameAuthenticationFilter extends AbstractAuthenticationProcessi
 		String clientId = request.getParameter(clientIdParameter);
 
 		if (userInfo == null) {
-			throw new UsernameNotFoundException("用户名或密码错误");
+			throw new UsernameNotFoundException("404.9");
 		}
 	
 		if (userInfo.getSysUser().getUserType() != SysUserType.SYSTEM && !StringUtils.equalsIgnoreCase(clientId, userInfo.getSysUser().getUserType().getCode())) {

+ 7 - 1
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/core/handler/BaseAuthenticationFailureEvenHandler.java

@@ -24,14 +24,20 @@ public class BaseAuthenticationFailureEvenHandler extends ExceptionMappingAuthen
 
     @Override
     public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException {
+    	
+    	int resultCode = HttpStatus.SC_CONFLICT;
+    	
         String message = exception.getLocalizedMessage();
         if (message.equals("Bad credentials")) {
             message = "用户名或密码错误";
         }else if(message.equals("User is disabled")){
             message = "账户被锁定";
+        }else if(message.equals("404.9")){
+        	message = "用户名或密码错误";
+        	resultCode = 99;
         }
         logger.info("登录失败,异常:{}", message);
-        HttpResponseResult result = new HttpResponseResult(false, HttpStatus.SC_CONFLICT, null, message);
+        HttpResponseResult result = new HttpResponseResult(false, resultCode, null, message);
         response.setContentType("application/json; charset=utf-8");
         response.getWriter().write(objectMapper.writeValueAsString(result));
     }

+ 16 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/ClassGroupDao.java

@@ -10,6 +10,7 @@ import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 public interface ClassGroupDao extends BaseDAO<Integer, ClassGroup> {
 
@@ -175,4 +176,19 @@ public interface ClassGroupDao extends BaseDAO<Integer, ClassGroup> {
      * @return
      */
     int addStudentNum(@Param("classGroup") ClassGroup classGroup);
+
+    /**
+     * 获取当前班级老师id列表
+     * @param id
+     * @return
+     */
+    Set<Integer> queryTeacherIds(String id);
+
+    /**
+     * 获取老师所在班级群组列表
+     * @param userId
+     * @param search
+     * @return
+     */
+    List<ImGroupModel> queryTeacherGroups(@Param("userId") Integer userId, @Param("search") String search);
 }

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

@@ -47,6 +47,15 @@ public interface CourseScheduleDao extends BaseDAO<Long, CourseSchedule> {
 
     /**
      * @Author: Joburgess
+     * @Date: 2019/10/11
+     * @params [courseScheduleId]
+     * @return java.util.List<java.lang.String>
+     * @describe 获取课程签到学生姓名
+     */
+    List<String> findStudentNamesByCourseSchedule(Long courseScheduleId);
+
+    /**
+     * @Author: Joburgess
      * @Date: 2019/9/17
      * 根据日期获取老师当日排课信息
      */
@@ -61,6 +70,7 @@ public interface CourseScheduleDao extends BaseDAO<Long, CourseSchedule> {
      * @describe 根据
      */
     List<CourseScheduleDto> getCourseSchedulesWithDate(Map<String,Object> params);
+    int countCourseSchedulesWithDate(Map<String,Object> params);
 
     /**
      * @Author: Joburgess

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

@@ -10,6 +10,7 @@ import com.ym.mec.common.entity.ImUserModel;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
+import java.util.Set;
 
 public interface MusicGroupDao extends BaseDAO<String, MusicGroup> {
 	
@@ -71,4 +72,19 @@ public interface MusicGroupDao extends BaseDAO<String, MusicGroup> {
      * @return
      */
     List<ImUserModel> findGroupUsers(String musicGroupId);
+
+    /**
+     * 获取教师所在乐团列表
+     * @param userId
+     * @param search
+     * @return
+     */
+    List<ImGroupModel> queryTeacherGroups(@Param("userId") Integer userId, @Param("search")String search);
+
+    /**
+     * 获取当前乐团所有教师列表
+     * @param id
+     * @return
+     */
+    Set<Integer> queryTeacherIds(String id);
 }

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TeacherAttendanceDao.java

@@ -3,6 +3,7 @@ package com.ym.mec.biz.dal.dao;
 import com.ym.mec.biz.dal.dto.TeacherPersonalAttendanceDto;
 import com.ym.mec.biz.dal.entity.TeacherAttendance;
 import com.ym.mec.common.dal.BaseDAO;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 import java.util.Map;
@@ -29,5 +30,15 @@ public interface TeacherAttendanceDao extends BaseDAO<Long, TeacherAttendance> {
      * 统计课次
      */
     int countClassTime(Long classGroupId);
+
+    /**
+     * @Author: Joburgess
+     * @Date: 2019/10/11
+     * @params [teacherId, courseScheduleId]
+     * @return com.ym.mec.biz.dal.entity.TeacherAttendance
+     * @describe 根据老师编号和课程编号获取老师签到记录
+     */
+    TeacherAttendance findByTeacherAttendanceInfo(@Param("teacherId") Long teacherId,
+                                                  @Param("courseScheduleId") Long courseScheduleId);
 	
 }

+ 12 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TeacherDao.java

@@ -1,11 +1,15 @@
 package com.ym.mec.biz.dal.dao;
 
 import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.biz.dal.dto.BasicUserDto;
 import com.ym.mec.biz.dal.entity.Teacher;
 import com.ym.mec.common.dal.BaseDAO;
 
+import com.ym.mec.common.entity.ImGroupModel;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+
 public interface TeacherDao extends BaseDAO<Integer, Teacher> {
 
     /**
@@ -26,4 +30,12 @@ public interface TeacherDao extends BaseDAO<Integer, Teacher> {
      * @param user
      */
     void addSysUser(SysUser user);
+
+    /**
+     * 获取和当前教师相关的学员列表
+     * @param teacherId
+     * @param search
+     * @return
+     */
+    List<BasicUserDto> queryGroupStudents(@Param("teacherId") Integer teacherId, @Param("search") String search);
 }

+ 18 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/VipGroupDao.java

@@ -105,6 +105,24 @@ public interface VipGroupDao extends BaseDAO<Long, VipGroup> {
 
 	/**
 	 * @Author: Joburgess
+	 * @Date: 2019/10/11
+	 * @params [vipGroupId]
+	 * @return com.ym.mec.biz.dal.dto.VipGroupSalaryBaseInfo
+	 * @describe 获取vip课财务基本信息
+	 */
+	VipGroupSalaryBaseInfo getVipGroupSalaryInfo(Long vipGroupId);
+
+	/**
+	 * @Author: Joburgess
+	 * @Date: 2019/10/11
+	 * @params [vipGroupId]
+	 * @return int
+	 * @describe 统计扣费笔数
+	 */
+	int countVipGroupDeductionNum(Long vipGroupId);
+
+	/**
+	 * @Author: Joburgess
 	 * @Date: 2019/10/3
 	 * @params [params]
 	 * @return java.util.List<com.ym.mec.biz.dal.entity.CourseSchedule>

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

@@ -23,6 +23,28 @@ public class CourseScheduleDto extends CourseSchedule {
     @ApiModelProperty(value = "班级编号,房间号",required = false)
     private String sealClassId;
 
+    @ApiModelProperty(value = "签到状态(1已签到,0未签到)",required = false)
+    private Integer signInStatus;
+
+    @ApiModelProperty(value = "签退状态(1已签到,0未签到)",required = false)
+    private Integer signOutStatus;
+
+    public Integer getSignInStatus() {
+        return signInStatus;
+    }
+
+    public void setSignInStatus(Integer signInStatus) {
+        this.signInStatus = signInStatus;
+    }
+
+    public Integer getSignOutStatus() {
+        return signOutStatus;
+    }
+
+    public void setSignOutStatus(Integer signOutStatus) {
+        this.signOutStatus = signOutStatus;
+    }
+
     public String getSealClassId() {
         return sealClassId;
     }

+ 34 - 11
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/EmployeeDto.java

@@ -5,6 +5,7 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiModelProperty;
 
 import java.util.Date;
+import java.util.List;
 
 /**
  * @Author Joburgess
@@ -17,7 +18,7 @@ public class EmployeeDto {
 
     /** 用户名 */
     @ApiModelProperty(value = "用户名",required = false)
-    private String username;
+    private String realName;
 
     @ApiModelProperty(value = "性别",required = false)
     private UserGenderEnum gender;
@@ -32,6 +33,12 @@ public class EmployeeDto {
     @ApiModelProperty(value = "角色名称",required = false)
     private String roleName;
 
+    @ApiModelProperty(value = "角色名称",required = false)
+    private List<String> roleNames;
+
+    @ApiModelProperty(value = "角色编号",required = false)
+    private List<Integer> roleIds;
+
     /** 工作性质(兼职、全职、临时) */
     private String jobNature;
 
@@ -42,24 +49,40 @@ public class EmployeeDto {
     private java.util.Date demissionDate;
 
     @ApiModelProperty(value = "部门ID",required = false)
-    private Long organIdList;
+    private List<Long> organIdList;
 
     @ApiModelProperty(value = "部门名称",required = false)
-    private String organNameList;
+    private List<String> organNameList;
+
+    public List<String> getRoleNames() {
+        return roleNames;
+    }
+
+    public void setRoleNames(List<String> roleNames) {
+        this.roleNames = roleNames;
+    }
+
+    public List<Integer> getRoleIds() {
+        return roleIds;
+    }
+
+    public void setRoleIds(List<Integer> roleIds) {
+        this.roleIds = roleIds;
+    }
 
-    public Long getOrganIdList() {
+    public List<Long> getOrganIdList() {
         return organIdList;
     }
 
-    public void setOrganIdList(Long organIdList) {
+    public void setOrganIdList(List<Long> organIdList) {
         this.organIdList = organIdList;
     }
 
-    public String getOrganNameList() {
+    public List<String> getOrganNameList() {
         return organNameList;
     }
 
-    public void setOrganNameList(String organNameList) {
+    public void setOrganNameList(List<String> organNameList) {
         this.organNameList = organNameList;
     }
 
@@ -71,12 +94,12 @@ public class EmployeeDto {
         this.id = id;
     }
 
-    public String getUsername() {
-        return username;
+    public String getRealName() {
+        return realName;
     }
 
-    public void setUsername(String username) {
-        this.username = username;
+    public void setRealName(String realName) {
+        this.realName = realName;
     }
 
     public UserGenderEnum getGender() {

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

@@ -28,6 +28,17 @@ public class VipGroupCourseSchduleRecordDto {
     @ApiModelProperty(value = "结算状态")
     private YesOrNoEnum isSalary;
 
+    @ApiModelProperty(value = "上课人数")
+    private Integer attendanceNum;
+
+    public Integer getAttendanceNum() {
+        return attendanceNum;
+    }
+
+    public void setAttendanceNum(Integer attendanceNum) {
+        this.attendanceNum = attendanceNum;
+    }
+
     public Long getId() {
         return id;
     }

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

@@ -15,12 +15,56 @@ public class VipGroupManageDetailDto extends VipGroup {
     @ApiModelProperty(value = "最新课次",required = false)
     private Integer latestClassTime;
 
+    @ApiModelProperty(value = "科目名称")
+    private String subjectName;
+
+    @ApiModelProperty(value = "科目编号列表")
+    private String subjectIdList;
+
+    @ApiModelProperty(value = "课程形式")
+    private String categoryName;
+
     @ApiModelProperty(value = "学生数量", required = false)
     private Integer studentNum;
 
     @ApiModelProperty(value = "小课学院",required = false)
     private List<SysUser> students;
 
+    @ApiModelProperty(value = "教学点名称")
+    private String teacherSchoolName;
+
+    public String getTeacherSchoolName() {
+        return teacherSchoolName;
+    }
+
+    public void setTeacherSchoolName(String teacherSchoolName) {
+        this.teacherSchoolName = teacherSchoolName;
+    }
+
+    public String getCategoryName() {
+        return categoryName;
+    }
+
+    public void setCategoryName(String categoryName) {
+        this.categoryName = categoryName;
+    }
+
+    public String getSubjectIdList() {
+        return subjectIdList;
+    }
+
+    public void setSubjectIdList(String subjectIdList) {
+        this.subjectIdList = subjectIdList;
+    }
+
+    public String getSubjectName() {
+        return subjectName;
+    }
+
+    public void setSubjectName(String subjectName) {
+        this.subjectName = subjectName;
+    }
+
     public Integer getLatestClassTime() {
         return latestClassTime;
     }

+ 58 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/VipGroupSalaryBaseInfo.java

@@ -0,0 +1,58 @@
+package com.ym.mec.biz.dal.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import org.codehaus.jackson.annotate.JsonIgnore;
+
+import java.math.BigDecimal;
+
+/**
+ * @Author Joburgess
+ * @Date 2019/10/11
+ */
+public class VipGroupSalaryBaseInfo {
+
+    @ApiModelProperty(value = "预计课酬总额")
+    @JsonIgnore
+    private BigDecimal expectTotalSalary;
+
+    @ApiModelProperty(value = "扣费笔数")
+    private Integer feeDeductionNum;
+
+    @ApiModelProperty(value = "扣费总额")
+    private BigDecimal totalFeeDeduction;
+
+    @ApiModelProperty(value = "课酬总额")
+    private BigDecimal totalSalary;
+
+    public BigDecimal getExpectTotalSalary() {
+        return expectTotalSalary;
+    }
+
+    public void setExpectTotalSalary(BigDecimal expectTotalSalary) {
+        this.expectTotalSalary = expectTotalSalary;
+    }
+
+    public Integer getFeeDeductionNum() {
+        return feeDeductionNum;
+    }
+
+    public void setFeeDeductionNum(Integer feeDeductionNum) {
+        this.feeDeductionNum = feeDeductionNum;
+    }
+
+    public BigDecimal getTotalFeeDeduction() {
+        return totalFeeDeduction;
+    }
+
+    public void setTotalFeeDeduction(BigDecimal totalFeeDeduction) {
+        this.totalFeeDeduction = totalFeeDeduction;
+    }
+
+    public BigDecimal getTotalSalary() {
+        return totalSalary;
+    }
+
+    public void setTotalSalary(BigDecimal totalSalary) {
+        this.totalSalary = totalSalary;
+    }
+}

+ 24 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/VipGroupSalaryDto.java

@@ -2,8 +2,10 @@ package com.ym.mec.biz.dal.dto;
 
 import com.ym.mec.biz.dal.entity.CourseScheduleTeacherSalary;
 import com.ym.mec.biz.dal.enums.TeachModeEnum;
+import com.ym.mec.biz.dal.enums.YesOrNoEnum;
 import io.swagger.annotations.ApiModelProperty;
 
+import java.math.BigDecimal;
 import java.util.Date;
 
 /**
@@ -21,6 +23,28 @@ public class VipGroupSalaryDto extends CourseScheduleTeacherSalary {
     @ApiModelProperty(value = "教学形式")
     private TeachModeEnum teachMode;
 
+    @ApiModelProperty(value = "扣除费用")
+    private BigDecimal deductionFee;
+
+    @ApiModelProperty(value = "是否已结算")
+    private YesOrNoEnum isSalary;
+
+    public YesOrNoEnum getIsSalary() {
+        return isSalary;
+    }
+
+    public void setIsSalary(YesOrNoEnum isSalary) {
+        this.isSalary = isSalary;
+    }
+
+    public BigDecimal getDeductionFee() {
+        return deductionFee;
+    }
+
+    public void setDeductionFee(BigDecimal deductionFee) {
+        this.deductionFee = deductionFee;
+    }
+
     @Override
     public Long getCourseScheduleId() {
         return courseScheduleId;

+ 5 - 3
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/CourseSchedule.java

@@ -9,6 +9,8 @@ import com.ym.mec.biz.dal.enums.CourseStatusEnum;
 import com.ym.mec.biz.dal.enums.TeachModeEnum;
 import com.ym.mec.common.enums.BaseEnum;
 
+import java.math.BigDecimal;
+
 /**
  * 对应数据库表(course_schedule):
  */
@@ -52,7 +54,7 @@ public class CourseSchedule {
 
 	/** 补贴 */
 	@ApiModelProperty(value = "补贴", required = false)
-	private long subsidy;
+	private BigDecimal subsidy;
 
 	/** 上课日期 */
 	@ApiModelProperty(value = "上课日期", required = false)
@@ -110,11 +112,11 @@ public class CourseSchedule {
 		this.status = status;
 	}
 
-	public void setSubsidy(long subsidy) {
+	public void setSubsidy(BigDecimal subsidy) {
 		this.subsidy = subsidy;
 	}
 
-	public long getSubsidy() {
+	public BigDecimal getSubsidy() {
 		return this.subsidy;
 	}
 

+ 14 - 3
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/MusicGroup.java

@@ -91,7 +91,10 @@ public class MusicGroup {
 	private String img;
 	
 	@ApiModelProperty(value = "教学主任",required = false)
-	private String directorUserId;
+	private Integer directorUserId;
+
+	@ApiModelProperty(value = "乐团创建人",required = false)
+	private Integer operatorUserId;
 
 	public String getImg() {
 		return img;
@@ -269,14 +272,22 @@ public class MusicGroup {
 		this.isExtraClass = isExtraClass;
 	}
 
-	public String getDirectorUserId() {
+	public Integer getDirectorUserId() {
 		return directorUserId;
 	}
 
-	public void setDirectorUserId(String directorUserId) {
+	public void setDirectorUserId(Integer directorUserId) {
 		this.directorUserId = directorUserId;
 	}
 
+	public Integer getOperatorUserId() {
+		return operatorUserId;
+	}
+
+	public void setOperatorUserId(Integer operatorUserId) {
+		this.operatorUserId = operatorUserId;
+	}
+
 	@Override
 	public String toString() {
 		return ToStringBuilder.reflectionToString(this);

+ 1 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/MusicGroupSubjectPlan.java

@@ -50,7 +50,7 @@ public class MusicGroupSubjectPlan {
 	
 	/** 保证金(只有租赁才有) */
 	@ApiModelProperty(value = "保证金(只有租赁才有)",required = false)
-	private BigDecimal depositFee;
+	private BigDecimal depositFee = new BigDecimal(0);
 	
 	/**  */
 	private java.util.Date createTime;

+ 34 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/TeacherAttendance.java

@@ -2,6 +2,7 @@ package com.ym.mec.biz.dal.entity;
 
 import com.ym.mec.biz.dal.enums.SignStatusEnum;
 
+import com.ym.mec.biz.dal.enums.YesOrNoEnum;
 import io.swagger.annotations.ApiModelProperty;
 
 import org.apache.commons.lang3.builder.ToStringBuilder;
@@ -39,6 +40,15 @@ public class TeacherAttendance {
 	/** 状态(正常签到,异常签到) */
 	@ApiModelProperty(value = "状态(1正常签到,0异常签到,2正常签退) ",required = false)
 	private SignStatusEnum status;
+
+	@ApiModelProperty(value = "签到状态:0异常,1正常")
+	private YesOrNoEnum signInStatus;
+
+	@ApiModelProperty(value = "签退状态:0异常,1正常")
+	private YesOrNoEnum signOutStatus;
+
+	@ApiModelProperty(value = "签退使劲按")
+	private Date signOutTime;
 	
 	/** 备注 */
 	@ApiModelProperty(value = "备注",required = false)
@@ -47,6 +57,30 @@ public class TeacherAttendance {
 	/**  */
 	private java.util.Date createTime;
 
+	public YesOrNoEnum getSignInStatus() {
+		return signInStatus;
+	}
+
+	public void setSignInStatus(YesOrNoEnum signInStatus) {
+		this.signInStatus = signInStatus;
+	}
+
+	public YesOrNoEnum getSignOutStatus() {
+		return signOutStatus;
+	}
+
+	public void setSignOutStatus(YesOrNoEnum signOutStatus) {
+		this.signOutStatus = signOutStatus;
+	}
+
+	public Date getSignOutTime() {
+		return signOutTime;
+	}
+
+	public void setSignOutTime(Date signOutTime) {
+		this.signOutTime = signOutTime;
+	}
+
 	public Long getId() {
 		return id;
 	}

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

@@ -81,6 +81,9 @@ public class VipGroup {
 	@ApiModelProperty("活动方案编号")
 	private Long vipGroupActivityId;
 
+	@ApiModelProperty(value = "活动方案名称")
+	private String vipGroupActivityName;
+
 	@ApiModelProperty(value = "课程状态")
 	private VipGroupStatusEnum status;
 
@@ -96,6 +99,14 @@ public class VipGroup {
 	@ApiModelProperty(value = "赠送课时类型")
 	private TeachModeEnum giveTeachMode;
 
+	public String getVipGroupActivityName() {
+		return vipGroupActivityName;
+	}
+
+	public void setVipGroupActivityName(String vipGroupActivityName) {
+		this.vipGroupActivityName = vipGroupActivityName;
+	}
+
 	public String getUserName() {
 		return userName;
 	}

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

@@ -8,7 +8,10 @@ import com.ym.mec.common.enums.BaseEnum;
  */
 public enum  VipGroupStatusEnum implements BaseEnum<Integer, VipGroupStatusEnum> {
 
-    NOT_START(0, "未开始"), APPLYING(1, "报名中"), FINISH(2, "报名已结束"), CANCEL(3, "取消");
+    NOT_START(0, "未开始"),
+    APPLYING(1, "报名中"),
+    FINISH(2, "报名已结束"),
+    CANCEL(3, "取消");
 
     private Integer code;
 

+ 35 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/page/CourseScheduleQueryInfo.java

@@ -0,0 +1,35 @@
+package com.ym.mec.biz.dal.page;
+
+import com.ym.mec.common.page.QueryInfo;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.Date;
+
+/**
+ * @Author Joburgess
+ * @Date 2019/10/11
+ */
+public class CourseScheduleQueryInfo extends QueryInfo {
+
+    @ApiModelProperty(value = "部门编号")
+    private Long organId;
+
+    @ApiModelProperty(value = "上课日期")
+    private Date date;
+
+    public Long getOrganId() {
+        return organId;
+    }
+
+    public void setOrganId(Long organId) {
+        this.organId = organId;
+    }
+
+    public Date getDate() {
+        return date;
+    }
+
+    public void setDate(Date date) {
+        this.date = date;
+    }
+}

+ 20 - 4
mec-biz/src/main/java/com/ym/mec/biz/service/ContractService.java

@@ -24,7 +24,7 @@ public interface ContractService {
 	String queryRegisterContract(Integer userId);
 
 	/**
-	 * 传递课程协议
+	 * 传递乐团课程协议
 	 * @param userId
 	 * @param musicGroupId
 	 * @return
@@ -32,12 +32,28 @@ public interface ContractService {
 	boolean transferMusicGroupCoursesContract(Integer userId, String musicGroupId);
 
 	/**
-	 * 查询课程协议
+	 * 查询乐团课程协议
 	 * @param userId
-	 * @param musicGroupId
+	 * @param vipGroupId
+	 * @return
+	 */
+	String queryMusicGroupCoursesContract(Integer userId, String vipGroupId);
+
+	/**
+	 * 传递VIP课程协议
+	 * @param userId
+	 * @param vipGroupId
+	 * @return
+	 */
+	boolean transferVipGroupCoursesContract(Integer userId, Long vipGroupId);
+
+	/**
+	 * 查询VIP课程协议
+	 * @param userId
+	 * @param vipGroupId
 	 * @return
 	 */
-	String queryMusicGroupCoursesContract(Integer userId, String musicGroupId);
+	String queryVipGroupCoursesContract(Integer userId, Long vipGroupId);
 
 	/**
 	 * 传递商品协议

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

@@ -5,7 +5,9 @@ import com.ym.mec.biz.dal.dto.CourseScheduleDto;
 import com.ym.mec.biz.dal.dto.TeacherAttendanceDto;
 import com.ym.mec.biz.dal.entity.CourseSchedule;
 import com.ym.mec.biz.dal.entity.CourseScheduleComplaints;
+import com.ym.mec.biz.dal.page.CourseScheduleQueryInfo;
 import com.ym.mec.biz.dal.page.StudentCourseScheduleRecordQueryInfo;
+import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.service.BaseService;
 
 import java.util.Date;
@@ -59,6 +61,13 @@ public interface CourseScheduleService extends BaseService<Long, CourseSchedule>
     /**
      * @Author: Joburgess
      * @Date: 2019/9/17
+     * 根据日期获取当日排课信息
+     */
+    PageInfo getCourseSchedulesWithDateByEdu(CourseScheduleQueryInfo queryInfo);
+
+    /**
+     * @Author: Joburgess
+     * @Date: 2019/9/17
      * 根据月份获取乐团在该月有课的日期
      */
     List<Date> getCourseScheduleDateByMonth(Long musicGroupID, Date month);

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

@@ -1,11 +1,16 @@
 package com.ym.mec.biz.service;
 
+import com.ym.mec.biz.dal.dto.BasicUserDto;
 import com.ym.mec.biz.dal.dto.TeacherUserDto;
 import com.ym.mec.biz.dal.entity.Teacher;
 import com.ym.mec.biz.dal.page.TeacherQueryInfo;
+import com.ym.mec.common.entity.ImGroupModel;
 import com.ym.mec.common.page.PageInfo;
+import com.ym.mec.common.page.QueryInfo;
 import com.ym.mec.common.service.BaseService;
 
+import java.util.List;
+
 public interface TeacherService extends BaseService<Integer, Teacher> {
 
     /**
@@ -47,4 +52,20 @@ public interface TeacherService extends BaseService<Integer, Teacher> {
      * 删除教师
      */
     void deleteTeacher(Long userId);
+
+    /**
+     * 获取教师所在群组列表
+     * @param userId
+     * @param search
+     * @return
+     */
+    List<ImGroupModel> queryTeacherGroups(Integer userId,String search);
+
+    /**
+     * 获取和当前教师相关的学员列表
+     * @param id
+     * @param search
+     * @return
+     */
+    List<BasicUserDto> queryGroupStudents(Integer id, String search);
 }

+ 13 - 2
mec-biz/src/main/java/com/ym/mec/biz/service/VipGroupService.java

@@ -8,6 +8,8 @@ import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.service.BaseService;
 
 import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
 
 public interface VipGroupService extends BaseService<Long, VipGroup> {
 
@@ -45,7 +47,7 @@ public interface VipGroupService extends BaseService<Long, VipGroup> {
      * @return com.ym.mec.common.page.PageInfo
      * @describe 获取vip课教学记录
      */
-    PageInfo findVipGroupTeachingRecord(VipGroupTeachingRecordQueryInfo queryInfo);
+    Map<String, Object> findVipGroupTeachingRecord(VipGroupTeachingRecordQueryInfo queryInfo);
 
     /**
      * @Author: Joburgess
@@ -153,6 +155,15 @@ public interface VipGroupService extends BaseService<Long, VipGroup> {
      * @return com.ym.mec.common.page.PageInfo
      * @describe vip财务记录
      */
-    PageInfo findVipGroupSalarys(VipGroupSalaryQueryInfo queryInfo);
+    Map<String, Object> findVipGroupSalarys(VipGroupSalaryQueryInfo queryInfo);
+
+    /**
+     * @Author: Joburgess
+     * @Date: 2019/10/11
+     * @params [courseScheduleId]
+     * @return java.util.List<java.lang.String>
+     * @describe 获取上课签到学员
+     */
+    List<String> findVipGroupAttendanceStudents(Long courseScheduleId);
 
 }

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

@@ -380,19 +380,35 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
     public List<ImGroupModel> queryUserGroups(Integer userId, String search) {
         List<ImGroupModel> imGroupModels = musicGroupDao.queryUserGroups(userId, search);
         List<ImGroupModel> imGroupModels1 = classGroupDao.queryUserGroups(userId, search);
-        if (imGroupModels.size() < 1 || imGroupModels == null) {
-            return imGroupModels1;
-        } else {
+        if(imGroupModels != null && imGroupModels.size() > 0){
             imGroupModels.forEach(e -> {
-                e.setCount(musicGroupDao.countMusicGroupUserNum(e.getId()));
+                //获取创建乐团的老师
+                MusicGroup musicGroup = musicGroupDao.get(e.getId());
+                //获取教学老师id列表
+                Set<Integer> teachers = musicGroupDao.queryTeacherIds(e.getId());
+                teachers.add(musicGroup.getTeamTeacherId());
+                teachers.add(musicGroup.getEducationalTeacherId());
+                teachers.add(musicGroup.getOperatorUserId());
+                teachers.add(musicGroup.getDirectorUserId());
+                teachers.removeAll(Collections.singleton(null));
+                //获取乐团群用户总数
+                e.setCount(musicGroupDao.countMusicGroupUserNum(e.getId()) + teachers.size());
                 e.setId("mg" + e.getId());
             });
+        }else {
+            imGroupModels = new ArrayList<>();
+        }
+        if(imGroupModels1 != null && imGroupModels1.size() > 0){
             imGroupModels1.forEach(e -> {
+                //获取当前班级老师总数
+                Set<Integer> teachers = classGroupDao.queryTeacherIds(e.getId());
+                teachers.removeAll(Collections.singleton(null));
+                e.setCount(e.getCount() + teachers.size());
                 e.setId("cg" + e.getId());
             });
             imGroupModels.addAll(imGroupModels1);
-            return imGroupModels;
         }
+        return imGroupModels;
     }
 
     @Override

+ 252 - 51
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ContractServiceImpl.java

@@ -8,6 +8,7 @@ import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.StringUtils;
@@ -17,14 +18,17 @@ import org.springframework.stereotype.Service;
 
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.biz.dal.dao.MusicGroupPaymentCalenderDao;
 import com.ym.mec.biz.dal.dto.StudentInfo;
 import com.ym.mec.biz.dal.entity.Goods;
+import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender;
 import com.ym.mec.biz.dal.entity.MusicGroupSubjectPlan;
 import com.ym.mec.biz.dal.entity.StudentRegistration;
 import com.ym.mec.biz.dal.entity.Subject;
 import com.ym.mec.biz.dal.entity.SysUserContracts;
 import com.ym.mec.biz.dal.entity.SysUserContracts.ContractType;
 import com.ym.mec.biz.dal.entity.SysUserTsign;
+import com.ym.mec.biz.dal.entity.VipGroup;
 import com.ym.mec.biz.dal.enums.OrderDetailTypeEnum;
 import com.ym.mec.biz.service.ContractService;
 import com.ym.mec.biz.service.MusicGroupSubjectPlanService;
@@ -33,10 +37,12 @@ import com.ym.mec.biz.service.StudentRegistrationService;
 import com.ym.mec.biz.service.SubjectService;
 import com.ym.mec.biz.service.SysUserContractsService;
 import com.ym.mec.biz.service.SysUserTsignService;
+import com.ym.mec.biz.service.VipGroupService;
 import com.ym.mec.common.exception.BizException;
 import com.ym.mec.thirdparty.eseal.ESealPlugin;
 import com.ym.mec.thirdparty.storage.StoragePlugin;
 import com.ym.mec.util.freemarker.FreemarkerTemplateEngine;
+import com.ym.mec.util.money.MoneyUtil;
 import com.ym.mec.util.pdf.PDFUtil;
 
 @Service
@@ -50,17 +56,22 @@ public class ContractServiceImpl implements ContractService {
 
 	@Autowired
 	private SysUserContractsService sysUserContractsService;
-	
+
 	@Autowired
 	private StudentRegistrationService studentRegistrationService;
-	
+
 	@Autowired
 	private StudentPaymentOrderService studentPaymentOrderService;
-	
-    @Autowired
-    private MusicGroupSubjectPlanService musicGroupSubjectPlanService;
-    
-	
+
+	@Autowired
+	private MusicGroupSubjectPlanService musicGroupSubjectPlanService;
+
+	@Autowired
+	private MusicGroupPaymentCalenderDao musicGroupPaymentCalenderDao;
+
+	@Autowired
+	private VipGroupService vipGroupService;
+
 	@Autowired
 	private SubjectService subjectService;
 
@@ -117,7 +128,10 @@ public class ContractServiceImpl implements ContractService {
 
 		// 合成freemarker
 		String srcPdfPath = contractBaseDir + "/register/" + userId + ".pdf";
-		File debtFile = new File(contractBaseDir);
+
+		File srcFile = new File(srcPdfPath);
+
+		File debtFile = new File(srcFile.getParent());
 		if (!debtFile.exists()) {
 			debtFile.mkdirs();
 		}
@@ -127,11 +141,11 @@ public class ContractServiceImpl implements ContractService {
 
 		Map<String, Object> params = new HashMap<String, Object>();
 
-		templateEngine.render(params, "register.ftl", new File(srcPdfPath));
+		templateEngine.render(params, "register.ftl", srcFile);
 
 		// 生成借款协议PDF
 		try {
-			PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(new File(srcPdfPath)), srcPdfPath,
+			PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath,
 					"config/fonts/simsun.ttc");
 		} catch (IOException e) {
 			throw new BizException("生成pdf协议失败", e);
@@ -142,7 +156,7 @@ public class ContractServiceImpl implements ContractService {
 		Date date = new Date();
 		// 上传到oss
 		String dateStrOss = dateFormatOss.format(date);
-		String pdfFilePath = storagePlugin.uploadFile(dateStrOss, new File(srcPdfPath));
+		String pdfFilePath = storagePlugin.uploadFile(dateStrOss, srcFile);
 
 		SysUserContracts sysUserContracts = new SysUserContracts();
 		sysUserContracts.setCreateTime(date);
@@ -152,7 +166,7 @@ public class ContractServiceImpl implements ContractService {
 
 		sysUserContractsService.insert(sysUserContracts);
 
-		FileUtils.deleteQuietly(new File(srcPdfPath));
+		FileUtils.deleteQuietly(srcFile);
 
 		return true;
 	}
@@ -162,7 +176,10 @@ public class ContractServiceImpl implements ContractService {
 
 		// 合成freemarker
 		String srcPdfPath = contractBaseDir + "/register/" + userId + ".pdf";
-		File debtFile = new File(contractBaseDir);
+
+		File srcFile = new File(srcPdfPath);
+
+		File debtFile = new File(srcFile.getParent());
 		if (!debtFile.exists()) {
 			debtFile.mkdirs();
 		}
@@ -172,15 +189,15 @@ public class ContractServiceImpl implements ContractService {
 
 		Map<String, Object> params = new HashMap<String, Object>();
 
-		templateEngine.render(params, "register.ftl", new File(srcPdfPath));
+		templateEngine.render(params, "register.ftl", srcFile);
 
 		String result = "";
 		try {
-			result = FileUtils.readFileToString(new File(srcPdfPath));
+			result = FileUtils.readFileToString(srcFile);
 		} catch (IOException e) {
 			throw new BizException("读取注册协议出错", e);
 		}
-		FileUtils.deleteQuietly(new File(srcPdfPath));
+		FileUtils.deleteQuietly(srcFile);
 
 		return result;
 	}
@@ -195,7 +212,10 @@ public class ContractServiceImpl implements ContractService {
 
 		// 合成freemarker
 		String srcPdfPath = contractBaseDir + "/courses/" + userId + ".pdf";
-		File debtFile = new File(contractBaseDir);
+
+		File srcFile = new File(srcPdfPath);
+
+		File debtFile = new File(srcFile.getParent());
 		if (!debtFile.exists()) {
 			debtFile.mkdirs();
 		}
@@ -204,32 +224,40 @@ public class ContractServiceImpl implements ContractService {
 		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
 
 		Map<String, Object> params = new HashMap<String, Object>();
-		
-		//查询参数信息
+
+		// 查询参数信息
 		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
 		params.put("studentInfo", studentInfo);
-		
-		//课程类型
+
+		// 课程类型
 		params.put("classesType", "乐团团课");
-		
-		//课程费用
+
+		// 课程费用
 		StudentRegistration studentRegistration = studentRegistrationService.queryByUserIdAndMusicGroupId(userId, musicGroupId);
-		if(studentRegistration == null){
+		if (studentRegistration == null) {
 			throw new BizException("用户 报名信息不存在");
 		}
-		MusicGroupSubjectPlan musicGroupSubjectPlan = musicGroupSubjectPlanService.getMusicOneSubjectClassPlan(musicGroupId, studentRegistration.getActualSubjectId());
-		if(musicGroupSubjectPlan == null){
+		MusicGroupSubjectPlan musicGroupSubjectPlan = musicGroupSubjectPlanService.getMusicOneSubjectClassPlan(musicGroupId,
+				studentRegistration.getActualSubjectId());
+		if (musicGroupSubjectPlan == null) {
 			throw new BizException("声部课程费用设置找不到");
 		}
 		params.put("courseFee", musicGroupSubjectPlan.getFee().doubleValue());
-		
-		//收费形式
 
-		templateEngine.render(params, "courses.ftl", new File(srcPdfPath));
+		// 收费形式
+		List<MusicGroupPaymentCalender> calenders = musicGroupPaymentCalenderDao.findByMusicGroupId(musicGroupId);
+
+		if (calenders == null || calenders.size() == 0) {
+			params.put("paymentcalender", "一次性");
+		} else {
+			params.put("paymentcalender", calenders.stream().map(cal -> cal.getPaymentMonth().toString()).collect(Collectors.joining(",")));
+		}
+
+		templateEngine.render(params, "courses.ftl", srcFile);
 
 		// 生成借款协议PDF
 		try {
-			PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(new File(srcPdfPath)), srcPdfPath,
+			PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath,
 					"config/fonts/simsun.ttc");
 		} catch (IOException e) {
 			throw new BizException("生成pdf协议失败", e);
@@ -240,7 +268,7 @@ public class ContractServiceImpl implements ContractService {
 		Date date = new Date();
 		// 上传到oss
 		String dateStrOss = dateFormatOss.format(date);
-		String pdfFilePath = storagePlugin.uploadFile(dateStrOss, new File(srcPdfPath));
+		String pdfFilePath = storagePlugin.uploadFile(dateStrOss, srcFile);
 
 		SysUserContracts sysUserContracts = new SysUserContracts();
 		sysUserContracts.setCreateTime(date);
@@ -250,7 +278,7 @@ public class ContractServiceImpl implements ContractService {
 
 		sysUserContractsService.insert(sysUserContracts);
 
-		FileUtils.deleteQuietly(new File(srcPdfPath));
+		FileUtils.deleteQuietly(srcFile);
 
 		return true;
 	}
@@ -260,7 +288,10 @@ public class ContractServiceImpl implements ContractService {
 
 		// 合成freemarker
 		String srcPdfPath = contractBaseDir + "/courses/" + userId + ".pdf";
-		File debtFile = new File(contractBaseDir);
+
+		File srcFile = new File(srcPdfPath);
+
+		File debtFile = new File(srcFile.getParent());
 		if (!debtFile.exists()) {
 			debtFile.mkdirs();
 		}
@@ -269,15 +300,39 @@ public class ContractServiceImpl implements ContractService {
 		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
 
 		Map<String, Object> params = new HashMap<String, Object>();
-		
+
 		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
 		params.put("studentInfo", studentInfo);
 
-		templateEngine.render(params, "courses.ftl", new File(srcPdfPath));
+		// 课程类型
+		params.put("classesType", "乐团团课");
+
+		// 课程费用
+		StudentRegistration studentRegistration = studentRegistrationService.queryByUserIdAndMusicGroupId(userId, musicGroupId);
+		if (studentRegistration == null) {
+			throw new BizException("用户 报名信息不存在");
+		}
+		MusicGroupSubjectPlan musicGroupSubjectPlan = musicGroupSubjectPlanService.getMusicOneSubjectClassPlan(musicGroupId,
+				studentRegistration.getActualSubjectId());
+		if (musicGroupSubjectPlan == null) {
+			throw new BizException("声部课程费用设置找不到");
+		}
+		params.put("courseFee", musicGroupSubjectPlan.getFee().doubleValue());
+
+		// 收费形式
+		List<MusicGroupPaymentCalender> calenders = musicGroupPaymentCalenderDao.findByMusicGroupId(musicGroupId);
+
+		if (calenders == null || calenders.size() == 0) {
+			params.put("paymentcalender", "一次性");
+		} else {
+			params.put("paymentcalender", calenders.stream().map(cal -> cal.getPaymentMonth().toString()).collect(Collectors.joining(",")));
+		}
+
+		templateEngine.render(params, "courses.ftl", srcFile);
 
 		String result = "";
 		try {
-			result = FileUtils.readFileToString(new File(srcPdfPath));
+			result = FileUtils.readFileToString(srcFile);
 		} catch (IOException e) {
 			throw new BizException("读取课程协议出错", e);
 		}
@@ -287,6 +342,123 @@ public class ContractServiceImpl implements ContractService {
 	}
 
 	@Override
+	public boolean transferVipGroupCoursesContract(Integer userId, Long vipGroupId) {
+		SysUserTsign sysUserTsign = sysUserTsignService.get(userId);
+
+		if (sysUserTsign == null) {
+			return false;
+		}
+
+		// 合成freemarker
+		String srcPdfPath = contractBaseDir + "/courses/" + userId + ".pdf";
+
+		File srcFile = new File(srcPdfPath);
+
+		File debtFile = new File(srcFile.getParent());
+		if (!debtFile.exists()) {
+			debtFile.mkdirs();
+		}
+
+		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
+		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
+
+		Map<String, Object> params = new HashMap<String, Object>();
+
+		// 查询参数信息
+		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
+		params.put("studentInfo", studentInfo);
+
+		// 课程类型
+		params.put("classesType", "VIP课");
+
+		// 课程费用
+		VipGroup vipGroup = vipGroupService.get(vipGroupId);
+		if (vipGroup == null) {
+			throw new BizException("VIP课找不到");
+		}
+		params.put("courseFee", vipGroup.getTotalPrice().doubleValue());
+
+		// 收费形式
+		params.put("paymentcalender", "一次性");
+
+		templateEngine.render(params, "courses.ftl", srcFile);
+
+		// 生成借款协议PDF
+		try {
+			PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath,
+					"config/fonts/simsun.ttc");
+		} catch (IOException e) {
+			throw new BizException("生成pdf协议失败", e);
+		}
+
+		eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);
+
+		Date date = new Date();
+		// 上传到oss
+		String dateStrOss = dateFormatOss.format(date);
+		String pdfFilePath = storagePlugin.uploadFile(dateStrOss, srcFile);
+
+		SysUserContracts sysUserContracts = new SysUserContracts();
+		sysUserContracts.setCreateTime(date);
+		sysUserContracts.setType(ContractType.REGISTER);
+		sysUserContracts.setUrl(pdfFilePath);
+		sysUserContracts.setUserId(userId);
+
+		sysUserContractsService.insert(sysUserContracts);
+
+		FileUtils.deleteQuietly(srcFile);
+
+		return true;
+	}
+
+	@Override
+	public String queryVipGroupCoursesContract(Integer userId, Long vipGroupId) {
+
+		// 合成freemarker
+		String srcPdfPath = contractBaseDir + "/courses/" + userId + ".pdf";
+
+		File srcFile = new File(srcPdfPath);
+
+		File debtFile = new File(srcFile.getParent());
+		if (!debtFile.exists()) {
+			debtFile.mkdirs();
+		}
+
+		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
+		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
+
+		Map<String, Object> params = new HashMap<String, Object>();
+
+		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
+		params.put("studentInfo", studentInfo);
+
+		// 课程类型
+		params.put("classesType", "VIP课");
+
+		// 课程费用
+		VipGroup vipGroup = vipGroupService.get(vipGroupId);
+		if (vipGroup == null) {
+			throw new BizException("VIP课找不到");
+		}
+		params.put("courseFee", vipGroup.getTotalPrice().doubleValue());
+
+		// 收费形式
+		params.put("paymentcalender", "一次性");
+
+		templateEngine.render(params, "courses.ftl", srcFile);
+
+		String result = "";
+		try {
+			result = FileUtils.readFileToString(srcFile);
+		} catch (IOException e) {
+			throw new BizException("读取课程协议出错", e);
+		}
+		FileUtils.deleteQuietly(srcFile);
+
+		return result;
+	}
+
+	@Override
 	public boolean transferGoodsContract(Integer userId, String musicGroupId) {
 		SysUserTsign sysUserTsign = sysUserTsignService.get(userId);
 
@@ -296,7 +468,10 @@ public class ContractServiceImpl implements ContractService {
 
 		// 合成freemarker
 		String srcPdfPath = contractBaseDir + "/goods/" + userId + ".pdf";
-		File debtFile = new File(contractBaseDir);
+
+		File srcFile = new File(srcPdfPath);
+
+		File debtFile = new File(srcFile.getParent());
 		if (!debtFile.exists()) {
 			debtFile.mkdirs();
 		}
@@ -305,23 +480,32 @@ public class ContractServiceImpl implements ContractService {
 		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
 
 		Map<String, Object> params = new HashMap<String, Object>();
-		
-		//查询参数信息
+
+		// 查询参数信息
 		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
 		
-		Subject subject = subjectService.get(studentInfo.getSubject().getId());
+		int subjectId = studentInfo.getSubject().getId();
+
+		Subject subject = subjectService.get(subjectId);
 		studentInfo.setSubject(subject);
-		
+
 		params.put("studentInfo", studentInfo);
-		
+
 		List<Goods> goodsList = studentPaymentOrderService.queryApplyGoodsList(musicGroupId, OrderDetailTypeEnum.MUSICAL);
 		params.put("goodsList", goodsList);
+		
+		MusicGroupSubjectPlan musicGroupSubjectPlan =musicGroupSubjectPlanService.getMusicOneSubjectClassPlan(musicGroupId, subjectId);
+		if (musicGroupSubjectPlan == null) {
+			throw new BizException("声部课程费用设置找不到");
+		}
+		params.put("depositFee", musicGroupSubjectPlan.getDepositFee().doubleValue());
+		params.put("depositFeeFmt", MoneyUtil.toChinese(musicGroupSubjectPlan.getDepositFee().toString()));
 
-		templateEngine.render(params, "goods.ftl", new File(srcPdfPath));
+		templateEngine.render(params, "goods.ftl", srcFile);
 
 		// 生成借款协议PDF
 		try {
-			PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(new File(srcPdfPath)), srcPdfPath,
+			PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath,
 					"config/fonts/simsun.ttc");
 		} catch (IOException e) {
 			throw new BizException("生成pdf协议失败", e);
@@ -332,7 +516,7 @@ public class ContractServiceImpl implements ContractService {
 		Date date = new Date();
 		// 上传到oss
 		String dateStrOss = dateFormatOss.format(date);
-		String pdfFilePath = storagePlugin.uploadFile(dateStrOss, new File(srcPdfPath));
+		String pdfFilePath = storagePlugin.uploadFile(dateStrOss, srcFile);
 
 		SysUserContracts sysUserContracts = new SysUserContracts();
 		sysUserContracts.setCreateTime(date);
@@ -342,7 +526,7 @@ public class ContractServiceImpl implements ContractService {
 
 		sysUserContractsService.insert(sysUserContracts);
 
-		FileUtils.deleteQuietly(new File(srcPdfPath));
+		FileUtils.deleteQuietly(srcFile);
 
 		return true;
 	}
@@ -352,7 +536,10 @@ public class ContractServiceImpl implements ContractService {
 
 		// 合成freemarker
 		String srcPdfPath = contractBaseDir + "/goods/" + userId + ".pdf";
-		File debtFile = new File(contractBaseDir);
+
+		File srcFile = new File(srcPdfPath);
+
+		File debtFile = new File(srcFile.getParent());
 		if (!debtFile.exists()) {
 			debtFile.mkdirs();
 		}
@@ -362,21 +549,35 @@ public class ContractServiceImpl implements ContractService {
 
 		Map<String, Object> params = new HashMap<String, Object>();
 
+		// 查询参数信息
 		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
-		params.put("studentInfo", studentInfo);
 		
+		int subjectId = studentInfo.getSubject().getId();
+
+		Subject subject = subjectService.get(subjectId);
+		studentInfo.setSubject(subject);
+
+		params.put("studentInfo", studentInfo);
+
 		List<Goods> goodsList = studentPaymentOrderService.queryApplyGoodsList(musicGroupId, OrderDetailTypeEnum.MUSICAL);
 		params.put("goodsList", goodsList);
+		
+		MusicGroupSubjectPlan musicGroupSubjectPlan =musicGroupSubjectPlanService.getMusicOneSubjectClassPlan(musicGroupId, subjectId);
+		if (musicGroupSubjectPlan == null) {
+			throw new BizException("声部课程费用设置找不到");
+		}
+		params.put("depositFee", musicGroupSubjectPlan.getDepositFee().doubleValue());
+		params.put("depositFeeFmt", MoneyUtil.toChinese(musicGroupSubjectPlan.getDepositFee().toString()));
 
-		templateEngine.render(params, "goods.ftl", new File(srcPdfPath));
+		templateEngine.render(params, "goods.ftl", srcFile);
 
 		String result = "";
 		try {
-			result = FileUtils.readFileToString(new File(srcPdfPath));
+			result = FileUtils.readFileToString(srcFile);
 		} catch (IOException e) {
 			throw new BizException("读取商品协议出错", e);
 		}
-		FileUtils.deleteQuietly(new File(srcPdfPath));
+		FileUtils.deleteQuietly(srcFile);
 
 		return result;
 	}

+ 32 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleServiceImpl.java

@@ -10,10 +10,12 @@ import com.ym.mec.biz.dal.dto.CourseScheduleDto;
 import com.ym.mec.biz.dal.dto.TeacherAttendanceDto;
 import com.ym.mec.biz.dal.entity.CourseSchedule;
 import com.ym.mec.biz.dal.entity.CourseScheduleComplaints;
+import com.ym.mec.biz.dal.entity.Employee;
 import com.ym.mec.biz.dal.entity.SysConfig;
 import com.ym.mec.biz.dal.enums.AuditStatusEnum;
 import com.ym.mec.biz.dal.enums.ParamEnum;
 import com.ym.mec.biz.dal.enums.YesOrNoEnum;
+import com.ym.mec.biz.dal.page.CourseScheduleQueryInfo;
 import com.ym.mec.biz.dal.page.StudentCourseScheduleRecordQueryInfo;
 import com.ym.mec.biz.service.CourseScheduleService;
 import com.ym.mec.common.dal.BaseDAO;
@@ -145,6 +147,36 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 	}
 
 	@Override
+	public PageInfo getCourseSchedulesWithDateByEdu(CourseScheduleQueryInfo queryInfo) {
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if(null==user){
+			throw new BizException("请登录");
+		}
+		queryInfo.setOrganId(user.getOrganId().longValue());
+		PageInfo pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
+
+		if(Objects.isNull(queryInfo.getDate())){
+			queryInfo.setDate(new Date());
+		}
+
+		Map<String, Object> params = new HashMap<String, Object>();
+		MapUtil.populateMap(params, queryInfo);
+
+		List dataList = null;
+		int count = courseScheduleDao.countCourseSchedulesWithDate(params);
+		if (count > 0) {
+			pageInfo.setTotal(count);
+			params.put("offset", pageInfo.getOffset());
+			dataList = courseScheduleDao.getCourseSchedulesWithDate(params);
+		}
+		if (count == 0) {
+			dataList = new ArrayList<>();
+		}
+		pageInfo.setRows(dataList);
+		return pageInfo;
+	}
+
+	@Override
 	public List<CourseScheduleDto> getTeacherCourseSchedulesWithDate(Date classDate) {
 		if(Objects.isNull(classDate)){
 			throw new BizException("请选择上课日期!");

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

@@ -109,6 +109,11 @@ public class DemoGroupServiceImpl extends BaseServiceImpl<Long, DemoGroup>  impl
 	public void createCourseScheduleAndUpdateOrganId(Long demoGroupId,Long coursePlanId){
 		DemoGroup demoGroup=demoGroupDao.get(demoGroupId);
 
+		DemoGroupCoursesPlan demoGroupCoursesPlan1 = demoGroupCoursesPlanDao.get(coursePlanId);
+		if(demoGroupCoursesPlan1.getStatus()==YesOrNoEnum.YES){
+			throw new BizException("该时段课程已被预约");
+		}
+
 		SysUser user = sysUserFeignService.queryUserInfo();
 
 		//创建班级

+ 3 - 2
mec-biz/src/main/java/com/ym/mec/biz/service/impl/EmployeeServiceImpl.java

@@ -75,7 +75,7 @@ public class EmployeeServiceImpl extends BaseServiceImpl<Integer, Employee>  imp
 	@Override
 	@Transactional(rollbackFor = Exception.class)
 	public void updateEmployee(Employee employee) {
-		Employee employee1 = employeeDao.get(employee.getUserId());
+		Employee employee1 = employeeDao.get(employee.getId());
 		if(null==employee1){
 			employeeDao.insert(employee);
 		}else{
@@ -98,7 +98,7 @@ public class EmployeeServiceImpl extends BaseServiceImpl<Integer, Employee>  imp
 
 		queryInfo.setOrganId(user.getOrganId().longValue());
 		PageInfo<EmployeeDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
-		Map<String, Object> params = new HashMap<String, Object>();
+		Map<String, Object> params = new HashMap<>();
 		MapUtil.populateMap(params, queryInfo);
 
 		List<EmployeeDto> dataList = null;
@@ -107,6 +107,7 @@ public class EmployeeServiceImpl extends BaseServiceImpl<Integer, Employee>  imp
 			pageInfo.setTotal(count);
 			params.put("offset", pageInfo.getOffset());
 			dataList = employeeDao.queryEmployByOrganId(params);
+
 		}
 		if (count == 0) {
 			dataList = new ArrayList<>();

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

@@ -7,6 +7,7 @@ import java.util.Date;
 import java.util.List;
 import java.util.UUID;
 
+import com.ym.mec.biz.dal.entity.*;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Propagation;
@@ -24,13 +25,6 @@ import com.ym.mec.biz.dal.dao.StudentPaymentOrderDao;
 import com.ym.mec.biz.dal.dto.BasicUserDto;
 import com.ym.mec.biz.dal.dto.MusicCardDto;
 import com.ym.mec.biz.dal.dto.SubFeeSettingDto;
-import com.ym.mec.biz.dal.entity.MusicGroup;
-import com.ym.mec.biz.dal.entity.MusicGroupBuildLog;
-import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender;
-import com.ym.mec.biz.dal.entity.MusicGroupPaymentEntities;
-import com.ym.mec.biz.dal.entity.MusicGroupSubjectGoodsGroup;
-import com.ym.mec.biz.dal.entity.MusicGroupSubjectPlan;
-import com.ym.mec.biz.dal.entity.StudentPaymentOrder;
 import com.ym.mec.biz.dal.enums.ClassGroupStudentStatusEnum;
 import com.ym.mec.biz.dal.enums.ClassGroupTypeEnum;
 import com.ym.mec.biz.dal.enums.DealStatusEnum;

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

@@ -10,14 +10,17 @@ import com.ym.mec.biz.dal.entity.*;
 import com.ym.mec.biz.dal.enums.CourseStatusEnum;
 import com.ym.mec.biz.dal.enums.ParamEnum;
 import com.ym.mec.biz.dal.enums.SignStatusEnum;
+import com.ym.mec.biz.dal.enums.YesOrNoEnum;
 import com.ym.mec.biz.dal.page.TeacherAttendanceQueryInfo;
 import com.ym.mec.biz.service.CourseHomeworkService;
 import com.ym.mec.biz.service.TeacherAttendanceService;
 import com.ym.mec.common.dal.BaseDAO;
+import com.ym.mec.common.exception.BizException;
 import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.service.impl.BaseServiceImpl;
 import com.ym.mec.util.collection.MapUtil;
 
+import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -51,29 +54,52 @@ public class TeacherAttendanceServiceImpl extends BaseServiceImpl<Long, TeacherA
 	@Override
 	public void addTeacherAttendanceRecord(TeacherSignOutDto teacherSignOutDto) {
 		SysUser user = sysUserFeignService.queryUserInfo();
-		TeacherAttendance teacherAttendance=teacherSignOutDto.getTeacherAttendanceInfo();
-		teacherAttendance.setTeacherId(Long.valueOf(user.getId()));
+		if(Objects.isNull(user)){
+			throw new BizException("请登录");
+		}
+
+		if(Objects.isNull(teacherSignOutDto.getTeacherAttendanceInfo().getCourseScheduleId())){
+			throw new BizException("请选择课程!");
+		}
+
+		TeacherAttendance teacherAttendance=teacherAttendanceDao.findByTeacherAttendanceInfo(user.getId().longValue(),teacherSignOutDto.getTeacherAttendanceInfo().getCourseScheduleId());
+
+		if(Objects.isNull(teacherAttendance)){
+			if(teacherSignOutDto.getTeacherAttendanceInfo().getStatus()==SignStatusEnum.YES_QUIT){
+				throw new BizException("该课程还未签到,不能进行签退操作!");
+			}
+			teacherAttendance=teacherSignOutDto.getTeacherAttendanceInfo();
+			teacherAttendance.setTeacherId(Long.valueOf(user.getId()));
+		}
+
 		CourseSchedule courseSchedule=new CourseSchedule();
 		TeacherAttendanceDto currentCourseDetail = courseScheduleDao.getCurrentCourseDetail(teacherAttendance.getCourseScheduleId());
 		courseSchedule.setId(currentCourseDetail.getCourseScheduleId());
+
+		teacherAttendance.setMusicGroupId(currentCourseDetail.getMusicGroupId());
+		teacherAttendance.setClassGroupId(currentCourseDetail.getClassId());
 		Date date = new Date();
 		if(teacherAttendance.getStatus()!= SignStatusEnum.YES_QUIT){
 			Long timeGap=(date.getTime()-currentCourseDetail.getStartClassTime().getTime())/1000/60;
 			if(timeGap<= ParamEnum.TEACHER_ATTENDANCE_TIME_GAP.getCode()){
-				teacherAttendance.setStatus(SignStatusEnum.SIGN);
+				teacherAttendance.setSignInStatus(YesOrNoEnum.YES);
 			}else{
-				teacherAttendance.setStatus(SignStatusEnum.EXCEPTION);
+				if(StringUtils.isEmpty(teacherAttendance.getRemark())){
+					throw new BizException("当前为异常签到,请填写原因!");
+				}
+				teacherAttendance.setSignInStatus(YesOrNoEnum.NO);
 			}
+			teacherAttendance.setSignInTime(date);
 			courseSchedule.setStatus(CourseStatusEnum.UNDERWAY);
+			teacherAttendanceDao.insert(teacherAttendance);
 		}else{
+			teacherAttendance.setSignOutStatus(YesOrNoEnum.YES);
+			teacherAttendance.setSignOutTime(date);
+			teacherAttendance.setCreateTime(date);
 			courseSchedule.setStatus(CourseStatusEnum.OVER);
+			teacherAttendanceDao.update(teacherAttendance);
 		}
 		courseScheduleDao.update(courseSchedule);
-		teacherAttendance.setMusicGroupId(currentCourseDetail.getMusicGroupId());
-		teacherAttendance.setClassGroupId(currentCourseDetail.getClassId());
-		teacherAttendance.setSignInTime(date);
-		teacherAttendance.setCreateTime(date);
-		teacherAttendanceDao.insert(teacherAttendance);
 		if(teacherAttendance.getStatus()==SignStatusEnum.YES_QUIT){
 			//更新课次
 			ClassGroup classGroup=new ClassGroup();

+ 55 - 7
mec-biz/src/main/java/com/ym/mec/biz/service/impl/TeacherServiceImpl.java

@@ -5,16 +5,18 @@ import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.auth.api.enums.SysUserType;
 import com.ym.mec.auth.api.enums.YesOrNoEnum;
-import com.ym.mec.biz.dal.dao.OrganizationDao;
-import com.ym.mec.biz.dal.dao.SubjectDao;
-import com.ym.mec.biz.dal.dao.TeacherDao;
+import com.ym.mec.biz.dal.dao.*;
+import com.ym.mec.biz.dal.dto.BasicUserDto;
+import com.ym.mec.biz.dal.entity.MusicGroup;
 import com.ym.mec.biz.dal.entity.Teacher;
 import com.ym.mec.biz.dal.page.TeacherQueryInfo;
 import com.ym.mec.biz.service.TeacherService;
 import com.ym.mec.common.dal.BaseDAO;
+import com.ym.mec.common.entity.ImGroupModel;
 import com.ym.mec.common.entity.ImResult;
 import com.ym.mec.common.entity.ImUserModel;
 import com.ym.mec.common.page.PageInfo;
+import com.ym.mec.common.page.QueryInfo;
 import com.ym.mec.common.service.impl.BaseServiceImpl;
 import com.ym.mec.im.ImFeignService;
 import org.apache.commons.lang3.StringUtils;
@@ -22,8 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Date;
-import java.util.List;
+import java.util.*;
 
 @Service
 public class TeacherServiceImpl extends BaseServiceImpl<Integer, Teacher>  implements TeacherService {
@@ -33,6 +34,10 @@ public class TeacherServiceImpl extends BaseServiceImpl<Integer, Teacher>  imple
 	@Autowired
 	private SubjectDao subjectDao;
 	@Autowired
+	private MusicGroupDao musicGroupDao;
+	@Autowired
+	private ClassGroupDao classGroupDao;
+	@Autowired
 	private OrganizationDao organizationDao;
 	@Autowired
 	private SysUserFeignService sysUserFeignService;
@@ -90,6 +95,49 @@ public class TeacherServiceImpl extends BaseServiceImpl<Integer, Teacher>  imple
 	}
 
 	@Override
+	public List<ImGroupModel> queryTeacherGroups(Integer userId,String search) {
+		//获取教师所在乐团列表
+		List<ImGroupModel> imGroupModels =  musicGroupDao.queryTeacherGroups(userId,search);
+		//获取教师所在班级列表
+		List<ImGroupModel> imGroupModels1 =  classGroupDao.queryTeacherGroups(userId,search);
+		if(imGroupModels != null && imGroupModels.size() > 0){
+			imGroupModels.forEach(e -> {
+				//获取创建乐团的老师
+				MusicGroup musicGroup = musicGroupDao.get(e.getId());
+				//获取教学老师id列表
+				Set<Integer> teachers = musicGroupDao.queryTeacherIds(e.getId());
+				teachers.add(musicGroup.getTeamTeacherId());
+				teachers.add(musicGroup.getEducationalTeacherId());
+				teachers.add(musicGroup.getOperatorUserId());
+				teachers.add(musicGroup.getDirectorUserId());
+				teachers.removeAll(Collections.singleton(null));
+				//获取乐团群用户总数
+				e.setCount(musicGroupDao.countMusicGroupUserNum(e.getId()) + teachers.size());
+				e.setId("mg" + e.getId());
+			});
+		}else {
+			imGroupModels = new ArrayList<>();
+		}
+		if(imGroupModels1 != null && imGroupModels1.size() > 0){
+			imGroupModels1.forEach(e -> {
+				//获取当前班级老师总数
+				Set<Integer> teachers = classGroupDao.queryTeacherIds(e.getId());
+				teachers.removeAll(Collections.singleton(null));
+				e.setCount(e.getCount() + teachers.size());
+				e.setId("cg" + e.getId());
+			});
+			imGroupModels.addAll(imGroupModels1);
+		}
+
+		return imGroupModels;
+	}
+
+	@Override
+	public List<BasicUserDto> queryGroupStudents(Integer teacherId, String search) {
+		return teacherDao.queryGroupStudents(teacherId,search);
+	}
+
+	@Override
 	public PageInfo<Teacher> queryPageDetail(TeacherQueryInfo queryInfo) {
 		PageInfo<Teacher> pageInfo = queryPage(queryInfo);
 		List<Teacher> teachers = pageInfo.getRows();
@@ -109,10 +157,10 @@ public class TeacherServiceImpl extends BaseServiceImpl<Integer, Teacher>  imple
 		if(teacher != null){
 			if(StringUtils.isNotEmpty(teacher.getFlowOrganRange())){
 				List<String> organNames = organizationDao.findByOrganIds(teacher.getFlowOrganRange());
-				teacher.setFlowOrganRange(JSON.toJSONString(organNames));
+				teacher.setFlowOrganRange(StringUtils.join(organNames,","));
 			}
 			if(StringUtils.isNotEmpty(teacher.getSubjectId())){
-				teacher.setSubjectId(JSON.toJSONString(subjectDao.findBySubIds(teacher.getSubjectId())));
+				teacher.setSubjectId(StringUtils.join(subjectDao.findBySubIds(teacher.getSubjectId()),","));
 			}
 		}
 		return teacher;

+ 64 - 9
mec-biz/src/main/java/com/ym/mec/biz/service/impl/VipGroupServiceImpl.java

@@ -19,7 +19,6 @@ 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 org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -43,6 +42,8 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 	@Autowired
 	private CourseScheduleService courseScheduleService;
 	@Autowired
+	private CourseScheduleDao courseScheduleDao;
+	@Autowired
 	private VipGroupDefaultClassesUnitPriceDao vipGroupDefaultClassesUnitPriceDao;
 	@Autowired
 	private VipGroupActivityDao vipGroupActivityDao;
@@ -72,6 +73,8 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 	private CourseScheduleTeacherSalaryDao courseScheduleTeacherSalaryDao;
     @Autowired
 	private ImFeignService imFeignService;
+    @Autowired
+	private SubjectDao subjectDao;
 
 	@Override
 	public BaseDAO<Long, VipGroup> getDAO() {
@@ -302,15 +305,17 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 	@Override
 	public PageInfo findVipGroups(VipGroupQueryInfo queryInfo) {
 		PageInfo pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
-		Map<String, Object> params = new HashMap<String, Object>();
+		Map<String, Object> params = new HashMap<>();
 		MapUtil.populateMap(params, queryInfo);
 
-		List dataList = null;
+		List<VipGroup> dataList = null;
 		int count = vipGroupDao.countVipGroupByOrgan(params);
 		if (count > 0) {
 			pageInfo.setTotal(count);
 			params.put("offset", pageInfo.getOffset());
 			dataList = vipGroupDao.findAllByOrgan(params);
+			List<Long> vipGroupIds = dataList.stream().map(vipGroup -> vipGroup.getId()).collect(Collectors.toList());
+
 		}
 		if (count == 0) {
 			dataList = new ArrayList<>();
@@ -320,9 +325,12 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 	}
 
 	@Override
-	public PageInfo findVipGroupTeachingRecord(VipGroupTeachingRecordQueryInfo queryInfo) {
+	public Map<String, Object> findVipGroupTeachingRecord(VipGroupTeachingRecordQueryInfo queryInfo) {
+		if(Objects.isNull(queryInfo.getVipGroupId())){
+			throw new BizException("请指定vip课程!");
+		}
 		PageInfo pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
-		Map<String, Object> params = new HashMap<String, Object>();
+		Map<String, Object> params = new HashMap<>();
 		MapUtil.populateMap(params, queryInfo);
 
 		List dataList = null;
@@ -336,7 +344,13 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 			dataList = new ArrayList<>();
 		}
 		pageInfo.setRows(dataList);
-		return pageInfo;
+		TeachingRecordBaseInfo classTimes = vipGroupDao.getClassTimes(queryInfo.getVipGroupId());
+		classTimes.setIsSalaryNum(vipGroupDao.countIsSalaryNum(queryInfo.getVipGroupId()));
+		classTimes.setComplaintsNum(vipGroupDao.countComplaintsNum(queryInfo.getVipGroupId()));
+		Map<String,Object> result=new HashMap<>();
+		result.put("pageInfo",pageInfo);
+		result.put("baseInfo",classTimes);
+		return result;
 	}
 
 	@Override
@@ -369,7 +383,11 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 
 	@Override
 	public VipGroupManageDetailDto getVipGroupDetail(Long vipGroupId) {
+		if(Objects.isNull(vipGroupId)){
+			throw new BizException("请指定vip课程");
+		}
 		VipGroupManageDetailDto vipGroupBaseInfo = vipGroupDao.getVipGroupBaseInfo(vipGroupId);
+		vipGroupBaseInfo.setSubjectName(StringUtils.join(subjectDao.findBySubIds(vipGroupBaseInfo.getSubjectIdList()),","));
 		return vipGroupBaseInfo;
 	}
 
@@ -598,7 +616,7 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 	}
 
 	@Override
-	public PageInfo findVipGroupSalarys(VipGroupSalaryQueryInfo queryInfo) {
+	public Map<String, Object> findVipGroupSalarys(VipGroupSalaryQueryInfo queryInfo) {
 
     	if(Objects.isNull(queryInfo.getVipGroupId())){
     		throw new BizException("请指定vip课程!");
@@ -608,17 +626,54 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 		Map<String, Object> params = new HashMap<String, Object>();
 		MapUtil.populateMap(params, queryInfo);
 
-		List dataList = null;
+		List<VipGroupSalaryDto> dataList = null;
 		int count = courseScheduleTeacherSalaryDao.countVipGroupSalarys(params);
 		if (count > 0) {
 			pageInfo.setTotal(count);
 			params.put("offset", pageInfo.getOffset());
 			dataList = courseScheduleTeacherSalaryDao.findVipGroupSalarys(params);
+			dataList.forEach(vipGroupSalaryDto -> {
+				if(Objects.isNull(vipGroupSalaryDto.getExpectSalary())){
+					vipGroupSalaryDto.setExpectSalary(new BigDecimal(0));
+				}
+				if(Objects.isNull(vipGroupSalaryDto.getActualSalary())){
+					vipGroupSalaryDto.setActualSalary(new BigDecimal(0));
+					vipGroupSalaryDto.setIsSalary(YesOrNoEnum.NO);
+				}else{
+					vipGroupSalaryDto.setIsSalary(YesOrNoEnum.YES);
+				}
+				vipGroupSalaryDto.setDeductionFee(vipGroupSalaryDto.getExpectSalary().subtract(vipGroupSalaryDto.getActualSalary()));
+			});
 		}
 		if (count == 0) {
 			dataList = new ArrayList<>();
 		}
 		pageInfo.setRows(dataList);
-		return pageInfo;
+
+		VipGroupSalaryBaseInfo vipGroupSalaryBaseInfo = vipGroupDao.getVipGroupSalaryInfo(queryInfo.getVipGroupId());
+		if(Objects.isNull(vipGroupSalaryBaseInfo)){
+			vipGroupSalaryBaseInfo=new VipGroupSalaryBaseInfo();
+		}
+		if(Objects.isNull(vipGroupSalaryBaseInfo.getExpectTotalSalary())){
+			vipGroupSalaryBaseInfo.setExpectTotalSalary(new BigDecimal(0));
+		}
+		if(Objects.isNull(vipGroupSalaryBaseInfo.getTotalSalary())){
+			vipGroupSalaryBaseInfo.setTotalSalary(new BigDecimal(0));
+		}
+		vipGroupSalaryBaseInfo.setTotalFeeDeduction(vipGroupSalaryBaseInfo.getExpectTotalSalary().subtract(vipGroupSalaryBaseInfo.getTotalSalary()));
+		vipGroupSalaryBaseInfo.setFeeDeductionNum(vipGroupDao.countVipGroupDeductionNum(queryInfo.getVipGroupId()));
+
+		Map<String,Object> result=new HashMap<>();
+		result.put("pageInfo",pageInfo);
+		result.put("baseInfo",vipGroupSalaryBaseInfo);
+		return result;
+	}
+
+	@Override
+	public List<String> findVipGroupAttendanceStudents(Long courseScheduleId) {
+    	if(Objects.isNull(courseScheduleId)){
+    		throw new BizException("请指定课程");
+		}
+		return courseScheduleDao.findStudentNamesByCourseSchedule(courseScheduleId);
 	}
 }

+ 11 - 11
mec-biz/src/main/resources/config/contracts/courses.ftl

@@ -80,21 +80,21 @@
         <div style="display: flex;">乙方:
             <div style="flex: 1 auto;">
                 <div class="iInfo">
-                    <span>家长姓名 ${studentInfo.realName}</span>
-                    <span>电话: ${studentInfo.phone}</span>
+                    <span>家长姓名 ${studentInfo.realName!}</span>
+                    <span>电话: ${studentInfo.phone!}</span>
                 </div>
                 <div class="iInfo">
-                    <span>身份证号:${studentInfo.idCardNo}</span>
+                    <span>身份证号:${studentInfo.idCardNo!}</span>
                 </div>
                 <div class="iInfo">
-                    <span>学生姓名:${studentInfo.name}</span>
-                    <span>所在班级:${studentInfo.grade} ${studentInfo.clazz}</span>
+                    <span>学生姓名:${studentInfo.name!}</span>
+                    <span>所在班级:${studentInfo.grade!} ${studentInfo.clazz!}</span>
                 </div>
                 <div class="iInfo">
-                    <span>所在声部:${studentInfo.subject.name}</span>
+                    <span>所在声部:${studentInfo.subject.name!}</span>
                 </div>
             </div>
-        </div> 
+        </div>
             (本协议中“乙方“指学员及家长;”乙方学员“仅指参加甲方课程的学员;”乙方家长“仅指乙方学员的法定监护人。)
         </div>
         为进一步提升器乐教学质量和服务品质,保证学员学习进度,明确培训各方的权责,经甲、乙双方协商一致,特订立本协议,以便共同遵守。
@@ -102,9 +102,9 @@
         <h2>一、课程信息</h2>
         
         <div class="iInfoContent">
-            <span>授课类别:{{proto}}</span>
-            <span>课程费用:{{proto}}</span>
-            <span>收费形式:{{proto}}</span>
+            <span>授课类别:${classesType}</span>
+            <span>课程费用:${courseFee?string("0.00")}</span>
+            <span>收费形式:${paymentcalender}</span>
         </div>
 
         <h2>二、行为规范</h2>
@@ -156,7 +156,7 @@
             <div class="sign">甲方签章:深圳大雅乐盟网络教育股份有限公司
                 <span>日期:${.now?string("yyyy年MM月dd日")}</span>
             </div>
-            <div class="sign">乙方签字:${studentInfo.realName}
+            <div class="sign">乙方签字:${studentInfo.realName!}
                 <span>日期:${.now?string("yyyy年MM月dd日")} </span>
             </div>
         </div>

+ 14 - 14
mec-biz/src/main/resources/config/contracts/goods.ftl

@@ -1,5 +1,5 @@
-<!DOCTYPE html>
-<html lang="en" style="font-size: 100px;">
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" style="font-size: 100px;">
 <head>
     <meta charset="utf-8" />
     <meta http-equiv="X-UA-Compatible" content="IE=edge" />
@@ -79,30 +79,30 @@
         <div style="display: flex;">乙方:
             <div style="flex: 1 auto;">
                 <div class="iInfo">
-                    <span>家长姓名 ${studentInfo.realName}</span>
-                    <span>电话: ${studentInfo.phone}</span>
+                    <span>家长姓名 ${studentInfo.realName!}</span>
+                    <span>电话: ${studentInfo.phone!}</span>
                 </div>
                 <div class="iInfo">
-                    <span>身份证号:${studentInfo.idCardNo}</span>
+                    <span>身份证号:${studentInfo.idCardNo!}</span>
                 </div>
                 <div class="iInfo">
-                    <span>学生姓名:${studentInfo.name}</span>
-                    <span>所在班级:${studentInfo.grade} ${studentInfo.clazz}</span>
+                    <span>学生姓名:${studentInfo.name!}</span>
+                    <span>所在班级:${studentInfo.grade!} ${studentInfo.clazz!}</span>
                 </div>
                 <div class="iInfo">
-                    <span>所在声部:${studentInfo.subject.name}</span>
+                    <span>所在声部:${studentInfo.subject.name!}</span>
                 </div>
             </div>
         </div>                     
         
-        为了促进学校乐团健康、持续发展,让更多的学生在校园拥有良好的器乐学习机会,甲方基于公益普惠的原则,决定提供价值${goodsList[0].marketPrice?string("#.##")}元的KEY品牌全新乐器供乙方在学校乐团期间免费使用。现根据《中华人民共和国合同法》等法律法规规定,为明确甲乙双方权利义务,经协商一致,就乙方借用乐器事宜达成如下协议:
+        为了促进学校乐团健康、持续发展,让更多的学生在校园拥有良好的器乐学习机会,甲方基于公益普惠的原则,决定提供价值${goodsList[0].marketPrice?string("0.00")}元的KEY品牌全新乐器供乙方在学校乐团期间免费使用。现根据《中华人民共和国合同法》等法律法规规定,为明确甲乙双方权利义务,经协商一致,就乙方借用乐器事宜达成如下协议:
         <h2>一、甲方权利与义务:</h2>
-        1、乙方所借用的乐器为甲方资产,乐器所有权归属甲方所有,甲方有权在必要时向乙方收回借用乐器并退还押金。<br/>
-        2、甲方所提供乐器为全新的KEY品牌乐器。在乙方签订本协议、交纳乐器使用押金后,甲方即将乐器交付给乙方供其在学校乐团期间免费使用。<br/>
+1、乙方所借用的乐器为甲方资产,乐器所有权归属甲方所有,甲方有权在必要时向乙方收回借用乐器并退还押金。<br/>
+2、甲方所提供乐器为全新的KEY品牌乐器。在乙方签订本协议、交纳乐器使用押金后,甲方即将乐器交付给乙方供其在学校乐团期间免费使用。<br/>
         3、乙方归还乐器时,双方当面当场验收,经甲方维修技师检验确认乐器无人为损坏、可正常使用后,甲方在七个工作日内全额不计息退还乙方已交纳的押金。<br/>
         4、如乙方已购买甲方乐器保养服务,甲方需在乙方借用期间协助乙方处理乐器维修和保养问题。
         <h2>二、乙方权利与义务:</h2>
-        1、乙方在签订本协议、交纳乐器使用押金¥{{proto}}元(大写人民币{{proto}}元整)后,享有所借用乐器在学校乐团期间的免费使用权。乙方应当爱惜乐器并妥善保管,不得将该乐器转租、借用、出售、典当、质押或抵押,也不得将乐器交于非专业人士使用。乐器借用政策,每位团员仅可享受一次,退团后再次加入乐团的,将无法享受乐器借用政策。<br/>
+        1、乙方在签订本协议、交纳乐器使用押金¥${depositFee?string("0.00")}元(大写人民币${depositFeeFmt})后,享有所借用乐器在学校乐团期间的免费使用权。乙方应当爱惜乐器并妥善保管,不得将该乐器转租、借用、出售、典当、质押或抵押,也不得将乐器交于非专业人士使用。乐器借用政策,每位团员仅可享受一次,退团后再次加入乐团的,将无法享受乐器借用政策。<br/>
         2、乐器日常维护由乙方自行完成,每次练习完毕后需按老师要求对乐器进行擦拭并装箱保管。如因人为原因(包括但不限于磕、碰、摔等)造成乐器损坏的,乙方需自行承担维修费用;如因非甲方原因导致乐器无法正常使用(正常使用磨损除外)或乐器毁损、灭失、遗失的,乙方须按本协议中明示的乐器团购价格进行赔付。<br/>
         3、当乙方决定不再继续乐团学习时,应在退团之日起1日内将其借用的乐器归还甲方,双方当面当场验收,经甲方维修技师检验确认乐器无人为损坏、可正常使用后,乙方可按照本协议约定获得已交纳的押金;经甲方维修技师检验,乐器存在损坏的,乙方应承担相应的维修费用,如乐器已经无法正常使用的,乙方须按本协议中明示的乐器团购价格进行赔付,甲方有权从应退还乙方的押金中先行扣除维修费用、赔付费用,如甲方扣除押金后仍然不足以弥补维修费用、赔付费用的,甲方有权继续要求乙方支付剩余费用。<br/>
         4、乙方终止乐团学习2个月内,仍未将乐器归还给甲方的,则视为乙方违约,乙方所交押金甲方有权不予退还,同时乙方须按乐器团购价格进行赔付。
@@ -113,7 +113,7 @@
         </div>
         <div class="iInfo">
             <span>型号:${goodsList[0].specification}</span>
-            <span>团购价格:${goodsList[0].groupPurchasePrice?string("#.##")}</span>
+            <span>团购价格:${goodsList[0].groupPurchasePrice?string("0.00")}</span>
         </div>
 
         <h2>四、违约责任</h2>  
@@ -138,7 +138,7 @@
             <div class="sign">甲方签章:深圳大雅乐盟网络教育股份有限公司
                 <span>日期:${.now?string("yyyy年MM月dd日")}</span>
             </div>
-            <div class="sign">乙方签字:${studentInfo.realName}
+            <div class="sign">乙方签字:${studentInfo.realName!}
                 <span>日期:${.now?string("yyyy年MM月dd日")} </span>
             </div>
         </div>

+ 202 - 216
mec-biz/src/main/resources/config/contracts/register.ftl

@@ -1,222 +1,208 @@
 <!DOCTYPE html>
 <html lang="en" style="font-size: 100px;">
 <head>
-    <meta charset="utf-8" />
-    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
-    <meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
-    <meta http-equiv="Pragma" content="no-cache" />
-    <meta http-equiv="Cache-Control" content="no-cache" />
-    <meta http-equiv="Expires" content="0" />
-    <title>APP用户注册及乐团注册服务协议</title>
-    <style type="text/css">
-        body { margin: 0; }
-        header {
-            height: .40rem;
-            line-height: .40rem;
-            color: #000;
-            font-size: .17rem;
-            background: #fff;
-            box-shadow: 0px 1px 8px 0px rgba(0, 0, 0, 0.07);
-            text-align: center;
-        }
-        header .back {
-            width: .2rem;
-            height: .2rem;
-            position: absolute;
-            left: .12rem;
-            top: .1rem;
-        }
-        .container {
-            padding: .22rem .2rem .3rem;
-            font-size: .14rem;
-        }
-        h1 {
-            font-size: .16rem;
-            text-align: center;
-        }
-        h2 {
-            font-size: .16rem;
-            font-weight: bold;
-            padding-top: .15rem;
-        }
-        h3 {
-            font-size: .14rem;
-            font-weight: bold;
-        }
-        .signature {
-            display: flex;
-            padding-top: .5rem;
-        }
-        .signature .sign {
-            flex: 1;
-            position: relative;
-        }
-        .signature span {
-            display: block;
-        }
-        .signature .cachet {
-            position: absolute;
-            top: -.6rem;
-            left: 0;
-            width: 1.5rem;
-            height: 1.5rem;
-        }
-        .iInfo {
-            display: flex;
-        }
-        .iInfo span {
-            flex: 1;
-        }
-        .iInfoContent, .iInfoContent span {
-            display: block;
-        }
-    </style>
+<meta charset="utf-8" />
+<meta http-equiv="X-UA-Compatible" content="IE=edge" />
+<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
+<meta http-equiv="Pragma" content="no-cache" />
+<meta http-equiv="Cache-Control" content="no-cache" />
+<meta http-equiv="Expires" content="0" />
+<title>APP用户注册及乐团注册服务协议</title>
+<style>
+body { margin: 0; }
+header {
+height: .40rem;
+line-height: .40rem;
+color: #000;
+font-size: .17rem;
+background: #fff;
+box-shadow: 0px 1px 8px 0px rgba(0, 0, 0, 0.07);
+text-align: center;
+}
+header .back {
+width: .2rem;
+height: .2rem;
+position: absolute;
+left: .12rem;
+top: .1rem;
+}
+.container {
+padding: .22rem .2rem .3rem;
+font-size: .14rem;
+}
+h1 {
+font-size: .16rem;
+text-align: center;
+}
+h2 {
+font-size: .16rem;
+font-weight: bold;
+padding-top: .15rem;
+}
+h3 {
+font-size: .14rem;
+font-weight: bold;
+}
+.signature {
+display: flex;
+padding-top: .5rem;
+}
+.signature .sign {
+flex: 1;
+position: relative;
+}
+.signature span {
+display: block;
+}
+.signature .cachet {
+position: absolute;
+top: -.6rem;
+left: 0;
+width: 1.5rem;
+height: 1.5rem;
+}
+.iInfo {
+display: flex;
+}
+.iInfo span {
+flex: 1;
+}
+.iInfoContent, .iInfoContent span {
+display: block;
+}
+</style>
 </head>
-<body style="font-family:'SimSun'">
-    <div class="container">
-        <h1>《APP用户注册及乐团注册服务协议》</h1>
-
-        欢迎用户使用{{proto}}(下称“本软件”),请用户在使用本软件前仔细阅读本协议。如用户不同意本协议任何条款,请勿在本软件注册账号或使用大雅乐盟基于本软件提供的服务(下称“本服务”)。用户点击“注册”、“登录”或“同意”等按钮或使用本服务后,本协议即构成大雅乐盟与用户之间具有约束力的法律文件。
-        <h2>一、提示</h2>
-        1. 用户在使用本软件或本服务前,应当认真阅读本协议。请用户务必审慎阅读、充分理解各条款内容,特别是免除或者限制责任的条款、法律适用和争议解决条款。免除或者限制责任的条款将以粗体下划线标识,用户应重点阅读,并自行选择接受或不接受。如用户对本协议有任何疑问,可联系大雅乐盟。<br/>
-        2. 当用户按照注册页面提示填写信息、阅读并同意本协议且完成全部注册程序,或登录本软件,或使用本服务后,即表示用户已充分阅读、理解并接受本协议的全部内容,并与大雅乐盟达成一致,成为大雅乐盟的用户。阅读本协议的过程中,如果用户不同意或不接受本协议任何条款,用户应立即停止注册、登录本软件或使用本服务。<br/>
-        3. 大雅乐盟可以随时更新本协议的各项条款,包括但不限于增加新的服务类型或功能,更新后的协议条款一经大雅乐盟在本软件公布或更新即生效并代替原来的协议条款,大雅乐盟不会另行通知用户,用户可以及时关注并阅读大雅乐盟更新的本协议最新版本;用户继续使用本软件或本服务的,视为用户接受本协议的最新更新版本;用户不接受本协议最新版本的,应立即停止使用本软件或本服务。<br/>
-        4. 特别提醒:未满18周岁的用户应在法定监护人的陪同下阅读后,并且应在法定监护人的同意和指导下注册和/或使用本软件及本服务。
-        <h2>二、关于本软件及本服务的重要提示</h2>
-        1. 用户使用本服务需要下载本软件的客户端版本,本软件的客户端版本提供包括但不限于 iOS、Android等多个应用版本,用户必须选择与所安装终端设备相匹配的软件版本。 用户可以直接从大雅乐盟的网站上获取本软件,也可以从得到大雅乐盟授权的第三方获取。如果用户从未经大雅乐盟授权的第三方获取本软件或与本软件名称相同的安装程序,大雅乐盟无法保证该软件能够正常使用,并对因此给用户造成的损失不予负责。下载安装程序后,用户需要按照该程序提示的步骤正确安装。<br/>
-        2. 为了改善用户体验、完善服务内容,大雅乐盟将不断努力开发新的服务,并为用户不时提供软件更新(这些更新可能会采取软件替换、修改、功能强化、版本升级等形式)。大雅乐盟有权不经向用户特别通知而对本软件进行更新,或者对本软件的部分功能效果进行改变或限制。新版本发布后,旧版本的软件可能无法使用。大雅乐盟无法保证旧版本软件继续可用及相应的客户服务,请用户随时核对并下载最新版本。<br/>
-        3. 用户理解并同意:为了向用户提供有效的服务,本软件会利用用户终端设备的处理器和带宽等资源,用户使用本软件时,需要接入互联网、移动互联网,此时可能产生数据流量的费用,用户需自行向运营商了解相关资费信息,并自行承担接入互联网、移动互联网所需的费用(包括但不限于上网费、通讯费)以及使用本软件及本服务必需的设备(包括但不限于电脑、手机等移动终端设备)。<br/>
-        4. 大雅乐盟给予用户一项个人的、不可转让及非排他性的许可,以使用本软件。用户可以为非商业目的在单一台终端设备上安装、使用、显示、运行本软件。用户不得为商业运营目的安装、使用、运行本软件,不可以对该软件或者该软件运行过程中释放到任何计算机终端内存中的数据及该软件运行过程中客户端与服务器端的交互数据进行复制、更改、修改、挂接运行或创作任何衍生作品,形式包括但不限于使用插件、外挂或非经授权的第三方工具/服务接入本软件和相关系统。<br/>
-        5. 本协议其他条款未明示授权的其他一切权利仍由大雅乐盟保留,用户在行使这些权利时须另外取得大雅乐盟的书面许可。大雅乐盟如果未行使前述任何权利,并不构成对该权利的放弃。
-        
-        <h2>三、服务内容</h2> 
-        1. 大雅乐盟:即{{proto}}。<br/>
-        2. 本服务是基于互联网及移动互联网,通过本软件向用户提供【直播教学、录播教学、智能打分、学员管理等】功能服务。大雅乐盟以乐团为单位对用户进行管理,用户注册本软件即视为用户同意参加乐团,遵守乐团的各项制度和管理。用户在使用本软件或本服务过程中发生任何问题的,可以与大雅乐盟乐团老师联系和处理。具体内容及具体规则以用户与大雅乐盟签署的协议及/或本软件公示的内容为准。<br/>
-        3. 服务功能介绍:<br/>
-        直播教学:{{proto}}<br/>
-        录播教学:{{proto}}<br/>
-        智能打分:{{proto}}<br/>
-        学员管理:{{proto}}<br/>
-        4. 本软件规则包括但不限于大雅乐盟通过官网、本软件等途径发布的全部规则、细则、解读、说明公告等。<br/>
-        5. 服务费用<br/>
-        5.1 用户使用本软件或本服务的费用以用户与大雅乐盟签署的协议及/或本软件公示的内容为准。<br/>
-        6. 乐团管理<br/>
-        6.1大雅乐盟有权对用户进行管理,制定乐团各项制度,对用户在乐团的日常行为进行管理。<br/>
-        
-        <h2>四、用户账户注册、使用与管理</h2>  
-        1. 用户资格<br/>
-        用户开始使用本软件或本服务前,应当具备中华人民共和国法律规定的与用户行为相对应的民事行为能力,否则用户的法定监护人应依照法律规定承担因此而导致的一切后果。<br/>
-        2. 账户说明<br/>
-        用户使用本软件时,应当注册账户,注册时可以使用{{proto}},用户应当提供并填写真实、合法、准确、完整的资料和信息,并在相关信息变更时在1个工作日内在本软件更新。因用户提供或填写的资料、信息不符合上述要求而导致的任何问题及后果,应由用户自行承担,大雅乐盟不对此承担任何责任。当用户按照注册页面提示填写信息、阅读并同意本协议且完成全部注册程序后,用户可获得本软件账户并成为本软件用户。<br/>
-        3. 账户安全规范<br/>
-        3.1 用户的账户由用户自行设置、保管。建议用户务必保管好用户的账户及密码,当用户每次使用完本软件时,应以正确步骤离开本软件。用户了解并同意,确保用户账户及密码的机密安全是用户的责任。用户将对利用该账户及密码所进行的一切行动及言论负完全的责任,并同意以下事项:<br/>
-        3.1.1 用户主动泄露账户、密码或遭受他人攻击、诈骗等行为导致的损失及后果,均由用户自行承担;<br/>
-        3.1.2 用户的账户只限用户本人使用,未经大雅乐盟事先书面同意,不得将账户提供、转让、许可、出售给任何第三方;<br/>
-        3.1.3 擅自使用他人账户及密码的,大雅乐盟及其合法授权主体有权追究实际使用人的法律责任;<br/>
-        3.1.4 用户应当设置符合本软件要求的密码,并妥善保管和保护密码,不得随意告诉他人,并定期更新密码。大雅乐盟同时还建议用户通过使用复杂密码等方式,不要使用过于简单的词语或数字,以保证用户的账号、密码安全;<br/>
-        3.1.5 如发现任何未经授权使用用户账户访问和/或使用本软件或其他可能导致用户账户遭窃、遗失的情况,建议用户立即通知大雅乐盟。<br/>
-        3.2 大雅乐盟有权基于单方独立判断,在其认为可能发生危害交易安全等情形时,不经通知而先行暂停、中断或终止向用户提供本协议项下的全部或部分用户服务,并将注册资料移除或删除,且无需对用户或任何第三方承担任何责任。前述情形包括但不限于:<br/>
-        3.2.1 大雅乐盟发现异常交易或有理由认为存在违法违规情形时;<br/>
-        3.2.2 大雅乐盟认为用户账户被冒用或其他大雅乐盟认为有风险的其他情形。<br/>
-        4. 用户忘记或丢失账户、密码时,可以按照本软件的申诉途径凭初始注册资料找回账户,但大雅乐盟并不承诺用户忘记或丢失账户后一定能通过申诉途径找回该账户。本软件的账户或密码找回/重设机制仅负责识别用户在申诉申请上所填资料与系统记录资料的一致性,而无法识别申诉人是否系真正账户使用权人。用户因忘记或丢失账户或密码而遭致任何法律责任或损失的,用户应自行承担全部法律责任及损失,大雅乐盟不对此承担任何责任。<br/>
-        5. 用户理解并同意,本软件同大多数互联网软件一样,可能会受多种因素影响,包括但不限于用户原因、网络服务质量、社会环境等;也可能会受各种安全问题的侵扰,包括但不限于他人非法利用用户资料,进行现实中的骚扰;用户下载安装的其他软件或访问的其他网站中可能含有病毒、木马程序或其他恶意程序,威胁用户的终端设备信息和数据安全,继而影响本软件的正常使用等。因此,用户应加强信息安全及个人信息的保护意识,注意密码保护,以免遭受损失。<br/>
-        
-        <h2>五、服务使用规则</h2>
-        1. 用户使用本软件或本服务时,不得实施下列行为:<br/>
-        1.1使用本软件或本服务的过程中出现下列情形:<br/>
-        1.1.1破坏宪法所确定的基本原则的;<br/>
-        1.1.2危害国家安全、泄露国家秘密、颠覆国家政权、破坏国家统一的;<br/>
-        1.1.3损害国家荣誉和利益的;<br/>
-        1.1.4煽动民族仇恨、民族歧视,破坏民族团结的;<br/>
-        1.1.5破坏国家宗教政策,宣扬邪教和封建迷信的;<br/>
-        1.1.6散布谣言,扰乱社会秩序,破坏社会稳定的;<br/>
-        1.1.7散布淫秽、色情、赌博、暴力、凶杀、恐怖或者教唆犯罪的;<br/>
-        1.1.8侮辱或者诽谤他人,侵害他人合法权益的;<br/>
-        1.1.9含有法律法规、行政规章所禁止的其他内容的;<br/>
-        1.2 发布、传送、传播、储存侵害他人合法权利(包括但不限于名誉权、肖像权、知识产权、商业秘密等)的内容;<br/>
-        1.3 发布、传送、传播、储存与他人隐私、个人信息或资料有关的内容;<br/>
-        1.4 发布、传送、传播虚假、骚扰、营销、广告、诱导分享等相关的内容;<br/>
-        1.5 违反法律法规或干扰、破坏大雅乐盟、本软件的正常运营的其他内容。<br/>
-        2. 未经大雅乐盟事先书面同意,用户使用本软件时不得有下列行为:<br/>
-        2.1 以创建相同、类似或竞争服务为目的访问本软件或使用本服务;<br/>
-        2.2 删除、遮掩、修改本软件及其副本上关于著作权的声明;<br/>
-        2.3 对本软件或本服务(包括但不限于服务或其内容中的广告或赞助内容)进行任何形式的许可、出售、租赁、转让、发行或做其他商业用途;<br/>
-        2.4 通过修改或伪造软件运行中的指令、数据,或者增加、删减、变动软件的功能或运行效果,或者将用于上述用途的软件、方法进行运营或向公众传播,无论是否基于商业目的;<br/>
-        2.5 通过非大雅乐盟开发、授权的第三方软件、插件、外挂、系统,登录或使用本软件或本服务;<br/>
-        2.6 自行或者授权他人、第三方软件对本软件及其组件、模块、数据进行干扰,或在本软件或利用本服务上传或发布病毒、蠕虫、恶意代码、故意破坏或改变系统或数据的软件;<br/>
-        2.7 其他未经大雅乐盟明示授权的行为。<br/>
-        3. 用户内容是指用户上传、提供信息和资料或以其他方式使用本软件与本服务时产生的所有内容(包括但不限于用户信息、资料、图片或其他内容),用户是用户内容的唯一的责任人,应当承担因用户内容披露而导致的用户或任何第三方被识别的风险。<br/>
-        4. 用户充分了解并同意,用户必须为自己注册账号下的一切行为负责,包括用户所发表的任何内容以及由此产生的任何后果。用户应对本服务中的内容自行加以判断,并承担因使用内容而引起的所有风险,包括因对内容的正确性、完整性或实用性的依赖而产生的风险。大雅乐盟无法且不会对因前述风险而导致的任何损失或损害承担责任。<br/>
-        5. 用户应服从大雅乐盟乐团的管理,用户在乐团出现下列情形的,大雅乐盟有权对用户作出警告,用户收到警告后仍然不遵守大雅乐盟的管理制度的,大雅乐盟有权对用户作出退团等处分:<br/>
-        5.1上课、排练时不遵守纪律,影响乐团其他团员的正常上课、排练;<br/>
-        5.2不服从乐团老师的管理和指导;<br/>
-        5.3一个学期内发生两次及以上缺席乐团上课、排练行为;<br/>
-        5.4一个学期内发生两次及以上未按老师要求回传视频作业的情形;<br/>
-        5.5连续{{proto}}天不练习,影响乐团团员和乐团的整体水平的。<br/>
-        6. 用户在每次参加乐团排练、训练时,应按专业老师要求带齐训练所需乐器、教材乐谱、乐谱本、铅笔及乐器护理等学习用品,并提前10分钟到达排练场地,做好准备工作;始终保持排练、训练场地的清洁卫生;如遇到特殊情况无法参加乐团排练、训练时,应提前一天向乐团老师请假。<br/>
-        7. 因用户个人原因未能按时上课的,视为该用户放弃该次上课,学校乐团声部训练不因用户请假而停止整个声部课教学,如用户因此给乐团造成任何不良影响的,用户应尽力弥补并消除该不良影响。<br/>
-        8. 用户应保证每日练习时间不少于20分钟,并按专业老师要求通过本软件回传周视频作业。<br/>
-        9. 退团:用户如因自身原因拟退出乐团的,应向学校申请退团,并获得学校的同意退团批准,再经用户家长确认后,方可退团。<br/>
-
-        
-        <h2>六、第三方链接及服务</h2>
-        1. 本软件或本服务可能保留有第三方网站或网址的链接,访问这些链接将由用户自己做出决定,大雅乐盟并不就这些链接上所提供的任何信息、数据、观点、图片、陈述或建议的准确性、完整性、充分性和可靠性提供承诺或保证。大雅乐盟没有审查过任何第三方网站,对这些网站及其内容不进行控制,也不负任何责任。如果用户决定访问任何与本站链接的第三方网站,其可能带来的结果和风险全部由用户自己承担。<br/>
-        2. 用户在使用本软件中第三方提供的产品或服务时,除遵守本协议约定外,还应遵守第三方的用户协议。大雅乐盟和第三方对可能出现的纠纷在法律规定和约定的范围内各自承担责任。因用户使用本软件或要求大雅乐盟提供特定服务时,本软件可能会调用第三方系统或者通过第三方支持用户的使用或访问,使用或访问的结果由该第三方提供(包括但不限于第三方通过公众账号提供的服务,或通过开放平台接入的内容等),大雅乐盟不保证通过第三方提供服务及内容的安全性、准确性、有效性及其他不确定的风险,由此若引发的任何争议及损害,与大雅乐盟无关,大雅乐盟不承担任何责任。<br/>
-        3. 用户已知晓并同意大雅乐盟提供本服务(无论是免费服务还是有偿服务)还可能基于第三方如合作单位(包括但不限于电信运营商)提供的技术支持等服务获得。如果因第三方提供的服务给用户增加任何成本或造成任何损失的,大雅乐盟会协助用户与第三方进行沟通和处理,如因此发生维修、更换等费用的,应由用户自行承担,大雅乐盟不对此承担任何法律责任和赔偿责任。<br/>
-        
-        <h2>七、知识产权的保护以及保密</h2>
-        1. 大雅乐盟的商标、商号、Logo、图形及其组合,以及大雅乐盟的其他标识、产品和服务名称均为大雅乐盟或大雅乐盟关联公司所有,未经大雅乐盟书面授权,任何人不得以任何方式展示、使用或作其他处理,也不得向任何第三方表明或让其误认为其有权展示、使用或作其他处理。<br/>
-        2. 大雅乐盟提供的培训、课程相关的全部内容(包括但不限于培训课程设置、培训课件、教材等)的知识产权均归大雅乐盟单独和完整所有。用户应当保护大雅乐盟的知识产权,只能用于自身学习之目的,未经大雅乐盟事先书面同意,不得擅自将培训课程相关的任何内容进行复制、复印、影音、拍摄或进行摘要等措施后以转让、出售、赠与或其他任何形式提供给任何第三方,否则大雅乐盟有权追究其法律责任。<br/>
-        3. 大雅乐盟为提供服务而使用的任何软件(包括但不限于软件中所含的任何图象、照片、动画、录像、录音、音乐、文字和附加程序、随附的帮助材料)的一切权利均属于该软件的著作权人,未经该软件的著作权人许可,用户不得对该软件进行反向工程(reverse engineer)、反向编译(decompile)或反汇编(disassemble)。<br/>
-        4. 用户已经了解并同意:在大雅乐盟提供的所有服务器上的数据(包括但不限于虚拟物品等)全部归大雅乐盟所有。在不影响用户正常接收服务的情况下,大雅乐盟有权决定保留或不保留服务器上的全部或部分数据。<br/>
-        5. 用户已经了解并同意:大雅乐盟有权将本协议项下大雅乐盟所有的知识产权授权第三方使用,在变更产品运营商时,大雅乐盟可以将其运营的产品或服务以及与该在产品或服务相关的归大雅乐盟所有的知识产权转让给新的产品运营商。<br/>
-        6. 用户使用大雅乐盟提供的本软件或本服务期间获取的文件、资料、表格等信息,包括但不限于有关合作资料、营销资料等,无论是口头、书面的或是电子文件形式的,均属大雅乐盟的商业秘密,用户必须对这些商业秘密严格遵守保密义务,不得向外透露,也不得使用这些商业秘密为自己或他人谋取利益。<br/>
-        
-        <h2>八、违约条款</h2>
-        1. 用户违反本协议约定时即构成违约情形,大雅乐盟有权要求用户采取及时的补救措施,消除违约后果,并有权终止本协议。如用户的违约行为使大雅乐盟及/或关联公司遭受损失(包括自身的直接经济损失、商誉损失及对外支付的赔偿金、和解款、律师费、诉讼费等间接经济损失)的,用户应赔偿大雅乐盟及/或关联公司的上述全部损失。<br/>
-        2. 用户理解并同意,如用户的行为导致第三方向大雅乐盟及/或关联公司主张权利或任何索赔、要求或损失的,大雅乐盟及/或关联公司在对第三人承担赔偿义务后可向用户追偿与此相关的全部损失。<br/>
-        
-        <h2>九、协议终止</h2>
-        1. 用户有权通过以下任一方式终止本协议:<br/>
-        1.1用户自行注销用户的账户的;<br/>
-        1.2用户按照本协议约定方式退出乐团的;<br/>
-        1.3 变更事项生效或服务协议更新时,用户停止使用并明示不愿接受变更事项或明示不愿接受更新后的服务协议的;<br/>
-        1.4 用户明示不愿继续使用本软件或本服务,且符合本协议终止条件的。<br/>
-        2. 出现以下情况时,大雅乐盟可以终止本协议:<br/>
-        2.1 用户违反本协议约定的,大雅乐盟依据违约条款终止本协议,或对用户处以退团处分的;<br/>
-        2.2 用户的账户被大雅乐盟依据本协议进行注销等清理的;<br/>
-        2.3 用户在使用本软件或本服务时存在侵犯他人合法权益或其他严重违法违规行为的;<br/>
-        2.4 不可抗力导致本协议不能履行的(“不可抗力”是指双方不可预见、或可以预见但不能避免并或克服的客观情况,该事件妨碍、影响或延误任何一方根据合同履行其全部或部分义务。该事件包括但不限于政府行为、法律或规定的发布或修订,自然灾害、战争、网络堵塞或中断、黑客袭击或任何其他类似事件),且该不可抗力持续30天以上的;<br/>
-        2.5 根据相关法律法规规定大雅乐盟应当终止服务或大雅乐盟认为需终止服务的其他情形。<br/>
-        3. 协议终止后的处理<br/>
-        本协议终止后,除法律有明确规定外,大雅乐盟无义务向用户或用户指定的第三方披露用户账户中的任何信息。<br/>
-
-        <h2>十、责任限制</h2>
-        1. 用户使用本软件或本服务的风险应由用户自行承担,大雅乐盟对本软件不作任何类型的担保,不论是明示的、默示的保证和条件,包括但不限于本软件的适销性、适用性、无病毒、无疏忽或无技术瑕疵问题、所有权和无侵权的明示或默示担保和条件,对在任何情况下因使用或不能使用本软件所产生的直接、间接、偶然、特殊及后续的损害及风险,大雅乐盟不承担任何责任。<br/>
-        2. 用户明确理解和同意,大雅乐盟不对因下述任一情况而导致的损害赔偿承担责任,包括但不限于利润、商誉、使用、数据等方面的损失或其它无形损失的损害赔偿:<br/>
-        1.1 大雅乐盟向用户免费提供的任何产品或者服务;<br/>
-        1.2 大雅乐盟向用户赠送的任何产品或者服务;<br/>
-        1.3 对于用户使用本软件上可能涉及由第三方所有、控制或者运营的网站或平台提供的服务及其导致的风险;<br/>
-        1.4 因用户的过错导致的任何损失,该过错包括但不限于:决策失误、操作不当、遗忘或泄露密码、密码被他人破解、用户使用的计算机系统被第三方侵入、用户向大雅乐盟发送的指令信息不明确或存在歧义、用户下载非法或不明程序、用户委托他人代理交易时他人恶意或不当操作而造成的损失;<br/>
-        1.5 信息网络设备连接故障,电脑、通讯或其他系统出现故障,不能进行数据传输、保存的;<br/>
-        1.6 本软件或其服务器停机维护期间;<br/>
-        1.7 不可抗力因素导致的任何损失;<br/>
-        1.8 大雅乐盟依据本协议约定终止协议时。<br/>
-        3. 用户理解并同意,因大雅乐盟过错导致用户不能享受相应服务,大雅乐盟承担相应责任的最高限额不超过用户实际支付的当次服务费用总额。<br/>
-        4. 大雅乐盟努力保障用户的知情权,如主动中断或终止部分或全部网络服务,应提前90日在大雅乐盟服务平台以公告通知、app推送等方式通知。<br/>
-         
-        <h2>十一、隐私权保护政策</h2>
-        用户及用户的监护人同意,大雅乐盟向用户提供本服务时,会收集、使用必要的用户个人信息,包括但不限于用户姓名、性别、年龄、学校、班级、联系方式、用户监护人的姓名及联系方式等,并将收集到的信息用于提供本服务必需的目的和场景。大雅乐盟不会收集与提供本服务无关的用户个人信息,具体隐私权保护政策详见大雅乐盟或本软件公示的《隐私政策》。<br/>
-         
-        <h2>十二、争议解决及适用法律</h2>
-        1. 本协议及其修订的有效性、履行、解释及争议解决,均适用中华人民共和国大陆地区法律。<br/>
-        2. 用户与大雅乐盟之间就本协议发生的任何纠纷或争议,首先应友好协商解决,协商不成的,应将纠纷或争议提交至大雅乐盟所在地有管辖权的法院管辖。<br/>
-
-        <h2>十三、其他</h2>
-        1. 如本协议中的任何条款无论因何种原因导致全部或部分无效或不具有执行力的,则该条款应视为自始不存在且不影响本协议其他条款的效力,此时该条款可被新的条款所取代,以保证最大限度地接近双方意图、确保本协议要求的经济目的,以及实现原有条款的意图。<br/>
-        2. 本协议中的标题仅为方便而设,本身并无实际涵义,不能作为本协议涵义解释的依据。<br/>
-        3. 如用户对本软件、本服务或本协议内容有任何疑问、意见或建议,用户可联系大雅乐盟,联系电话:{{proto}},大雅乐盟将及时回复用户的请求。<br/>
-
-    </div>
+<body>
+<div class="container">
+<h1>《APP用户注册及乐团注册服务协议》</h1>
+<p>欢迎用户使用{{proto}}(下称“本软件”),请用户在使用本软件前仔细阅读本协议。如用户不同意本协议任何条款,请勿在本软件注册账号或使用大雅乐盟基于本软件提供的服务(下称“本服务”)。用户点击“注册”、“登录”或“同意”等按钮或使用本服务后,本协议即构成大雅乐盟与用户之间具有约束力的法律文件。</p>
+<h2>一、提示</h2>
+<p>1. 用户在使用本软件或本服务前,应当认真阅读本协议。请用户务必审慎阅读、充分理解各条款内容,特别是免除或者限制责任的条款、法律适用和争议解决条款。免除或者限制责任的条款将以粗体下划线标识,用户应重点阅读,并自行选择接受或不接受。如用户对本协议有任何疑问,可联系大雅乐盟。</p>
+<p>2. 当用户按照注册页面提示填写信息、阅读并同意本协议且完成全部注册程序,或登录本软件,或使用本服务后,即表示用户已充分阅读、理解并接受本协议的全部内容,并与大雅乐盟达成一致,成为大雅乐盟的用户。阅读本协议的过程中,如果用户不同意或不接受本协议任何条款,用户应立即停止注册、登录本软件或使用本服务。</p>
+<p>3. 大雅乐盟可以随时更新本协议的各项条款,包括但不限于增加新的服务类型或功能,更新后的协议条款一经大雅乐盟在本软件公布或更新即生效并代替原来的协议条款,大雅乐盟不会另行通知用户,用户可以及时关注并阅读大雅乐盟更新的本协议最新版本;用户继续使用本软件或本服务的,视为用户接受本协议的最新更新版本;用户不接受本协议最新版本的,应立即停止使用本软件或本服务。</p>
+<p>4. 特别提醒:未满18周岁的用户应在法定监护人的陪同下阅读后,并且应在法定监护人的同意和指导下注册和/或使用本软件及本服务。
+<h2>二、关于本软件及本服务的重要提示</h2>
+<p>1. 用户使用本服务需要下载本软件的客户端版本,本软件的客户端版本提供包括但不限于 iOS、Android等多个应用版本,用户必须选择与所安装终端设备相匹配的软件版本。 用户可以直接从大雅乐盟的网站上获取本软件,也可以从得到大雅乐盟授权的第三方获取。如果用户从未经大雅乐盟授权的第三方获取本软件或与本软件名称相同的安装程序,大雅乐盟无法保证该软件能够正常使用,并对因此给用户造成的损失不予负责。下载安装程序后,用户需要按照该程序提示的步骤正确安装。</p>
+<p>2. 为了改善用户体验、完善服务内容,大雅乐盟将不断努力开发新的服务,并为用户不时提供软件更新(这些更新可能会采取软件替换、修改、功能强化、版本升级等形式)。大雅乐盟有权不经向用户特别通知而对本软件进行更新,或者对本软件的部分功能效果进行改变或限制。新版本发布后,旧版本的软件可能无法使用。大雅乐盟无法保证旧版本软件继续可用及相应的客户服务,请用户随时核对并下载最新版本。</p>
+<p>3. 用户理解并同意:为了向用户提供有效的服务,本软件会利用用户终端设备的处理器和带宽等资源,用户使用本软件时,需要接入互联网、移动互联网,此时可能产生数据流量的费用,用户需自行向运营商了解相关资费信息,并自行承担接入互联网、移动互联网所需的费用(包括但不限于上网费、通讯费)以及使用本软件及本服务必需的设备(包括但不限于电脑、手机等移动终端设备)。</p>
+<p>4. 大雅乐盟给予用户一项个人的、不可转让及非排他性的许可,以使用本软件。用户可以为非商业目的在单一台终端设备上安装、使用、显示、运行本软件。用户不得为商业运营目的安装、使用、运行本软件,不可以对该软件或者该软件运行过程中释放到任何计算机终端内存中的数据及该软件运行过程中客户端与服务器端的交互数据进行复制、更改、修改、挂接运行或创作任何衍生作品,形式包括但不限于使用插件、外挂或非经授权的第三方工具/服务接入本软件和相关系统。</p>
+<p>5. 本协议其他条款未明示授权的其他一切权利仍由大雅乐盟保留,用户在行使这些权利时须另外取得大雅乐盟的书面许可。大雅乐盟如果未行使前述任何权利,并不构成对该权利的放弃。
+<h2>三、服务内容</h2> 
+<p>1. 大雅乐盟:即{{proto}}。</p>
+<p>2. 本服务是基于互联网及移动互联网,通过本软件向用户提供【直播教学、录播教学、智能打分、学员管理等】功能服务。大雅乐盟以乐团为单位对用户进行管理,用户注册本软件即视为用户同意参加乐团,遵守乐团的各项制度和管理。用户在使用本软件或本服务过程中发生任何问题的,可以与大雅乐盟乐团老师联系和处理。具体内容及具体规则以用户与大雅乐盟签署的协议及/或本软件公示的内容为准。</p>
+<p>3. 服务功能介绍:</p>
+<p>直播教学:{{proto}}</p>
+<p>录播教学:{{proto}}</p>
+<p>智能打分:{{proto}}</p>
+<p>学员管理:{{proto}}</p>
+<p>4. 本软件规则包括但不限于大雅乐盟通过官网、本软件等途径发布的全部规则、细则、解读、说明公告等。</p>
+<p>5. 服务费用</p>
+<p>5.1 用户使用本软件或本服务的费用以用户与大雅乐盟签署的协议及/或本软件公示的内容为准。</p>
+<p>6. 乐团管理</p>
+<p>6.1大雅乐盟有权对用户进行管理,制定乐团各项制度,对用户在乐团的日常行为进行管理。</p>
+<h2>四、用户账户注册、使用与管理</h2>  
+<p>1. 用户资格</p>
+<p>用户开始使用本软件或本服务前,应当具备中华人民共和国法律规定的与用户行为相对应的民事行为能力,否则用户的法定监护人应依照法律规定承担因此而导致的一切后果。</p>
+<p>2. 账户说明</p>
+<p>用户使用本软件时,应当注册账户,注册时可以使用{{proto}},用户应当提供并填写真实、合法、准确、完整的资料和信息,并在相关信息变更时在1个工作日内在本软件更新。因用户提供或填写的资料、信息不符合上述要求而导致的任何问题及后果,应由用户自行承担,大雅乐盟不对此承担任何责任。当用户按照注册页面提示填写信息、阅读并同意本协议且完成全部注册程序后,用户可获得本软件账户并成为本软件用户。</p>
+<p>3. 账户安全规范</p>
+<p>3.1 用户的账户由用户自行设置、保管。建议用户务必保管好用户的账户及密码,当用户每次使用完本软件时,应以正确步骤离开本软件。用户了解并同意,确保用户账户及密码的机密安全是用户的责任。用户将对利用该账户及密码所进行的一切行动及言论负完全的责任,并同意以下事项:</p>
+<p>3.1.1 用户主动泄露账户、密码或遭受他人攻击、诈骗等行为导致的损失及后果,均由用户自行承担;</p>
+<p>3.1.2 用户的账户只限用户本人使用,未经大雅乐盟事先书面同意,不得将账户提供、转让、许可、出售给任何第三方;</p>
+<p>3.1.3 擅自使用他人账户及密码的,大雅乐盟及其合法授权主体有权追究实际使用人的法律责任;</p>
+<p>3.1.4 用户应当设置符合本软件要求的密码,并妥善保管和保护密码,不得随意告诉他人,并定期更新密码。大雅乐盟同时还建议用户通过使用复杂密码等方式,不要使用过于简单的词语或数字,以保证用户的账号、密码安全;</p>
+<p>3.1.5 如发现任何未经授权使用用户账户访问和/或使用本软件或其他可能导致用户账户遭窃、遗失的情况,建议用户立即通知大雅乐盟。</p>
+<p>3.2 大雅乐盟有权基于单方独立判断,在其认为可能发生危害交易安全等情形时,不经通知而先行暂停、中断或终止向用户提供本协议项下的全部或部分用户服务,并将注册资料移除或删除,且无需对用户或任何第三方承担任何责任。前述情形包括但不限于:</p>
+<p>3.2.1 大雅乐盟发现异常交易或有理由认为存在违法违规情形时;</p>
+<p>3.2.2 大雅乐盟认为用户账户被冒用或其他大雅乐盟认为有风险的其他情形。</p>
+<p>4. 用户忘记或丢失账户、密码时,可以按照本软件的申诉途径凭初始注册资料找回账户,但大雅乐盟并不承诺用户忘记或丢失账户后一定能通过申诉途径找回该账户。本软件的账户或密码找回/重设机制仅负责识别用户在申诉申请上所填资料与系统记录资料的一致性,而无法识别申诉人是否系真正账户使用权人。用户因忘记或丢失账户或密码而遭致任何法律责任或损失的,用户应自行承担全部法律责任及损失,大雅乐盟不对此承担任何责任。</p>
+<p>5. 用户理解并同意,本软件同大多数互联网软件一样,可能会受多种因素影响,包括但不限于用户原因、网络服务质量、社会环境等;也可能会受各种安全问题的侵扰,包括但不限于他人非法利用用户资料,进行现实中的骚扰;用户下载安装的其他软件或访问的其他网站中可能含有病毒、木马程序或其他恶意程序,威胁用户的终端设备信息和数据安全,继而影响本软件的正常使用等。因此,用户应加强信息安全及个人信息的保护意识,注意密码保护,以免遭受损失。</p>
+<h2>五、服务使用规则</h2>
+<p>1. 用户使用本软件或本服务时,不得实施下列行为:</p>
+<p>1.1使用本软件或本服务的过程中出现下列情形:</p>
+<p>1.1.1破坏宪法所确定的基本原则的;</p>
+<p>1.1.2危害国家安全、泄露国家秘密、颠覆国家政权、破坏国家统一的;</p>
+<p>1.1.3损害国家荣誉和利益的;</p>
+<p>1.1.4煽动民族仇恨、民族歧视,破坏民族团结的;</p>
+<p>1.1.5破坏国家宗教政策,宣扬邪教和封建迷信的;</p>
+<p>1.1.6散布谣言,扰乱社会秩序,破坏社会稳定的;</p>
+<p>1.1.7散布淫秽、色情、赌博、暴力、凶杀、恐怖或者教唆犯罪的;</p>
+<p>1.1.8侮辱或者诽谤他人,侵害他人合法权益的;</p>
+<p>1.1.9含有法律法规、行政规章所禁止的其他内容的;</p>
+<p>1.2 发布、传送、传播、储存侵害他人合法权利(包括但不限于名誉权、肖像权、知识产权、商业秘密等)的内容;</p>
+<p>1.3 发布、传送、传播、储存与他人隐私、个人信息或资料有关的内容;</p>
+<p>1.4 发布、传送、传播虚假、骚扰、营销、广告、诱导分享等相关的内容;</p>
+<p>1.5 违反法律法规或干扰、破坏大雅乐盟、本软件的正常运营的其他内容。</p>
+<p>2. 未经大雅乐盟事先书面同意,用户使用本软件时不得有下列行为:</p>
+<p>2.1 以创建相同、类似或竞争服务为目的访问本软件或使用本服务;</p>
+<p>2.2 删除、遮掩、修改本软件及其副本上关于著作权的声明;</p>
+<p>2.3 对本软件或本服务(包括但不限于服务或其内容中的广告或赞助内容)进行任何形式的许可、出售、租赁、转让、发行或做其他商业用途;</p>
+<p>2.4 通过修改或伪造软件运行中的指令、数据,或者增加、删减、变动软件的功能或运行效果,或者将用于上述用途的软件、方法进行运营或向公众传播,无论是否基于商业目的;</p>
+<p>2.5 通过非大雅乐盟开发、授权的第三方软件、插件、外挂、系统,登录或使用本软件或本服务;</p>
+<p>2.6 自行或者授权他人、第三方软件对本软件及其组件、模块、数据进行干扰,或在本软件或利用本服务上传或发布病毒、蠕虫、恶意代码、故意破坏或改变系统或数据的软件;</p>
+<p>2.7 其他未经大雅乐盟明示授权的行为。</p>
+<p>3. 用户内容是指用户上传、提供信息和资料或以其他方式使用本软件与本服务时产生的所有内容(包括但不限于用户信息、资料、图片或其他内容),用户是用户内容的唯一的责任人,应当承担因用户内容披露而导致的用户或任何第三方被识别的风险。</p>
+<p>4. 用户充分了解并同意,用户必须为自己注册账号下的一切行为负责,包括用户所发表的任何内容以及由此产生的任何后果。用户应对本服务中的内容自行加以判断,并承担因使用内容而引起的所有风险,包括因对内容的正确性、完整性或实用性的依赖而产生的风险。大雅乐盟无法且不会对因前述风险而导致的任何损失或损害承担责任。</p>
+<p>5. 用户应服从大雅乐盟乐团的管理,用户在乐团出现下列情形的,大雅乐盟有权对用户作出警告,用户收到警告后仍然不遵守大雅乐盟的管理制度的,大雅乐盟有权对用户作出退团等处分:</p>
+<p>5.1上课、排练时不遵守纪律,影响乐团其他团员的正常上课、排练;</p>
+<p>5.2不服从乐团老师的管理和指导;</p>
+<p>5.3一个学期内发生两次及以上缺席乐团上课、排练行为;</p>
+<p>5.4一个学期内发生两次及以上未按老师要求回传视频作业的情形;</p>
+<p>5.5连续{{proto}}天不练习,影响乐团团员和乐团的整体水平的。</p>
+<p>6. 用户在每次参加乐团排练、训练时,应按专业老师要求带齐训练所需乐器、教材乐谱、乐谱本、铅笔及乐器护理等学习用品,并提前10分钟到达排练场地,做好准备工作;始终保持排练、训练场地的清洁卫生;如遇到特殊情况无法参加乐团排练、训练时,应提前一天向乐团老师请假。</p>
+<p>7. 因用户个人原因未能按时上课的,视为该用户放弃该次上课,学校乐团声部训练不因用户请假而停止整个声部课教学,如用户因此给乐团造成任何不良影响的,用户应尽力弥补并消除该不良影响。</p>
+<p>8. 用户应保证每日练习时间不少于20分钟,并按专业老师要求通过本软件回传周视频作业。</p>
+<p>9. 退团:用户如因自身原因拟退出乐团的,应向学校申请退团,并获得学校的同意退团批准,再经用户家长确认后,方可退团。</p>
+<h2>六、第三方链接及服务</h2>
+<p>1. 本软件或本服务可能保留有第三方网站或网址的链接,访问这些链接将由用户自己做出决定,大雅乐盟并不就这些链接上所提供的任何信息、数据、观点、图片、陈述或建议的准确性、完整性、充分性和可靠性提供承诺或保证。大雅乐盟没有审查过任何第三方网站,对这些网站及其内容不进行控制,也不负任何责任。如果用户决定访问任何与本站链接的第三方网站,其可能带来的结果和风险全部由用户自己承担。</p>
+<p>2. 用户在使用本软件中第三方提供的产品或服务时,除遵守本协议约定外,还应遵守第三方的用户协议。大雅乐盟和第三方对可能出现的纠纷在法律规定和约定的范围内各自承担责任。因用户使用本软件或要求大雅乐盟提供特定服务时,本软件可能会调用第三方系统或者通过第三方支持用户的使用或访问,使用或访问的结果由该第三方提供(包括但不限于第三方通过公众账号提供的服务,或通过开放平台接入的内容等),大雅乐盟不保证通过第三方提供服务及内容的安全性、准确性、有效性及其他不确定的风险,由此若引发的任何争议及损害,与大雅乐盟无关,大雅乐盟不承担任何责任。</p>
+<p>3. 用户已知晓并同意大雅乐盟提供本服务(无论是免费服务还是有偿服务)还可能基于第三方如合作单位(包括但不限于电信运营商)提供的技术支持等服务获得。如果因第三方提供的服务给用户增加任何成本或造成任何损失的,大雅乐盟会协助用户与第三方进行沟通和处理,如因此发生维修、更换等费用的,应由用户自行承担,大雅乐盟不对此承担任何法律责任和赔偿责任。</p>
+<h2>七、知识产权的保护以及保密</h2>
+<p>1. 大雅乐盟的商标、商号、Logo、图形及其组合,以及大雅乐盟的其他标识、产品和服务名称均为大雅乐盟或大雅乐盟关联公司所有,未经大雅乐盟书面授权,任何人不得以任何方式展示、使用或作其他处理,也不得向任何第三方表明或让其误认为其有权展示、使用或作其他处理。</p>
+<p>2. 大雅乐盟提供的培训、课程相关的全部内容(包括但不限于培训课程设置、培训课件、教材等)的知识产权均归大雅乐盟单独和完整所有。用户应当保护大雅乐盟的知识产权,只能用于自身学习之目的,未经大雅乐盟事先书面同意,不得擅自将培训课程相关的任何内容进行复制、复印、影音、拍摄或进行摘要等措施后以转让、出售、赠与或其他任何形式提供给任何第三方,否则大雅乐盟有权追究其法律责任。</p>
+<p>3. 大雅乐盟为提供服务而使用的任何软件(包括但不限于软件中所含的任何图象、照片、动画、录像、录音、音乐、文字和附加程序、随附的帮助材料)的一切权利均属于该软件的著作权人,未经该软件的著作权人许可,用户不得对该软件进行反向工程(reverse engineer)、反向编译(decompile)或反汇编(disassemble)。</p>
+<p>4. 用户已经了解并同意:在大雅乐盟提供的所有服务器上的数据(包括但不限于虚拟物品等)全部归大雅乐盟所有。在不影响用户正常接收服务的情况下,大雅乐盟有权决定保留或不保留服务器上的全部或部分数据。</p>
+<p>5. 用户已经了解并同意:大雅乐盟有权将本协议项下大雅乐盟所有的知识产权授权第三方使用,在变更产品运营商时,大雅乐盟可以将其运营的产品或服务以及与该在产品或服务相关的归大雅乐盟所有的知识产权转让给新的产品运营商。</p>
+<p>6. 用户使用大雅乐盟提供的本软件或本服务期间获取的文件、资料、表格等信息,包括但不限于有关合作资料、营销资料等,无论是口头、书面的或是电子文件形式的,均属大雅乐盟的商业秘密,用户必须对这些商业秘密严格遵守保密义务,不得向外透露,也不得使用这些商业秘密为自己或他人谋取利益。</p>
+<h2>八、违约条款</h2>
+<p>1. 用户违反本协议约定时即构成违约情形,大雅乐盟有权要求用户采取及时的补救措施,消除违约后果,并有权终止本协议。如用户的违约行为使大雅乐盟及/或关联公司遭受损失(包括自身的直接经济损失、商誉损失及对外支付的赔偿金、和解款、律师费、诉讼费等间接经济损失)的,用户应赔偿大雅乐盟及/或关联公司的上述全部损失。</p>
+<p>2. 用户理解并同意,如用户的行为导致第三方向大雅乐盟及/或关联公司主张权利或任何索赔、要求或损失的,大雅乐盟及/或关联公司在对第三人承担赔偿义务后可向用户追偿与此相关的全部损失。</p>
+<h2>九、协议终止</h2>
+<p>1. 用户有权通过以下任一方式终止本协议:</p>
+<p>1.1用户自行注销用户的账户的;</p>
+<p>1.2用户按照本协议约定方式退出乐团的;</p>
+<p>1.3 变更事项生效或服务协议更新时,用户停止使用并明示不愿接受变更事项或明示不愿接受更新后的服务协议的;</p>
+<p>1.4 用户明示不愿继续使用本软件或本服务,且符合本协议终止条件的。</p>
+<p>2. 出现以下情况时,大雅乐盟可以终止本协议:</p>
+<p>2.1 用户违反本协议约定的,大雅乐盟依据违约条款终止本协议,或对用户处以退团处分的;</p>
+<p>2.2 用户的账户被大雅乐盟依据本协议进行注销等清理的;</p>
+<p>2.3 用户在使用本软件或本服务时存在侵犯他人合法权益或其他严重违法违规行为的;</p>
+<p>2.4 不可抗力导致本协议不能履行的(“不可抗力”是指双方不可预见、或可以预见但不能避免并或克服的客观情况,该事件妨碍、影响或延误任何一方根据合同履行其全部或部分义务。该事件包括但不限于政府行为、法律或规定的发布或修订,自然灾害、战争、网络堵塞或中断、黑客袭击或任何其他类似事件),且该不可抗力持续30天以上的;</p>
+<p>2.5 根据相关法律法规规定大雅乐盟应当终止服务或大雅乐盟认为需终止服务的其他情形。</p>
+<p>3. 协议终止后的处理</p>
+<p>本协议终止后,除法律有明确规定外,大雅乐盟无义务向用户或用户指定的第三方披露用户账户中的任何信息。</p>
+<h2>十、责任限制</h2>
+<p>1. 用户使用本软件或本服务的风险应由用户自行承担,大雅乐盟对本软件不作任何类型的担保,不论是明示的、默示的保证和条件,包括但不限于本软件的适销性、适用性、无病毒、无疏忽或无技术瑕疵问题、所有权和无侵权的明示或默示担保和条件,对在任何情况下因使用或不能使用本软件所产生的直接、间接、偶然、特殊及后续的损害及风险,大雅乐盟不承担任何责任。</p>
+<p>2. 用户明确理解和同意,大雅乐盟不对因下述任一情况而导致的损害赔偿承担责任,包括但不限于利润、商誉、使用、数据等方面的损失或其它无形损失的损害赔偿:</p>
+<p>2.1 大雅乐盟向用户免费提供的任何产品或者服务;</p>
+<p>2.2 大雅乐盟向用户赠送的任何产品或者服务;</p>
+<p>2.3 对于用户使用本软件上可能涉及由第三方所有、控制或者运营的网站或平台提供的服务及其导致的风险;</p>
+<p>2.4 因用户的过错导致的任何损失,该过错包括但不限于:决策失误、操作不当、遗忘或泄露密码、密码被他人破解、用户使用的计算机系统被第三方侵入、用户向大雅乐盟发送的指令信息不明确或存在歧义、用户下载非法或不明程序、用户委托他人代理交易时他人恶意或不当操作而造成的损失;</p>
+<p>2.5 信息网络设备连接故障,电脑、通讯或其他系统出现故障,不能进行数据传输、保存的;</p>
+<p>2.6 本软件或其服务器停机维护期间;</p>
+<p>2.7 不可抗力因素导致的任何损失;</p>
+<p>2.8 大雅乐盟依据本协议约定终止协议时。</p>
+<p>3. 用户理解并同意,因大雅乐盟过错导致用户不能享受相应服务,大雅乐盟承担相应责任的最高限额不超过用户实际支付的当次服务费用总额。</p>
+<p>4. 大雅乐盟努力保障用户的知情权,如主动中断或终止部分或全部网络服务,应提前90日在大雅乐盟服务平台以公告通知、app推送等方式通知。</p>
+<h2>十一、隐私权保护政策</h2>
+<p>用户及用户的监护人同意,大雅乐盟向用户提供本服务时,会收集、使用必要的用户个人信息,包括但不限于用户姓名、性别、年龄、学校、班级、联系方式、用户监护人的姓名及联系方式等,并将收集到的信息用于提供本服务必需的目的和场景。大雅乐盟不会收集与提供本服务无关的用户个人信息,具体隐私权保护政策详见大雅乐盟或本软件公示的《隐私政策》。</p>
+<h2>十二、争议解决及适用法律</h2>
+<p>1. 本协议及其修订的有效性、履行、解释及争议解决,均适用中华人民共和国大陆地区法律。</p>
+<p>2. 用户与大雅乐盟之间就本协议发生的任何纠纷或争议,首先应友好协商解决,协商不成的,应将纠纷或争议提交至大雅乐盟所在地有管辖权的法院管辖。</p>
+<h2>十三、其他</h2>
+<p>1. 如本协议中的任何条款无论因何种原因导致全部或部分无效或不具有执行力的,则该条款应视为自始不存在且不影响本协议其他条款的效力,此时该条款可被新的条款所取代,以保证最大限度地接近双方意图、确保本协议要求的经济目的,以及实现原有条款的意图。</p>
+<p>2. 本协议中的标题仅为方便而设,本身并无实际涵义,不能作为本协议涵义解释的依据。</p>
+<p>3. 如用户对本软件、本服务或本协议内容有任何疑问、意见或建议,用户可联系大雅乐盟,联系电话:{{proto}},大雅乐盟将及时回复用户的请求。</p>
+</div>
 </body>
 </html>

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

@@ -387,17 +387,29 @@
             LEFT JOIN teacher_school ts ON vg.teacher_school_id_ = ts.id_
             WHERE cgsm.user_id_ = #{search} AND cg.type_ = 'VIP') a
     </select>
+
     <select id="countClassStudent" resultType="int">
         select count(*) from class_group_student_mapper where class_group_id_=#{classGroupId}
     </select>
+
     <select id="findAllClassGroupByMusicGroup" resultMap="ClassGroup">
-        SELECT
-        *
-        FROM
-        class_group cg
+        SELECT * FROM class_group cg
         WHERE cg.music_group_id_=#{musicGroupId} AND del_flag_='0'
     </select>
 
+    <select id="queryTeacherIds" resultType="java.lang.Integer">
+        SELECT DISTINCT cgtm.user_id_ FROM class_group_teacher_mapper cgtm WHERE cgtm.class_group_id_ = #{id}
+    </select>
+
+    <select id="queryTeacherGroups" resultMap="imGroupModel">
+        SELECT cg.id_,cg.name_,cg.student_num_,cg.img_ FROM class_group_teacher_mapper cgtm
+        LEFT JOIN class_group cg ON cgtm.class_group_id_ = cg.id_
+        WHERE cgtm.user_id_ = #{userId}
+        <if test="search != null">
+            AND cg.name_ LIKE CONCAT('%',#{search},'%')
+        </if>
+    </select>
+
     <!-- 增加实际学生人数 -->
     <update id="addStudentNum" parameterType="com.ym.mec.biz.dal.entity.ClassGroup">
         UPDATE class_group SET student_num_ = student_num_+1,update_time_=#{updateTime} WHERE id_ = #{id} AND student_num_=#{studentNum}

+ 46 - 8
mec-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml

@@ -28,9 +28,10 @@
         <result column="name_" property="classGroupName"/>
         <result column="type_" property="type" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
         <result column="school_name_" property="schoolName"/>
-        <result column="attendance_status_" property="attendanceStatus" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
+        <result column="sign_in_status_" property="signInStatus"/>
+        <result column="sign_out_status_" property="signOutStatus"/>
         <result column="seal_class_id_" property="sealClassId"/>
-        <result column="paran_value_" property="vipAppealDaysRange"/>
+        <result column="teach_mode_" property="teachMode" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
     </resultMap>
 
     <resultMap type="com.ym.mec.biz.dal.entity.StudentCourseScheduleRecordDto" id="studentCourseScheduleRecord">
@@ -228,14 +229,40 @@
 
     <select id="getCourseSchedulesWithDate" resultMap="courseScheduleDto">
         SELECT
-            cg.*,
+            cg.id_ seal_class_id_,
+            cs.name_,
             cs.type_,
+            cs.id_,
             cs.class_date_,
-            cs.start_class_time_
+            CONCAT(cs.class_date_,' ',cs.start_class_time_) start_class_time_,
+            CONCAT(cs.class_date_,' ',cs.end_class_time_) end_class_time_,
+            cs.status_,
+	        su.username_ teacher_name_,
+	        ta.status_ attendance_status_
         FROM
-            course_schedule cs
-        LEFT JOIN class_group cg ON cs.class_group_id_=cg.id_
-        WHERE cs.class_date_=DATE_FORMAT(#{classDate},'%Y%m%d')
+            music_group mg
+            LEFT JOIN class_group cg ON mg.id_ = cg.music_group_id_
+            LEFT JOIN course_schedule cs ON cg.id_ = cs.class_group_id_
+            LEFT JOIN sys_user su ON cs.teacher_id_=su.id_
+	        LEFT JOIN teacher_attendance ta ON cs.id_=ta.class_group_id_ AND ta.teacher_id_=cs.teacher_id_
+        WHERE
+            mg.organ_id_ = #{organId}
+            AND cs.id_ IS NOT NULL
+            AND cs.class_date_ = DATE_FORMAT(#{classDate},'%Y%m%d')
+        <include refid="global.limit"/>
+    </select>
+
+    <select id="countCourseSchedulesWithDate" resultType="int">
+        SELECT
+        count(*)
+        FROM
+        music_group mg
+        LEFT JOIN class_group cg ON mg.id_ = cg.music_group_id_
+        LEFT JOIN course_schedule cs ON cg.id_ = cs.class_group_id_
+        WHERE
+        mg.organ_id_ = #{organId}
+        AND cs.id_ IS NOT NULL
+        AND cs.class_date_ = DATE_FORMAT(#{classDate},'%Y%m%d')
     </select>
 
     <select id="getStudentCourseSchedulesWithDate" resultMap="courseScheduleDto">
@@ -271,7 +298,9 @@
             CONCAT(cs.class_date_,' ',cs.end_class_time_) end_class_time_,
             cs.status_,
 	        s.name_ school_name_,
-	        ta.status_ attendance_status_
+	        cg.teach_mode_,
+	        ta.sign_in_status_ sign_in_status_,
+	        ta.sign_out_status_ sign_out_status_
         FROM
             course_schedule cs
             LEFT JOIN sys_user su ON cs.teacher_id_=su.id_
@@ -542,4 +571,13 @@
         WHERE
             cs.id_=#{courseScheduleId}
     </select>
+
+    <select id="findStudentNamesByCourseSchedule" resultType="string">
+        SELECT
+            su.username_
+        FROM
+            student_attendance sa
+            LEFT JOIN sys_user su ON sa.user_id_=su.id_
+            WHERE sa.course_schedule_id_=#{courseScheduleId}
+    </select>
 </mapper>

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

@@ -9,7 +9,7 @@
 	<resultMap type="com.ym.mec.biz.dal.entity.CourseScheduleTeacherSalary" id="CourseScheduleTeacherSalary">
 		<result column="id_" property="id" />
 		<result column="course_schedule_id_" property="courseScheduleId" />
-		<result column="teacher_role_" property="teacherRole" />
+		<result column="teacher_role_" property="teacherRole" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
 		<result column="user_id_" property="userId" />
 		<result column="expect_salary_" property="expectSalary" />
 		<result column="create_time_" property="createTime" />
@@ -105,15 +105,16 @@ create_time_ = #{createTime},
 
 	<sql id="vipGroupSalaryQueryCondition">
 		<where>
-			vg.id=#{vipGroupId} AND FIND_IN_SET(#{organId},vg.organ_id_list_)
+			vg.id_=#{vipGroupId} AND FIND_IN_SET(#{organId},vg.organ_id_list_)
 			<if test="startTime!=null and endTime!=null">
-				AND (cs.class_date BETWEEN #{startTime} AND #{endTime})
+				AND (cs.class_date_ BETWEEN #{startTime} AND #{endTime})
 			</if>
 		</where>
 	</sql>
 
 	<select id="findVipGroupSalarys" resultMap="VipGroupSalaryDto">
 		SELECT
+
 			cs.id_ course_schedule_id_,
 			CONCAT(cs.class_date_," ",cs.start_class_time_) class_date_,
 			cs.teach_mode_,

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

@@ -159,7 +159,7 @@ create_time_ = #{createTime},
 				AND dgcp.start_time_=#{startTime}
 			</if>
 			<if test="startTime!=null and endTime!=null">
-				AND dgcp.start_time_&gt;=#{startTime} AND dgcp.start_time_ &lt;= #{endTime}
+				AND (CONCAT(dgcp.course_date_,' ',dgcp.start_time_) BETWEEN #{startTime} AND #{endTime})
 			</if>
 		</where>
 	</sql>

+ 32 - 47
mec-biz/src/main/resources/config/mybatis/EmployeeMapper.xml

@@ -146,66 +146,51 @@
 		SELECT COUNT(*) FROM employee
 	</select>
 
+
     <resultMap type="com.ym.mec.biz.dal.dto.EmployeeDto" id="EmployeeDto">
         <result property="id" column="id_" />
-        <result property="username" column="username_" />
+        <result property="realName" column="real_name_" />
         <result property="gender" column="gender_" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
         <result property="phone" column="phone_" />
         <result property="lockFlag" column="lock_flag_" />
-        <result property="roleName" column="role_name_" />
         <result property="jobNature" column="job_nature_" />
         <result property="entryDate" column="entry_date_" />
         <result property="demissionDate" column="demission_date_" />
-        <result property="organIdList" column="organ_id_list_" />
-        <result property="organNameList" column="organ_name_list_" />
+        <collection property="roleNames" ofType="string" javaType="list">
+            <result column="role_name_" />
+        </collection>
+        <collection property="organNameList" ofType="string" javaType="list">
+            <result column="organ_name_list_" />
+        </collection>
+        <collection property="roleIds" ofType="integer" javaType="list">
+            <result column="role_id_" />
+        </collection>
+        <collection property="organIdList" ofType="Long" javaType="list">
+            <result column="organ_id_list_" />
+        </collection>
     </resultMap>
-
-    <sql id="queryCondition">
-        <where>
-            su.user_type_='SYSTEM'
-            <if test="organId != null">
-                and su.organ_id_=#{organId}
-            </if>
-            <if test="roleId != null">
-                and sr.id_ = #{roleId}
-            </if>
-            <if test="userNameOrPhone != null">
-                and (su.username_ like LIKE CONCAT('%',#{userNameOrPhone},'%')
-                or su.phone_ like LIKE CONCAT('%',#{userNameOrPhone},'%') or )
-            </if>
-        </where>
-    </sql>
-
     <select id="queryEmployByOrganId" resultMap="EmployeeDto">
-        SELECT
-        su.id_,
-        su.username_,
-        su.gender_,
-        su.phone_,
-        GROUP_CONCAT(DISTINCT sr.role_name_) role_name_,
-        su.lock_flag_,
-        e.organ_id_list_,
-        GROUP_CONCAT(DISTINCT o.name_) organ_name_list_,
-        e.job_nature_,
-        e.entry_date_,
-        e.demission_date_
-        FROM
-        sys_user su
-        LEFT JOIN employee e ON su.id_=e.user_id_
-        LEFT JOIN sys_user_role sur ON su.id_=sur.user_id_
-        LEFT JOIN sys_role sr ON sur.role_id_=sr.id_
+        SELECT su.id_,su.real_name_,su.gender_,su.phone_,su.user_type_,e.job_nature_,su.lock_flag_,
+        e.entry_date_,e.demission_date_,o.name_ organ_name_list_,o.id_ organ_id_list_,sr.role_name_,sr.id_ role_id_
+        FROM sys_user su
+        LEFT JOIN employee e ON su.id_ = e.user_id_
+        LEFT JOIN sys_user_role sur ON sur.user_id_ = e.user_id_
+        LEFT JOIN sys_role sr ON sr.id_ = sur.role_id_
         LEFT JOIN organization o ON FIND_IN_SET(o.id_,e.organ_id_list_)
-        <include refid="queryCondition"/>
-        GROUP BY su.id_
+        WHERE su.user_type_ LIKE '%SYSTEM%' AND FIND_IN_SET(su.organ_id_,e.organ_id_list_)
+        <if test="search != null">
+            AND (su.real_name_ LIKE CONCAT('%',#{search},'%') OR su.phone_ LIKE CONCAT('%',#{search},'%'))
+        </if>
+        <include refid="global.limit"/>
     </select>
 
     <select id="queryEmployByOrganIdCount" resultType="int">
-		SELECT
-			count(*)
-		FROM
-			sys_user su
-		LEFT JOIN employee e ON su.id_=e.user_id_
-		LEFT JOIN sys_user_role sur ON su.id_=sur.user_id_
-		LEFT JOIN sys_role sr ON sur.role_id_=sr.id_
+        SELECT COUNT(su.id_)
+        FROM sys_user su
+        LEFT JOIN employee e ON su.id_ = e.user_id_
+        WHERE su.user_type_ LIKE '%SYSTEM%' AND FIND_IN_SET(su.organ_id_,e.organ_id_list_)
+        <if test="search != null">
+            AND (su.real_name_ LIKE CONCAT('%',#{search},'%') OR su.phone_ LIKE CONCAT('%',#{search},'%'))
+        </if>
 	</select>
 </mapper>

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

@@ -239,4 +239,17 @@
 		LEFT JOIN sys_user su ON cgsm.user_id_ = su.id_
 		WHERE cg.music_group_id_ = #{musicGroupId} GROUP BY su.id_
 	</select>
+	<select id="queryTeacherGroups" resultMap="ImUserModel">
+		SELECT mg.id_,mg.name_,mg.img_ FROM music_group mg
+		WHERE (team_teacher_id_ = #{userId} OR educational_teacher_id_ = #{userId} OR operator_user_id_ = #{userId} OR director_user_id_ = #{userId})
+		<if test="search != null">
+			AND mg.name_ LIKE CONCAT('%',#{search},'%')
+		</if>
+	</select>
+
+	<select id="queryTeacherIds" resultType="java.lang.Integer">
+		SELECT DISTINCT cgtm.user_id_ FROM class_group cg
+		LEFT JOIN class_group_teacher_mapper cgtm ON cg.id_ = cgtm.class_group_id_
+		WHERE cg.music_group_id_ = #{id}
+	</select>
 </mapper>

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

@@ -102,6 +102,6 @@
     </select>
 
     <select id="findByOrganIds" resultType="java.lang.String">
-        SELECT name_ FROM organization IN (#{organIds}) WHERE del_flag_ = 0
+        SELECT name_ FROM organization WHERE del_flag_ = 0 AND id_ IN (#{organIds})
     </select>
 </mapper>

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

@@ -13,7 +13,9 @@
         <result column="class_group_id_" property="classGroupId"/>
         <result column="course_schedule_id_" property="courseScheduleId"/>
         <result column="sign_in_time_" property="signInTime"/>
-        <result column="status_" property="status" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
+        <result column="sign_in_status_" property="signInStatus" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
+        <result column="sign_out_time_" property="signOutTime"/>
+        <result column="sign_out_status_" property="signOutStatus" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
         <result column="remark_" property="remark"/>
         <result column="create_time_" property="createTime"/>
     </resultMap>
@@ -37,16 +39,16 @@
         </selectKey>
         -->
         INSERT INTO teacher_attendance
-        (id_,teacher_id_,music_group_id_,class_group_id_,course_schedule_id_,sign_in_time_,status_,remark_,create_time_)
-        VALUES(#{id},#{teacherId},#{musicGroupId},#{classGroupId},#{courseScheduleId},#{signInTime},#{status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{remark},now())
+        (id_,teacher_id_,music_group_id_,class_group_id_,course_schedule_id_,sign_in_time_,sign_in_status_,remark_,create_time_,sign_out_time_,sign_out_status_)
+        VALUES(#{id},#{teacherId},#{musicGroupId},#{classGroupId},#{courseScheduleId},#{signInTime},#{signInStatus,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{remark},now(),#{signOutTime},#{signOutStatus,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler})
     </insert>
 
     <!-- 根据主键查询一条记录 -->
     <update id="update" parameterType="com.ym.mec.biz.dal.entity.TeacherAttendance">
         UPDATE teacher_attendance
         <set>
-            <if test="status != null">
-                status_ = #{status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+            <if test="signInStatus != null">
+                sign_in_status_ = #{signInStatus,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
             </if>
             <if test="remark != null">
                 remark_ = #{remark},
@@ -66,6 +68,12 @@
             <if test="musicGroupId != null">
                 music_group_id_ = #{musicGroupId},
             </if>
+            <if test="signOutTime != null">
+                sign_out_time_ = #{signOutTime},
+            </if>
+            <if test="signOutStatus != null">
+                sign_out_status_ = #{signOutStatus,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+            </if>
         </set>
         WHERE id_ = #{id}
     </update>
@@ -148,6 +156,9 @@
     <select id="countClassTime" resultType="java.lang.Integer">
         select count(*) from teacher_attendance where class_group_id_=#{classGroupId} for update
     </select>
+    <select id="findByTeacherAttendanceInfo" resultMap="teacherPersonalAttendance">
+        ELECT * FROM teacher_attendance WHERE teacher_id_=#{teacherId} AND course_schedule_id_=#{courseScheduleId}
+    </select>
 
 
 </mapper>

+ 11 - 0
mec-biz/src/main/resources/config/mybatis/TeacherMapper.xml

@@ -237,4 +237,15 @@
     <select id="findByCertificateNum" resultMap="Teacher">
 		SELECT * FROM teacher WHERE certificate_num_ = #{certificateNum}
 	</select>
+    <select id="queryGroupStudents" resultMap="com.ym.mec.biz.dal.dao.MusicGroupDao.BasicUserDto">
+        SELECT su.username_,su.id_ user_id_,su.avatar_ head_url_,su.gender_,s.name_ FROM class_group_teacher_mapper cgtm
+        LEFT JOIN class_group_student_mapper cgsm ON cgtm.class_group_id_ = cgsm.class_group_id_
+        LEFT JOIN sys_user su ON cgsm.user_id_ = su.id_
+        LEFT JOIN student_registration sr ON sr.user_id_ = su.id_
+        LEFT JOIN `subject` s ON s.id_ = sr.actual_subject_id_
+        WHERE cgtm.user_id_ = #{teacherId}
+        <if test="search != null">
+            AND su.username_ LIKE CONCAT('%',#{search},'%')
+        </if>
+    </select>
 </mapper>

+ 48 - 12
mec-biz/src/main/resources/config/mybatis/VipGroupMapper.xml

@@ -22,6 +22,7 @@
         <result column="audit_status_" property="auditStatus" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
         <result column="organ_id_list_" property="organIdList"/>
         <result column="vip_group_activity_id_" property="vipGroupActivityId"/>
+        <result column="vip_group_activity_name_" property="vipGroupActivityName"/>
         <result column="status_" property="status" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
         <result column="online_classes_unit_price_" property="onlineClassesUnitPrice"/>
         <result column="offline_classes_unit_price_" property="offlineClassesUnitPrice"/>
@@ -38,11 +39,14 @@
 
     <resultMap id="vipGroupManageDetailDto" type="com.ym.mec.biz.dal.dto.VipGroupManageDetailDto" extends="VipGroup">
         <result property="studentNum" column="student_num_"/>
+        <result property="subjectIdList" column="subject_id_list_"/>
         <result property="latestClassTime" column="current_class_times_"/>
-        <collection property="students" ofType="com.ym.mec.auth.api.entity.SysUser" column="user_id_">
-            <result property="id" column="user_id_"/>
-            <result property="username" column="username_"/>
-        </collection>
+        <result property="categoryName" column="category_name_"/>
+        <result column="teacher_school_name_" property="teacherSchoolName"/>
+        <!--<collection property="students" ofType="com.ym.mec.auth.api.entity.SysUser" column="student_id_">-->
+            <!--<result property="id" column="student_id_"/>-->
+            <!--<result property="username" column="username_"/>-->
+        <!--</collection>-->
     </resultMap>
 
     <resultMap id="studentVipGroupDetailDto" type="com.ym.mec.biz.dal.dto.StudentVipGroupDetailDto" extends="studentVipGroup">
@@ -103,6 +107,7 @@
     <select id="findAllByOrgan" resultMap="VipGroup">
 		SELECT
             vg.*,
+            vga.name_ vip_group_activity_name_,
             su.username_,
             cg.student_num_,
             cg.total_class_times_,
@@ -112,6 +117,7 @@
             LEFT JOIN sys_user su ON vg.user_id_=su.id_
             LEFT JOIN vip_group_class_group_mapper vgcgm ON vg.id_=vgcgm.vip_group_id_
             LEFT JOIN class_group cg ON vgcgm.class_group_id_=cg.id_
+            LEFT JOIN vip_group_activity vga ON vg.vip_group_activity_id_=vga.id_
         <include refid="vipGroupQueryCondition"/>
         ORDER BY vg.id_
         <include refid="global.limit"/>
@@ -273,17 +279,23 @@
     <select id="getVipGroupBaseInfo" resultMap="vipGroupManageDetailDto">
         SELECT
             vg.*,
+            vga.name_ vip_group_activity_name_,
+            su.username_,
             cg.student_num_,
+            cg.subject_id_list_,
+            cg.total_class_times_,
             cg.current_class_times_,
-            su.*
+            vgc.name_ category_name_,
+            s.name_ teacher_school_name_
         FROM
             vip_group vg
+            LEFT JOIN sys_user su ON vg.user_id_=su.id_
             LEFT JOIN vip_group_class_group_mapper vgcgm ON vg.id_=vgcgm.vip_group_id_
             LEFT JOIN class_group cg ON vgcgm.class_group_id_=cg.id_
-            LEFT JOIN class_group_student_mapper cgsm ON vgcgm.class_group_id_=cgsm.class_group_id_
-            LEFT JOIN sys_user su ON cgsm.user_id_=su.id_
-        WHERE vg.id_=1
-        ORDER BY vg.id_ DESC
+            LEFT JOIN vip_group_activity vga ON vg.vip_group_activity_id_=vga.id_
+            LEFT JOIN vip_group_category vgc ON vg.vip_group_category_id_=vgc.id_
+            LEFT JOIN school s ON vg.teacher_school_id_=s.id_
+        WHERE vg.id_=#{vipGroupId}
     </select>
 
     <sql id="vipGroupAttendanceQueryCondition">
@@ -396,19 +408,21 @@
         <result column="status_" property="status" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
         <result column="teach_mode_" property="teachMode" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
         <result column="give_teach_mode_" property="giveTeachMode" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
+        <result column="is_salary_" property="isSalary" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
+        <result column="student_num_" property="attendanceNum"/>
     </resultMap>
 
     <sql id="teachingRecordQueryCondition">
         <where>
             vgcgm.vip_group_id_=#{vipGroupId}
             <if test="startTime!=null and endTime!=null">
-                cs.class_date_ BETWEEN #{startTime} AND #{endTime}
+                AND (cs.class_date_ BETWEEN #{startTime} AND #{endTime})
             </if>
             <if test="teachMode!=null and teachMode!=''">
-                cs.teach_mode_=#{teachMode}
+                AND cs.teach_mode_=#{teachMode,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
             </if>
             <if test="status!=null and status!=''">
-                cs.status_=#{status}
+                AND cs.status_=#{status}
             </if>
         </where>
     </sql>
@@ -419,6 +433,7 @@
             CONCAT(cs.class_date_,' ',cs.start_class_time_) start_class_time_,
             cs.status_,
             cs.teach_mode_,
+            cs.student_num_,
             csts.actual_salary_ IS NOT NULL is_salary_
         FROM
             vip_group_class_group_mapper vgcgm
@@ -465,4 +480,25 @@
         WHERE vgcgm.vip_group_id_=#{vipGroupId} AND csc.course_schedule_id_ IS NOT NULL
 
     </select>
+    <select id="getVipGroupSalaryInfo" resultType="com.ym.mec.biz.dal.dto.VipGroupSalaryBaseInfo">
+        SELECT
+             SUM(csts.expect_salary_) expectTotalSalary,
+             SUM(csts.actual_salary_) totalSalary
+        FROM
+            vip_group vg
+            LEFT JOIN vip_group_class_group_mapper vgcgm ON vg.id_=vgcgm.vip_group_id_
+            LEFT JOIN course_schedule cs ON vgcgm.class_group_id_=cs.class_group_id_
+            LEFT JOIN course_schedule_teacher_salary csts ON cs.id_=csts.course_schedule_id_
+        WHERE vg.id_=#{vipGroupId} AND cs.id_!=NULL AND csts.settlement_time_!=NULL
+    </select>
+    <select id="countVipGroupDeductionNum" resultType="int">
+        SELECT
+             COUNT(csts.id_)
+        FROM
+            vip_group vg
+            LEFT JOIN vip_group_class_group_mapper vgcgm ON vg.id_=vgcgm.vip_group_id_
+            LEFT JOIN course_schedule cs ON vgcgm.class_group_id_=cs.class_group_id_
+            LEFT JOIN course_schedule_teacher_salary csts ON cs.id_=csts.course_schedule_id_
+        WHERE vg.id_=#{vipGroupId} AND cs.id_!=NULL AND csts.settlement_time_!=NULL AND csts.actual_salary_&lt;csts.expect_salary_
+    </select>
 </mapper>

+ 1 - 1
mec-education/src/main/java/com/ym/mec/education/EducationApplication.java

@@ -13,7 +13,7 @@ import org.springframework.web.client.RestTemplate;
 
 import com.spring4all.swagger.EnableSwagger2Doc;
 
-@MapperScan({"com.ym.mec.education.mapper", "com.ym.mec.biz.dal.dao"})
+@MapperScan({"com.ym.mec.education.mapper", "com.ym.mec.biz.dal.dao","com.ym.mec.biz.config.mybatis"})
 @SpringBootApplication
 @EnableDiscoveryClient
 @EnableFeignClients("com.ym.mec")

+ 8 - 0
mec-education/src/main/java/com/ym/mec/education/config/WebMvcConfig.java

@@ -11,6 +11,8 @@ import java.util.Date;
 
 import com.ym.mec.common.config.EnumConverterFactory;
 import com.ym.mec.common.enums.BaseEnum;
+
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Primary;
@@ -58,6 +60,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
 		objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
 		// 序列化BigDecimal时不使用科学计数法输出
 		objectMapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
+		objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
+			@Override
+			public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
+				jsonGenerator.writeString(StringUtils.EMPTY);
+			}
+		});
 		// 日期和时间格式化
 		JavaTimeModule javaTimeModule = new JavaTimeModule();
 		javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

+ 15 - 0
mec-education/src/main/java/com/ym/mec/education/controller/CourseScheduleController.java

@@ -1,6 +1,7 @@
 package com.ym.mec.education.controller;
 
 import com.ym.mec.biz.dal.dto.ClassDateAdjustDto;
+import com.ym.mec.biz.dal.page.CourseScheduleQueryInfo;
 import com.ym.mec.biz.service.CourseScheduleService;
 import com.ym.mec.education.base.BaseResponse;
 import com.ym.mec.education.base.PageResponse;
@@ -10,11 +11,13 @@ import com.ym.mec.education.resp.CourseScheduleResp;
 import com.ym.mec.education.service.ICourseScheduleService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.Date;
 import java.util.Objects;
 
 /**
@@ -59,6 +62,18 @@ public class CourseScheduleController {
         return courseScheduleService.courseInfo(courseScheduleReq);
     }
 
+    @ApiOperation(value = "根据月份获取乐团在该月有课的日期")
+    @GetMapping("/getCourseScheduleDateByMonth")
+    public Object getCourseScheduleDateByMonth(@ApiParam(value = "月份", required = true) @RequestParam Date month) {
+        return BaseResponse.success(scheduleService.getCourseScheduleDates(month));
+    }
+
+    @ApiOperation(value = "根据日期获取当日排课")
+    @GetMapping("/getCourseSchedulesWithDate")
+    public Object getCourseSchedulesWithDate(CourseScheduleQueryInfo queryInfo) {
+        return BaseResponse.success(scheduleService.getCourseSchedulesWithDateByEdu(queryInfo));
+    }
+
     @ApiOperation(value = "课时调整")
     @PostMapping(value = "/classStartDateAdjust")
     public Object classStartDateAdjust(ClassDateAdjustDto classDateAdjustDto){

+ 53 - 49
mec-education/src/main/java/com/ym/mec/education/service/impl/TeacherServiceImpl.java

@@ -17,11 +17,11 @@ import com.ym.mec.education.resp.TeacherResp;
 import com.ym.mec.education.resp.VipGroupClassResp;
 import com.ym.mec.education.service.*;
 import com.ym.mec.education.utils.DateUtil;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
-import org.springframework.util.StringUtils;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
@@ -82,60 +82,64 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherMapper, Teacher> impl
     public PageResponse teacherList(TeacherReq req) {
         PageResponse response = new PageResponse();
         QueryWrapper<SysUser> userQueryWrapper = new QueryWrapper<>();
-        List<SysUser> userList = null;
-        if (req != null && StringUtils.isEmpty(req.getName())) {
+        if (Objects.isNull(req.getUserId())) {
+            return PageResponse.errorParam();
+        }
+        Teacher teacher = getById(req.getUserId());
+        if (Objects.isNull(teacher)) {
+            return PageResponse.noDataExists();
+        }
+        if (req != null && StringUtils.isNotBlank(req.getName())) {
             userQueryWrapper.like("real_name_", req.getName());
-            userList = sysUserService.list(userQueryWrapper);
         }
+        List<SysUser> userList = sysUserService.list(userQueryWrapper);
         QueryWrapper<Teacher> queryWrapper = new QueryWrapper<>();
-        List<Integer> userIds = null;
+        List<TeacherResp> teacherRespList = new ArrayList<>();
+        List<Integer> userIds;
+        IPage<Teacher> teacherIPage = new Page<>();
         if (!CollectionUtils.isEmpty(userList)) {
             userIds = userList.stream().map(SysUser::getId).collect(Collectors.toList());
             queryWrapper.in("id_", userIds);
-        }
-
-
-        IPage<Teacher> page = new Page(req.getPageNo() == null ? 1 : req.getPageNo(), req.getPageSize() == null ? 10 : req.getPageSize());
-        IPage<Teacher> teacherIPage = this.page(page, queryWrapper);
-
-        List<Teacher> teacherList = teacherIPage.getRecords();
-        List<TeacherResp> teacherRespList = new ArrayList<>();
-        if (!CollectionUtils.isEmpty(teacherList)) {
-            teacherList.forEach(e -> {
-                TeacherResp teacherResp = new TeacherResp();
-                String ids[] = e.getSubjectId().split(",");
-                List<String> stringB = Arrays.asList(ids);
-                QueryWrapper<Subject> queryWrapperSub = new QueryWrapper<>();
-                queryWrapperSub.in("id_", stringB);
-                List<Subject> subjectList = subjectService.list(queryWrapperSub);
-                if (!CollectionUtils.isEmpty(subjectList)) {
-                    List<String> subName = subjectList.stream().map(Subject::getName).collect(Collectors.toList());
-                    teacherResp.setSubjectName(subName);
-                }
-                teacherResp.setUserId(e.getId());
-                SysUser sysUser = sysUserService.getById(e.getId());
-                if (sysUser != null) {
-                    teacherResp.setAvatar(sysUser.getAvatar());
-                    teacherResp.setName(sysUser.getRealName());
-                }
-                QueryWrapper<ClassGroupTeacherMapper> queryWrapper1 = new QueryWrapper<>();
-                queryWrapper1.eq("user_id_", e.getId());
-                List<ClassGroupTeacherMapper> classGroupTeacherMappers = classGroupTeacherMapperService.list(queryWrapper1);
-                if (!CollectionUtils.isEmpty(classGroupTeacherMappers)) {
-                    List<Integer> classId = classGroupTeacherMappers.stream().map(ClassGroupTeacherMapper::getClassGroupId).collect(Collectors.toList());
-                    QueryWrapper<ClassGroup> groupQueryWrapper = new QueryWrapper<>();
-                    groupQueryWrapper.eq("id_", classId);
-                    List<ClassGroup> classGroups = classGroupService.list(groupQueryWrapper);
-                    if (!CollectionUtils.isEmpty(classGroups)) {
-                        List<String> className = classGroups.stream().map(ClassGroup::getName).collect(Collectors.toList());
-
-                        teacherResp.setClassName(className);
+            Optional.ofNullable(teacher.getOrganId()).ifPresent(organId ->
+                queryWrapper.lambda().eq(Teacher::getOrganId, organId));
+            IPage<Teacher> page = new Page(req.getPageNo() == null ? 1 : req.getPageNo(), req.getPageSize() == null ? 10 : req.getPageSize());
+            teacherIPage = this.page(page, queryWrapper);
+            List<Teacher> teacherList = teacherIPage.getRecords();
+            if (!CollectionUtils.isEmpty(teacherList)) {
+                teacherList.forEach(e -> {
+                    TeacherResp teacherResp = new TeacherResp();
+                    String ids[] = e.getSubjectId().split(",");
+                    List<String> stringB = Arrays.asList(ids);
+                    QueryWrapper<Subject> queryWrapperSub = new QueryWrapper<>();
+                    queryWrapperSub.in("id_", stringB);
+                    List<Subject> subjectList = subjectService.list(queryWrapperSub);
+                    if (!CollectionUtils.isEmpty(subjectList)) {
+                        List<String> subName = subjectList.stream().map(Subject::getName).collect(Collectors.toList());
+                        teacherResp.setSubjectName(subName);
                     }
-                }
-
-                teacherRespList.add(teacherResp);
-            });
-
+                    teacherResp.setUserId(e.getId());
+                    SysUser sysUser = sysUserService.getById(e.getId());
+                    if (sysUser != null) {
+                        teacherResp.setAvatar(sysUser.getAvatar());
+                        teacherResp.setName(sysUser.getRealName());
+                    }
+                    QueryWrapper<ClassGroupTeacherMapper> queryWrapper1 = new QueryWrapper<>();
+                    queryWrapper1.eq("user_id_", e.getId());
+                    List<ClassGroupTeacherMapper> classGroupTeacherMappers = classGroupTeacherMapperService.list(queryWrapper1);
+                    if (!CollectionUtils.isEmpty(classGroupTeacherMappers)) {
+                        List<Integer> classId = classGroupTeacherMappers.stream().map(ClassGroupTeacherMapper::getClassGroupId).collect(Collectors.toList());
+                        QueryWrapper<ClassGroup> groupQueryWrapper = new QueryWrapper<>();
+                        groupQueryWrapper.eq("id_", classId);
+                        List<ClassGroup> classGroups = classGroupService.list(groupQueryWrapper);
+                        if (!CollectionUtils.isEmpty(classGroups)) {
+                            List<String> className = classGroups.stream().map(ClassGroup::getName).collect(Collectors.toList());
+
+                            teacherResp.setClassName(className);
+                        }
+                    }
+                    teacherRespList.add(teacherResp);
+                });
+            }
         }
         response.setReturnCode(ReturnCodeEnum.CODE_200.getCode());
         response.setMessage(ReturnCodeEnum.CODE_200.getValue());
@@ -325,7 +329,7 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherMapper, Teacher> impl
         Page<CourseSchedule> courseSchedulePage = new Page<CourseSchedule>(req.getPageNo(), req.getPageSize());
         QueryWrapper<CourseSchedule> courseScheduleQueryWrapper = new QueryWrapper<>();
         courseScheduleQueryWrapper.lambda().eq(CourseSchedule::getTeacherId, req.getUserId())
-        .eq(Objects.nonNull(req.getDate()), CourseSchedule::getClassDate, req.getDate());
+            .eq(Objects.nonNull(req.getDate()), CourseSchedule::getClassDate, req.getDate());
         IPage<CourseSchedule> page = courseScheduleService.page(courseSchedulePage, courseScheduleQueryWrapper);
         BeanUtils.copyProperties(page, pageResult);
         if (!CollectionUtils.isEmpty(page.getRecords())) {

+ 1 - 1
mec-education/src/main/resources/application.yml

@@ -51,7 +51,7 @@ spring:
       min-idle: 0
 
 mybatis-plus:
-  mapper-locations: classpath*:mapper/*.xml
+  mapper-locations: classpath*:mapper/*.xml,classpath*:config/mybatis/*.xml
   typeAliasesPackage : com.ym.mec.education.entity
   configuration:
     log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

+ 2 - 0
mec-eureka/src/main/resources/application.yml

@@ -4,6 +4,8 @@ server:
     contextPath: /eureka
 
 eureka:
+  instance:
+    lease-renewal-interval-in-seconds: 1
   client:
     registerWithEureka: false
     fetchRegistry: false

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

@@ -13,6 +13,8 @@ import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
 import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
 import com.ym.mec.common.config.EnumConverterFactory;
 import com.ym.mec.common.enums.BaseEnum;
+
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Primary;
@@ -50,6 +52,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
 		objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
 		// 序列化BigDecimal时不使用科学计数法输出
 		objectMapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
+		objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
+			@Override
+			public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
+				jsonGenerator.writeString(StringUtils.EMPTY);
+			}
+		});
 		// 日期和时间格式化
 		JavaTimeModule javaTimeModule = new JavaTimeModule();
 		javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

+ 7 - 0
mec-student/src/main/java/com/ym/mec/student/config/WebMvcConfig.java

@@ -9,6 +9,7 @@ import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
 import java.util.Date;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Primary;
@@ -57,6 +58,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
 		objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
 		// 序列化BigDecimal时不使用科学计数法输出
 		objectMapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
+		objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
+			@Override
+			public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
+				jsonGenerator.writeString(StringUtils.EMPTY);
+			}
+		});
 		// 日期和时间格式化
 		JavaTimeModule javaTimeModule = new JavaTimeModule();
 		javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

+ 30 - 0
mec-student/src/main/java/com/ym/mec/student/controller/ContractsController.java

@@ -34,4 +34,34 @@ public class ContractsController extends BaseController {
 		return succeed(contractService.queryRegisterContract(sysUser.getId()));
 	}
 
+	@ApiOperation("查询商品协议")
+	@GetMapping(value = "queryGoodsContract")
+	public Object queryGoodsContract(String musicGroupId) {
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		if (sysUser == null) {
+			return failed("获取用户信息失败");
+		}
+		return succeed(contractService.queryGoodsContract(sysUser.getId(), musicGroupId));
+	}
+
+	@ApiOperation("查询乐团课程协议")
+	@GetMapping(value = "queryMusicGroupCoursesContract")
+	public Object queryMusicGroupCoursesContract(String musicGroupId) {
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		if (sysUser == null) {
+			return failed("获取用户信息失败");
+		}
+		return succeed(contractService.queryMusicGroupCoursesContract(sysUser.getId(), musicGroupId));
+	}
+
+	@ApiOperation("查询VIP课程协议")
+	@GetMapping(value = "queryVipGroupCoursesContract")
+	public Object queryVipGroupCoursesContract(Long vipGroupId) {
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		if (sysUser == null) {
+			return failed("获取用户信息失败");
+		}
+		return succeed(contractService.queryVipGroupCoursesContract(sysUser.getId(), vipGroupId));
+	}
+
 }

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

@@ -37,7 +37,7 @@ public class StudentDemoGroupController extends BaseController {
 
     @ApiOperation(value = "试听课列表获取")
     @PostMapping("/queryStudentDemoGroups")
-    public Object queryStudentDemoGroups(StudentDemoGroupQueryInfo queryInfo){
+    public Object queryStudentDemoGroups(@RequestBody StudentDemoGroupQueryInfo queryInfo){
         return succeed(demoGroupService.queryStudentDemoGroups(queryInfo));
     }
 

+ 7 - 0
mec-task/src/main/java/com/ym/mec/task/config/WebMvcConfig.java

@@ -9,6 +9,7 @@ import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
 import java.util.Date;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Primary;
@@ -57,6 +58,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
 		objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
 		// 序列化BigDecimal时不使用科学计数法输出
 		objectMapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
+		objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
+			@Override
+			public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
+				jsonGenerator.writeString(StringUtils.EMPTY);
+			}
+		});
 		// 日期和时间格式化
 		JavaTimeModule javaTimeModule = new JavaTimeModule();
 		javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

+ 7 - 0
mec-teacher/src/main/java/com/ym/mec/teacher/config/WebMvcConfig.java

@@ -9,6 +9,7 @@ import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
 import java.util.Date;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Primary;
@@ -57,6 +58,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
 		objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
 		// 序列化BigDecimal时不使用科学计数法输出
 		objectMapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
+		objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
+			@Override
+			public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
+				jsonGenerator.writeString(StringUtils.EMPTY);
+			}
+		});
 		// 日期和时间格式化
 		JavaTimeModule javaTimeModule = new JavaTimeModule();
 		javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

+ 70 - 0
mec-teacher/src/main/java/com/ym/mec/teacher/controller/OrderController.java

@@ -0,0 +1,70 @@
+package com.ym.mec.teacher.controller;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.snaker.engine.SnakerEngine;
+import org.snaker.engine.access.Page;
+import org.snaker.engine.access.QueryFilter;
+import org.snaker.engine.entity.HistoryOrder;
+import org.snaker.engine.entity.HistoryTask;
+import org.snaker.engine.entity.Process;
+import org.snaker.engine.entity.Task;
+import org.snaker.engine.helper.AssertHelper;
+import org.springframework.beans.factory.annotation.Autowired;
+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.RestController;
+
+import com.ym.mec.auth.api.client.SysUserFeignService;
+import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.common.controller.BaseController;
+
+@RestController
+@RequestMapping(value = "/snaker/order")
+public class OrderController extends BaseController {
+
+	@Autowired
+	private SnakerEngine snakerEngine;
+
+	@Autowired
+	private SysUserFeignService SysUserFeignService;
+
+	/**
+	 * 抄送实例已读
+	 * @param orderId
+	 * @param url
+	 * @return
+	 */
+	@PostMapping(value = "setCcread")
+	public Object ccread(String orderId) {
+		SysUser user = SysUserFeignService.queryUserInfo();
+
+		snakerEngine.order().updateCCStatus(orderId, new String[] { user.getId() + "" });
+		return succeed();
+	}
+
+	@GetMapping(value = "detail")
+	public Object json(String processId, String orderId) {
+		Process process = snakerEngine.process().getProcessById(processId);
+		AssertHelper.notNull(process);
+		Map<String, Object> jsonMap = new HashMap<String, Object>();
+		/*ProcessModel model = process.getModel();
+		if (model != null) {
+			jsonMap.put("process", model);
+		}*/
+
+		if (StringUtils.isNotEmpty(orderId)) {
+			List<Task> tasks = snakerEngine.query().getActiveTasks(new QueryFilter().setOrderId(orderId));
+			jsonMap.put("tasks", tasks);
+
+			List<HistoryTask> historyTasks = snakerEngine.query().getHistoryTasks(new QueryFilter().setOrderId(orderId));
+			jsonMap.put("historyTasks", historyTasks);
+		}
+		return jsonMap;
+	}
+
+}

+ 209 - 0
mec-teacher/src/main/java/com/ym/mec/teacher/controller/TaskController.java

@@ -0,0 +1,209 @@
+package com.ym.mec.teacher.controller;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.snaker.engine.SnakerEngine;
+import org.snaker.engine.access.Page;
+import org.snaker.engine.access.QueryFilter;
+import org.snaker.engine.core.AccessService;
+import org.snaker.engine.entity.HistoryOrder;
+import org.snaker.engine.entity.Task;
+import org.snaker.engine.entity.WorkItem;
+import org.snaker.engine.model.TaskModel.TaskType;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.ui.ModelMap;
+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.RestController;
+
+import com.ym.mec.auth.api.client.SysUserFeignService;
+import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.common.controller.BaseController;
+
+/**
+ * Snaker流程引擎常用Controller
+ * @author yuqs
+ * @since 0.1
+ */
+@RestController
+@RequestMapping(value = "/snaker/task")
+public class TaskController extends BaseController {
+
+	@Autowired
+	private SnakerEngine snakerEngine;
+
+	@Autowired
+	private SysUserFeignService SysUserFeignService;
+
+	@GetMapping(value = "home")
+	public Object homeTaskList() {
+
+		SysUser user = SysUserFeignService.queryUserInfo();
+
+		List<String> list = new ArrayList<String>();
+		list.add(user.getUsername());
+
+		String[] assignees = new String[list.size()];
+		list.toArray(assignees);
+
+		Page<WorkItem> majorPage = new Page<WorkItem>(5);
+		Page<WorkItem> aidantPage = new Page<WorkItem>(3);
+		Page<HistoryOrder> ccorderPage = new Page<HistoryOrder>(3);
+		List<WorkItem> majorWorks = snakerEngine.query().getWorkItems(majorPage,
+				new QueryFilter().setOperators(assignees).setTaskType(TaskType.Major.ordinal()));
+		List<WorkItem> aidantWorks = snakerEngine.query().getWorkItems(aidantPage,
+				new QueryFilter().setOperators(assignees).setTaskType(TaskType.Aidant.ordinal()));
+		List<HistoryOrder> ccWorks = snakerEngine.query().getCCWorks(ccorderPage, new QueryFilter().setOperators(assignees).setState(1));
+
+		ModelMap model = new ModelMap();
+		
+		model.addAttribute("majorWorks", majorWorks);
+		model.addAttribute("majorTotal", majorPage.getTotalCount());
+		model.addAttribute("aidantWorks", aidantWorks);
+		model.addAttribute("aidantTotal", aidantPage.getTotalCount());
+		model.addAttribute("ccorderWorks", ccWorks);
+		model.addAttribute("ccorderTotal", ccorderPage.getTotalCount());
+		return succeed(model);
+	}
+
+	/**
+	 * 根据当前用户查询我发起的任务列表
+	 * @param model
+	 * @return
+	 */
+	@GetMapping(value = "queryCreatedList")
+	public Object queryCreatedList(Page<HistoryOrder> page) {
+		SysUser user = SysUserFeignService.queryUserInfo();
+
+		snakerEngine.query().getHistoryOrders(page, new QueryFilter().setOperator(user.getUsername()));
+		return succeed(page);
+	}
+
+	/**
+	 * 根据当前用户查询待办任务列表
+	 * @param model
+	 * @return
+	 */
+	@GetMapping(value = "queryWaitList")
+	public Object queryWaitList(Page<WorkItem> page) {
+		SysUser user = SysUserFeignService.queryUserInfo();
+
+		snakerEngine.query().getWorkItems(page, new QueryFilter().setOperator(user.getUsername()));
+		return succeed(page);
+	}
+
+	/**
+	 * 根据当前用户查询已办任务列表
+	 * @param model
+	 * @return
+	 */
+	@GetMapping(value = "querypProcessedList")
+	public Object querypProcessedList(Page<WorkItem> page) {
+		SysUser user = SysUserFeignService.queryUserInfo();
+
+		snakerEngine.query().getHistoryWorkItems(page, new QueryFilter().setOperator(user.getUsername()));
+		return succeed(page);
+	}
+
+	@PostMapping(value = "actor/add")
+	public Object addTaskActor(String orderId, String taskName, String operator) {
+		List<Task> tasks = snakerEngine.query().getActiveTasks(new QueryFilter().setOrderId(orderId));
+		for (Task task : tasks) {
+			if (task.getTaskName().equalsIgnoreCase(taskName) && StringUtils.isNotEmpty(operator)) {
+				snakerEngine.task().addTaskActor(task.getId(), operator);
+			}
+		}
+		return succeed();
+	}
+
+	@GetMapping(value = "tip")
+	public Object addTaskActor(String orderId, String taskName) {
+		List<Task> tasks = snakerEngine.query().getActiveTasks(new QueryFilter().setOrderId(orderId));
+		StringBuilder builder = new StringBuilder();
+		String createTime = "";
+		for (Task task : tasks) {
+			if (task.getTaskName().equalsIgnoreCase(taskName)) {
+				String[] actors = snakerEngine.query().getTaskActorsByTaskId(task.getId());
+				for (String actor : actors) {
+					builder.append(actor).append(",");
+				}
+				createTime = task.getCreateTime();
+			}
+		}
+		if (builder.length() > 0) {
+			builder.deleteCharAt(builder.length() - 1);
+		}
+		Map<String, String> data = new HashMap<String, String>();
+		data.put("actors", builder.toString());
+		data.put("createTime", createTime);
+		return succeed(data);
+	}
+
+	/**
+	 * 活动任务查询列表
+	 * @param model
+	 * @return
+	 */
+	@GetMapping(value = "active/more")
+	public Object activeTaskList(Page<WorkItem> page, Integer taskType) {
+		SysUser user = SysUserFeignService.queryUserInfo();
+
+		List<String> list = new ArrayList<String>();
+		list.add(user.getUsername());
+
+		String[] assignees = new String[list.size()];
+		list.toArray(assignees);
+		snakerEngine.query().getWorkItems(page, new QueryFilter().setOperators(assignees).setTaskType(taskType));
+		return succeed(page);
+	}
+
+	/**
+	 * 活动任务查询列表
+	 * @param model
+	 * @return
+	 */
+	@GetMapping(value = "active/ccmore")
+	public Object activeCCList(Page<HistoryOrder> page) {
+		SysUser user = SysUserFeignService.queryUserInfo();
+
+		List<String> list = new ArrayList<String>();
+		list.add(user.getUsername());
+
+		String[] assignees = new String[list.size()];
+		list.toArray(assignees);
+		snakerEngine.query().getCCWorks(page, new QueryFilter().setOperators(assignees).setState(AccessService.STATE_ACTIVE));
+		return succeed(page);
+	}
+
+	/**
+	 * 活动任务的驳回
+	 * @param model
+	 * @param taskId
+	 * @return
+	 */
+	@PostMapping(value = "reject")
+	public Object activeTaskReject(String taskId) {
+
+		SysUser user = SysUserFeignService.queryUserInfo();
+
+		snakerEngine.executeAndJumpTask(taskId, user.getUsername(), null, null);
+		return succeed();
+	}
+
+	/**
+	 * 历史任务撤回
+	 * @param orderId
+	 * @return
+	 */
+	@PostMapping(value = "undo")
+	public Object historyTaskUndo(String orderId) {
+		SysUser user = SysUserFeignService.queryUserInfo();
+		snakerEngine.order().withdraw(orderId, user.getUsername());
+		return succeed();
+	}
+}

+ 45 - 19
mec-web/src/main/java/com/ym/mec/web/controller/TeacherController.java → mec-teacher/src/main/java/com/ym/mec/teacher/controller/TeacherController.java

@@ -1,21 +1,24 @@
-package com.ym.mec.web.controller;
-
-import com.ym.mec.common.security.SecurityUtils;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
-
-import java.util.Date;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
+package com.ym.mec.teacher.controller;
 
+import com.ym.mec.auth.api.client.SysUserFeignService;
+import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.biz.dal.entity.Teacher;
 import com.ym.mec.biz.dal.page.TeacherQueryInfo;
 import com.ym.mec.biz.dal.page.VipClassQueryInfo;
 import com.ym.mec.biz.service.ClassGroupService;
 import com.ym.mec.biz.service.TeacherService;
 import com.ym.mec.common.controller.BaseController;
+import com.ym.mec.common.page.QueryInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Date;
 
 @RequestMapping("teacher")
 @Api(tags = "教师服务")
@@ -27,6 +30,8 @@ public class TeacherController extends BaseController {
 
     @Autowired
     private ClassGroupService classGroupService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
 
     @ApiOperation(value = "新增教师")
     @PostMapping("/add")
@@ -48,17 +53,17 @@ public class TeacherController extends BaseController {
         return succeed();
     }
 
-    @ApiOperation(value = "删除教师")
-    @PostMapping("/delete/{userId}")
-    public Object update(@PathVariable("userId") Long userId) {
+    /*@ApiOperation(value = "删除教师")
+    @PostMapping("/delete")
+    public Object update(Long userId) {
         teacherService.deleteTeacher(userId);
         return succeed();
-    }
+    }*/
 
     @ApiOperation(value = "根据教师编号查询教师基本信息")
-    @GetMapping("/get/{id}")
+    @GetMapping("/get")
     @ApiParam(value = "教师编号", required = true)
-    public Object get(@PathVariable("id") Integer id) {
+    public Object get(Integer id) {
         return succeed(teacherService.getDetail(id));
     }
 
@@ -69,9 +74,9 @@ public class TeacherController extends BaseController {
     }
 
     @ApiOperation(value = "根据教师编号查询教师课程班列表")
-    @GetMapping("/getClass/{id}")
+    @GetMapping("/getClass")
     @ApiParam(value = "教师编号", required = true)
-    public Object getClassGroup(@PathVariable("id") Integer id) {
+    public Object getClassGroup(Integer id) {
         return succeed(classGroupService.findClassGroup4Teacher(id));
     }
 
@@ -87,4 +92,25 @@ public class TeacherController extends BaseController {
     public Object getTeacherVipClass(VipClassQueryInfo queryInfo){
         return succeed(classGroupService.getTeacherVipClass(queryInfo));
     }
+
+    @ApiOperation(value = "获取教师所有聊天群组")
+    @GetMapping("/queryTeacherGroups")
+    public Object queryTeacherGroups(String search){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if(sysUser == null){
+            return failed("获取用户信息失败");
+        }
+        return succeed(teacherService.queryTeacherGroups(sysUser.getId(),search));
+    }
+
+    @ApiOperation(value = "获取和当前教师相关的所有学员聊天列表")
+    @GetMapping("/queryGroupStudents")
+    public Object queryGroupStudents(String search){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if(sysUser == null){
+            return failed("获取用户信息失败");
+        }
+        return succeed(teacherService.queryGroupStudents(sysUser.getId(),search));
+    }
+
 }

+ 11 - 7
mec-teacher/src/main/java/com/ym/mec/teacher/controller/TeacherCourseScheduleController.java

@@ -1,6 +1,7 @@
 package com.ym.mec.teacher.controller;
 
 import com.ym.mec.biz.dal.dto.ClassDateAdjustDto;
+import com.ym.mec.biz.dal.dto.CourseScheduleDto;
 import com.ym.mec.biz.dal.enums.StudentAttendanceStatusEnum;
 import com.ym.mec.biz.dal.page.StudentAttendanceQueryInfo;
 import com.ym.mec.biz.service.CourseScheduleService;
@@ -14,8 +15,7 @@ import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.Date;
-import java.util.Objects;
+import java.util.*;
 
 /**
  * @Author Joburgess
@@ -31,7 +31,7 @@ public class TeacherCourseScheduleController extends BaseController {
     @Autowired
     private StudentAttendanceService studentAttendanceService;
 
-    @ApiOperation(value = "根据月份获取乐团在该月有课的日期")
+    @ApiOperation(value = "根据月份获取该月有课的日期")
     @GetMapping("/getCourseScheduleDateByMonth")
     public Object getCourseScheduleDateByMonth(@ApiParam(value = "月份", required = true) @RequestParam Date month) {
         if(Objects.isNull(month)){
@@ -46,19 +46,23 @@ public class TeacherCourseScheduleController extends BaseController {
         if(Objects.isNull(date)){
             return failed(HttpStatus.FORBIDDEN, "请指定日期!");
         }
-        return succeed(scheduleService.getTeacherCourseSchedulesWithDate(date));
+        List<CourseScheduleDto> teacherCourseSchedulesWithDate = scheduleService.getTeacherCourseSchedulesWithDate(date);
+        Map<String,Object> result = new HashMap<>();
+        result.put("rows",teacherCourseSchedulesWithDate);
+        result.put("appealDaysRange",1);
+        return succeed(result);
     }
 
     @ApiOperation(value = "根据课程ID查询正在或即将开始的课程")
-    @GetMapping("/getCurrentCourseDetail/{courseID}")
-    public Object getCurrentCourseDetail(@ApiParam(value = "课程ID", required = true) @PathVariable("courseID") Long courseID){
+    @GetMapping("/getCurrentCourseDetail")
+    public Object getCurrentCourseDetail(Long courseID){
         if(Objects.isNull(courseID)){
             return failed(HttpStatus.FORBIDDEN, "请指定课程!");
         }
         return succeed(scheduleService.getCurrentCourseDetail(courseID));
     }
 
-    @ApiOperation(value = "根据班级ID获取当前课程的学生")
+    @ApiOperation(value = "根据班级ID获取当前课程的学生列表")
     @GetMapping("/getCurrentCourseStudents")
     public Object getCurrentCourseStudents(StudentAttendanceQueryInfo queryInfo){
         if(Objects.isNull(queryInfo.getClassGroupId())){

+ 131 - 0
mec-util/src/main/java/com/ym/mec/util/money/MoneyUtil.java

@@ -0,0 +1,131 @@
+package com.ym.mec.util.money;
+
+public class MoneyUtil {  
+    /** 大写数字 */  
+    private static final String[] NUMBERS = { "零", "壹", "贰", "叁", "肆", "伍",  
+            "陆", "柒", "捌", "玖" };  
+  
+    /** 整数部分的单位 */  
+    private static final String[] IUNIT = { "元", "拾", "佰", "仟", "万", "拾", "佰",  
+            "仟", "亿", "拾", "佰", "仟", "万", "拾", "佰", "仟" };  
+  
+    /** 小数部分的单位 */  
+    private static final String[] DUNIT = { "角", "分", "厘" };  
+  
+    /** 
+     * 得到大写金额。 
+     */  
+    public static String toChinese(String str) {  
+        str = str.replaceAll(",", "");// 去掉","  
+        String integerStr;// 整数部分数字  
+        String decimalStr;// 小数部分数字  
+        // 初始化:分离整数部分和小数部分  
+        if (str.indexOf(".") > 0) {  
+            integerStr = str.substring(0, str.indexOf("."));  
+            decimalStr = str.substring(str.indexOf(".") + 1);  
+        } else if (str.indexOf(".") == 0) {  
+            integerStr = "";  
+            decimalStr = str.substring(1);  
+        } else {  
+            integerStr = str;  
+            decimalStr = "";  
+        }  
+        // integerStr去掉首0,不必去掉decimalStr的尾0(超出部分舍去)  
+        if (!integerStr.equals("")) {  
+            integerStr = Long.toString(Long.parseLong(integerStr));  
+            if (integerStr.equals("0")) {  
+                integerStr = "";  
+            }  
+        }  
+        // overflow超出处理能力,直接返回  
+        if (integerStr.length() > IUNIT.length) {  
+            System.out.println(str + ":超出处理能力");  
+            return str;  
+        }  
+  
+        int[] integers = toArray(integerStr);// 整数部分数字  
+        boolean isMust5 = isMust5(integerStr);// 设置万单位  
+        int[] decimals = toArray(decimalStr);// 小数部分数字  
+        return getChineseInteger(integers, isMust5)  
+                + getChineseDecimal(decimals);  
+    }  
+  
+    /** 
+     * 整数部分和小数部分转换为数组,从高位至低位 
+     */  
+    private static int[] toArray(String number) {  
+        int[] array = new int[number.length()];  
+        for (int i = 0; i < number.length(); i++) {  
+            array[i] = Integer.parseInt(number.substring(i, i + 1));  
+        }  
+        return array;  
+    }  
+  
+    /** 
+     * 得到中文金额的整数部分。 
+     */
+    private static String getChineseInteger(int[] integers, boolean isMust5) {  
+        StringBuffer chineseInteger = new StringBuffer("");  
+        int length = integers.length;  
+        for (int i = 0; i < length; i++) {  
+            // 0出现在关键位置:1234(万)5678(亿)9012(万)3456(元)  
+            // 特殊情况:10(拾元、壹拾元、壹拾万元、拾万元)  
+            String key = "";  
+            if (integers[i] == 0) {  
+                if ((length - i) == 13)// 万(亿)(必填)  
+                    key = IUNIT[4];  
+                else if ((length - i) == 9)// 亿(必填)  
+                    key = IUNIT[8];  
+                else if ((length - i) == 5 && isMust5)// 万(不必填)  
+                    key = IUNIT[4];  
+                else if ((length - i) == 1)// 元(必填)  
+                    key = IUNIT[0];  
+                // 0遇非0时补零,不包含最后一位  
+                if ((length - i) > 1 && integers[i + 1] != 0)  
+                    key += NUMBERS[0];  
+            }  
+            chineseInteger.append(integers[i] == 0 ? key  
+                    : (NUMBERS[integers[i]] + IUNIT[length - i - 1]));  
+        }  
+        return chineseInteger.toString();  
+    }  
+  
+    /** 
+     * 得到中文金额的小数部分。 
+     */  
+    private static String getChineseDecimal(int[] decimals) {  
+        StringBuffer chineseDecimal = new StringBuffer("");  
+        for (int i = 0; i < decimals.length; i++) {  
+            // 舍去3位小数之后的  
+            if (i == 3)  
+                break;  
+            chineseDecimal.append(decimals[i] == 0 ? ""  
+                    : (NUMBERS[decimals[i]] + DUNIT[i]));  
+        }  
+        return chineseDecimal.toString();  
+    }  
+  
+    /** 
+     * 判断第5位数字的单位"万"是否应加。 
+     */  
+    private static boolean isMust5(String integerStr) {  
+        int length = integerStr.length();  
+        if (length > 4) {  
+            String subInteger = "";  
+            if (length > 8) {  
+                // 取得从低位数,第5到第8位的字串  
+                subInteger = integerStr.substring(length - 8, length - 4);  
+            } else {  
+                subInteger = integerStr.substring(0, length - 4);  
+            }  
+            return Integer.parseInt(subInteger) > 0;  
+        } else {  
+            return false;  
+        }  
+    }  
+  
+    public static void main(String[] args) {  
+        System.out.println(MoneyUtil.toChinese("500100001.23"));  
+    }  
+  
+}  

+ 7 - 0
mec-web/src/main/java/com/ym/mec/web/config/WebMvcConfig.java

@@ -9,6 +9,7 @@ import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
 import java.util.Date;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Primary;
@@ -57,6 +58,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
 		objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
 		// 序列化BigDecimal时不使用科学计数法输出
 		objectMapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
+		objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
+			@Override
+			public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
+				jsonGenerator.writeString(StringUtils.EMPTY);
+			}
+		});
 		// 日期和时间格式化
 		JavaTimeModule javaTimeModule = new JavaTimeModule();
 		javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

+ 43 - 2
mec-web/src/main/java/com/ym/mec/web/controller/VipGroupManageController.java

@@ -1,21 +1,26 @@
 package com.ym.mec.web.controller;
 
+import com.ym.mec.biz.dal.dto.ClassDateAdjustDto;
 import com.ym.mec.biz.dal.dto.VipGroupApplyDto;
 import com.ym.mec.biz.dal.entity.StudentApplyRefunds;
 import com.ym.mec.biz.dal.entity.VipGroup;
 import com.ym.mec.biz.dal.page.VipGroupAttendanceQueryInfo;
 import com.ym.mec.biz.dal.page.VipGroupQueryInfo;
+import com.ym.mec.biz.dal.page.VipGroupSalaryQueryInfo;
 import com.ym.mec.biz.dal.page.VipGroupTeachingRecordQueryInfo;
+import com.ym.mec.biz.service.CourseScheduleService;
 import com.ym.mec.biz.service.VipGroupService;
 import com.ym.mec.common.controller.BaseController;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
 import org.springframework.web.bind.annotation.*;
 
 import java.math.BigDecimal;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Objects;
 
 /**
  * @Author Joburgess
@@ -28,6 +33,8 @@ public class VipGroupManageController extends BaseController {
 
     @Autowired
     private VipGroupService vipGroupService;
+    @Autowired
+    private CourseScheduleService scheduleService;
 
     @ApiOperation(value = "vip课申请")
     @PostMapping("/vipGroupApply")
@@ -49,8 +56,8 @@ public class VipGroupManageController extends BaseController {
     }
 
     @ApiOperation(value = "vip课详情")
-    @GetMapping("/getVipGroupDetail/{vipGroupId}")
-    public Object getVipGroupDetail(@PathVariable("vipGroupId") Long vipGroupId){
+    @GetMapping("/getVipGroupDetail")
+    public Object getVipGroupDetail(Long vipGroupId){
         return succeed(vipGroupService.getVipGroupDetail(vipGroupId));
     }
 
@@ -95,4 +102,38 @@ public class VipGroupManageController extends BaseController {
         return succeed(results);
     }
 
+    @ApiOperation(value = "停止vip课")
+    @PostMapping("/stopVipGroup")
+    public Object stopVipGroup(Long vipGroupId){
+        if(Objects.isNull(vipGroupId)){
+            return failed(HttpStatus.FORBIDDEN,"请指定vip课");
+        }
+
+        //停止vip课逻辑
+
+        return succeed();
+    }
+
+    @ApiOperation(value = "获取vip课财务信息")
+    @GetMapping("/findVipGroupSalarys")
+    public Object findVipGroupSalarys(VipGroupSalaryQueryInfo queryInfo){
+        return succeed(vipGroupService.findVipGroupSalarys(queryInfo));
+    }
+
+    @ApiOperation(value = "获取当前课程上课学员")
+    @GetMapping("/findVipGroupAttendanceStudents")
+    public Object findVipGroupStudents(Long courseScheduleId){
+        return succeed(vipGroupService.findVipGroupAttendanceStudents(courseScheduleId));
+    }
+
+    @ApiOperation(value = "课时调整")
+    @PostMapping(value = "/classStartDateAdjust")
+    public Object classStartDateAdjust(ClassDateAdjustDto classDateAdjustDto){
+        if(Objects.isNull(classDateAdjustDto.getId())){
+            return failed(HttpStatus.FORBIDDEN, "请指定课程!");
+        }
+        scheduleService.classStartDateAdjust(classDateAdjustDto);
+        return succeed();
+    }
+
 }

+ 1 - 1
mec-web/src/main/java/com/ym/mec/web/controller/student/StudentAttendanceController.java

@@ -25,7 +25,7 @@ public class StudentAttendanceController extends BaseController {
     @Autowired
     private StudentAttendanceService studentAttendanceService;
 
-    @ApiOperation(value = "批量插入学生上课签到信息")
+    @ApiOperation(value = "点名完成")
     @PostMapping("/addStudentAttendances")
     public Object addStudentAttendances(@RequestBody List<StudentAttendance> studentAttendances){
         studentAttendanceService.addStudentAttendances(studentAttendances);

+ 7 - 0
mec-workflow/src/main/java/com/ym/mec/workfow/config/WebMvcConfig.java

@@ -9,6 +9,7 @@ import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
 import java.util.Date;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Primary;
@@ -57,6 +58,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
 		objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
 		// 序列化BigDecimal时不使用科学计数法输出
 		objectMapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
+		objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
+			@Override
+			public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
+				jsonGenerator.writeString(StringUtils.EMPTY);
+			}
+		});
 		// 日期和时间格式化
 		JavaTimeModule javaTimeModule = new JavaTimeModule();
 		javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));