Bläddra i källkod

Merge branch 'saas_yonge' into master_saas

yonge 3 år sedan
förälder
incheckning
bcdcfde9ec
43 ändrade filer med 2216 tillägg och 77 borttagningar
  1. 29 0
      audio-analysis/src/main/java/com/yonge/netty/dto/NoteFrequencyRange.java
  2. 44 2
      audio-analysis/src/main/java/com/yonge/netty/dto/UserChannelContext.java
  3. 1 1
      cms/src/main/java/com/ym/mec/cms/config/ResourceServerConfig.java
  4. 3 0
      mec-auth/mec-auth-server/src/main/resources/config/mybatis/SysUserMapper.xml
  5. 4 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/MusicGroupPaymentCalenderDao.java
  6. 17 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TeacherContractsDao.java
  7. 27 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TenantContractTemplateDao.java
  8. 7 5
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TenantInfoDao.java
  9. 16 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/TenantContractTemplateDto.java
  10. 18 4
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/MusicGroup.java
  11. 103 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/TeacherContracts.java
  12. 159 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/TenantContractTemplate.java
  13. 17 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/TenantContractTemplateQueryInfo.java
  14. 16 0
      mec-biz/src/main/java/com/ym/mec/biz/service/TeacherContractsService.java
  15. 45 0
      mec-biz/src/main/java/com/ym/mec/biz/service/TenantContractTemplateService.java
  16. 35 13
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ContractServiceImpl.java
  17. 6 8
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleTeacherSalaryServiceImpl.java
  18. 9 5
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/MusicGroupServiceImpl.java
  19. 121 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/TeacherContractsServiceImpl.java
  20. 47 7
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/TeacherServiceImpl.java
  21. 138 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/TenantContractTemplateServiceImpl.java
  22. 140 0
      mec-biz/src/main/resources/config/contracts/latest_contract_template.ftl
  23. 3 3
      mec-biz/src/main/resources/config/contracts/product4.ftl
  24. 8 0
      mec-biz/src/main/resources/config/mybatis/MusicGroupPaymentCalenderMapper.xml
  25. 126 0
      mec-biz/src/main/resources/config/mybatis/TeacherContractsMapper.xml
  26. 3 0
      mec-biz/src/main/resources/config/mybatis/TeacherMapper.xml
  27. 155 0
      mec-biz/src/main/resources/config/mybatis/TenantContractTemplateMapper.xml
  28. 4 0
      mec-biz/src/main/resources/config/mybatis/TenantInfoMapper.xml
  29. 4 0
      mec-client-api/src/main/java/com/ym/mec/task/TaskRemoteService.java
  30. 5 0
      mec-client-api/src/main/java/com/ym/mec/task/fallback/TaskRemoteServiceFallback.java
  31. 3 8
      mec-common/common-core/src/main/java/com/ym/mec/common/service/BaseService.java
  32. 19 0
      mec-task/src/main/java/com/ym/mec/task/jobs/TeacherContractTask.java
  33. 1 1
      mec-teacher/src/main/java/com/ym/mec/teacher/config/ResourceServerConfig.java
  34. 80 0
      mec-teacher/src/main/java/com/ym/mec/teacher/controller/TeacherContractController.java
  35. 1 1
      mec-teacher/src/main/java/com/ym/mec/teacher/controller/TeacherController.java
  36. 128 0
      mec-thirdparty/src/main/java/com/ym/mec/thirdparty/lingxinpay/ContractSignService.java
  37. 443 0
      mec-thirdparty/src/main/java/com/ym/mec/thirdparty/lingxinpay/RSA.java
  38. 36 1
      mec-util/src/main/java/com/ym/mec/util/freemarker/FreemarkerTemplateEngine.java
  39. 3 3
      mec-web/src/main/java/com/ym/mec/web/controller/ExportController.java
  40. 62 15
      mec-web/src/main/java/com/ym/mec/web/controller/TaskController.java
  41. 43 0
      mec-web/src/main/java/com/ym/mec/web/controller/TeacherContractController.java
  42. 83 0
      mec-web/src/main/java/com/ym/mec/web/controller/TenantContractTemplateController.java
  43. 4 0
      mec-web/src/main/java/com/ym/mec/web/controller/education/EduMusicScoreController.java

+ 29 - 0
audio-analysis/src/main/java/com/yonge/netty/dto/NoteFrequencyRange.java

@@ -1,6 +1,8 @@
 package com.yonge.netty.dto;
 
 import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * 一个音符的频率范围,包含最大值和最小值
@@ -70,9 +72,36 @@ public class NoteFrequencyRange {
 		return false;
 	}
 	
+	@Override
+	public int hashCode() {
+		int result = 17;
+		result = 31 * result + Double.hashCode(minFrequency);
+		result = 31 * result + Double.hashCode(maxFrequency);
+		return result;
+	}
+
 	public static void main(String[] args) {
+		
+		Map<NoteFrequencyRange,Integer> map = new HashMap<NoteFrequencyRange, Integer>();
+		
 		NoteFrequencyRange nfr = new NoteFrequencyRange(442,442);
 		System.out.println(nfr.getMinFrequency() + "-"+ nfr.getMaxFrequency());
+		
+		if(map.containsKey(nfr) == false){
+			map.put(nfr, 1);
+		}
+
+		NoteFrequencyRange nfr1 = new NoteFrequencyRange(442,430);
+		System.out.println(nfr1.getMinFrequency() + "-"+ nfr1.getMaxFrequency());
+		
+		if(map.containsKey(nfr1) == false){
+			map.put(nfr1, 1);
+		}else{
+			map.put(nfr, 2);
+		}
+		
+		System.out.println(nfr.equals(nfr1));
+		System.out.println(map.size());
 	}
 
 }

+ 44 - 2
audio-analysis/src/main/java/com/yonge/netty/dto/UserChannelContext.java

@@ -7,6 +7,7 @@ import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -727,9 +728,48 @@ public class UserChannelContext {
 		NoteFrequencyRange noteFrequencyRange = null;
 		ChunkAnalysis chunkAnalysis = null;
 		boolean tempo = false;
-		boolean isContinue = true;
-		int unplayedSize = 0;
+		//boolean isContinue = true;
+		//int unplayedSize = 0;
 		int firstPeakIndex = -1;
+		
+		//将信号分堆归类
+		Map<NoteFrequencyRange, Integer> signalGrouping = new HashMap<NoteFrequencyRange, Integer>();
+		
+		for (int i = 0; i < chunkList.size(); i++) {
+			chunkAnalysis = chunkList.get(i);
+			if (chunkAnalysis != null) {
+				if (chunkAnalysis.getFrequency() > MIN_FREQUECY || firstPeakIndex > -1) {
+					
+					if (firstPeakIndex == -1) {
+						firstPeakIndex = i;
+					}
+					
+					noteFrequencyRange = new NoteFrequencyRange(standardFrequecy, chunkAnalysis.getFrequency());
+					
+					if (signalGrouping.containsKey(noteFrequencyRange)) {
+						signalGrouping.put(noteFrequencyRange, signalGrouping.get(noteFrequencyRange) + 1);
+					} else {
+						signalGrouping.put(noteFrequencyRange, 1);
+					}
+				}
+			}
+		}
+		
+		Integer maxTimes = 0, totalTimes = 0;
+		
+		for (Entry<NoteFrequencyRange, Integer> entry : signalGrouping.entrySet()) {
+			if (entry.getValue() > maxTimes) {
+				maxTimes = entry.getValue();
+			}
+			totalTimes = totalTimes + entry.getValue();
+		}
+		
+		if (maxTimes / totalTimes < hardLevel.getIntegrityRange()) {
+			tempo = false;
+			LOGGER.debug("节奏错误原因:不是同一个音");
+		}
+		
+		/**
 		for (int i = 0; i < chunkList.size(); i++) {
 			chunkAnalysis = chunkList.get(i);
 			if (chunkAnalysis != null) {
@@ -766,6 +806,7 @@ public class UserChannelContext {
 				}
 			}
 		}
+		*/
 		
 		if (tempo) {
 			// 判断进入时间点
@@ -939,6 +980,7 @@ public class UserChannelContext {
 		int standardPitch = 440; // a is 440 hz...
 		for (int x = 0; x < midi.length; ++x)
 		{
+			//转调
 		   midi[x] = new BigDecimal(standardPitch).multiply(new BigDecimal(Math.pow(2, new BigDecimal(x-69).divide(new BigDecimal(12),6,BigDecimal.ROUND_HALF_UP).doubleValue()))).doubleValue();
 		   System.out.println("x=" + x +"  "+ midi[x]);
 		}

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

@@ -27,7 +27,7 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
 		http.authorizeRequests()
 		.antMatchers("/task/**")
 		.hasIpAddress("0.0.0.0/0")
-				.antMatchers("/v2/api-docs", "/news/list", "/news/query", "/news/homeList", "/news/typeList")
+				.antMatchers("/v2/api-docs", "/news/list", "/news/query", "/news/homeList", "/news/typeList","/helpCenterContent/list")
 				.permitAll()
 				// 任何人不登录都可以获取的资源
 				// .antMatchers("/ipController/**").hasIpAddress("127.0.0.1") //特定ip可以不登录获取资源

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

@@ -154,6 +154,9 @@
             <if test="realName != null and realName != ''">
                 real_name_ = #{realName},
             </if>
+            <if test="idCardNo != null and idCardNo != ''">
+                id_card_no_ = #{idCardNo},
+            </if>
             <if test="isSuperAdmin != null">
                 is_super_admin_ = #{isSuperAdmin},
             </if>

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

@@ -7,8 +7,10 @@ import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender;
 import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PayUserType;
 import com.ym.mec.biz.dal.enums.PaymentStatusEnum;
 import com.ym.mec.common.dal.BaseDAO;
+
 import org.apache.ibatis.annotations.Param;
 
+import java.math.BigDecimal;
 import java.util.*;
 
 public interface MusicGroupPaymentCalenderDao extends BaseDAO<Long, MusicGroupPaymentCalender> {
@@ -322,4 +324,6 @@ public interface MusicGroupPaymentCalenderDao extends BaseDAO<Long, MusicGroupPa
     int countCalender(Map<String, Object> params);
 
     List<MusicGroupPaymentCalenderResultDto> queryCalenderPage(Map<String, Object> params);
+    
+    List<Map<String, BigDecimal>> queryChargeStandard(String musicGroupIdList);
 }

+ 17 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TeacherContractsDao.java

@@ -0,0 +1,17 @@
+package com.ym.mec.biz.dal.dao;
+
+import java.util.List;
+
+import com.ym.mec.biz.dal.entity.TeacherContracts;
+import com.ym.mec.common.dal.BaseDAO;
+
+public interface TeacherContractsDao extends BaseDAO<Long, TeacherContracts> {
+
+	TeacherContracts queryByUserId(Integer userId);
+	
+	TeacherContracts queryBySerialNo(String serialNo);
+	
+	List<TeacherContracts> queryNotUrlList();
+	
+	int batchUpdate(List<TeacherContracts> teacherContractsList);
+}

+ 27 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TenantContractTemplateDao.java

@@ -0,0 +1,27 @@
+package com.ym.mec.biz.dal.dao;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ibatis.annotations.Param;
+
+import com.ym.mec.common.dal.BaseDAO;
+import com.ym.mec.biz.dal.dto.TenantContractTemplateDto;
+import com.ym.mec.biz.dal.entity.TenantContractTemplate;
+
+public interface TenantContractTemplateDao extends BaseDAO<Integer, TenantContractTemplate> {
+
+	List<TenantContractTemplateDto> queryPageList(Map<String, Object> params);
+	
+	/**
+	 * 获取最新协议模板
+	 * @param owner
+	 * @param type
+	 * @return
+	 */
+	TenantContractTemplate queryLatestContractTemplate(@Param("owner") String owner, @Param("type") String type, @Param("tenantId") Integer tenantId);
+	
+	int disableContract(@Param("owner") String owner, @Param("type") String type, @Param("tenantId") Integer tenantId);
+	
+	Integer queryMaxVersion();
+}

+ 7 - 5
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TenantInfoDao.java

@@ -1,17 +1,19 @@
 package com.ym.mec.biz.dal.dao;
 
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ibatis.annotations.Param;
+
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ym.mec.biz.dal.entity.TenantInfo;
 import com.ym.mec.biz.dal.entity.TenantProductSumm;
-import org.apache.ibatis.annotations.Param;
-
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
 
 public interface TenantInfoDao extends BaseMapper<TenantInfo> {
+	
+	TenantInfo getLocked(Integer tenantId);
 
     <T> IPage<T> queryPage(Page<T> page, @Param("param") Map<String, Object> param);
 

+ 16 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/TenantContractTemplateDto.java

@@ -0,0 +1,16 @@
+package com.ym.mec.biz.dal.dto;
+
+import com.ym.mec.biz.dal.entity.TenantContractTemplate;
+
+public class TenantContractTemplateDto extends TenantContractTemplate {
+
+	private String latestOperator;
+
+	public String getLatestOperator() {
+		return latestOperator;
+	}
+
+	public void setLatestOperator(String latestOperator) {
+		this.latestOperator = latestOperator;
+	}
+}

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

@@ -1,15 +1,18 @@
 package com.ym.mec.biz.dal.entity;
 
+import io.swagger.annotations.ApiModelProperty;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
 import com.ym.mec.biz.dal.entity.CooperationOrgan.OwnershipType;
 import com.ym.mec.biz.dal.enums.CourseViewTypeEnum;
 import com.ym.mec.biz.dal.enums.MusicGroupStatusEnum;
 import com.ym.mec.biz.dal.enums.SalarySettlementTypeEnum;
 import com.ym.mec.biz.dal.enums.YesOrNoEnum;
 import com.ym.mec.common.entity.BaseEntity;
-import io.swagger.annotations.ApiModelProperty;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-
-import java.util.Date;
 
 /**
  * 对应数据库表(music_group):
@@ -193,6 +196,9 @@ public class MusicGroup extends BaseEntity {
 
 	@ApiModelProperty(value = "有乐保的人数",required = true)
 	private Integer hasInstrumentNum;
+	
+	@ApiModelProperty(value = "收费标准",required = false)
+	private BigDecimal chargeStandard;
 
 	public Integer getHasInstrumentNum() {
 		return hasInstrumentNum;
@@ -675,4 +681,12 @@ public class MusicGroup extends BaseEntity {
 	public void setMemberCourseShowFlag(Boolean memberCourseShowFlag) {
 		this.memberCourseShowFlag = memberCourseShowFlag;
 	}
+
+	public BigDecimal getChargeStandard() {
+		return chargeStandard;
+	}
+
+	public void setChargeStandard(BigDecimal chargeStandard) {
+		this.chargeStandard = chargeStandard;
+	}
 }

+ 103 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/TeacherContracts.java

@@ -0,0 +1,103 @@
+package com.ym.mec.biz.dal.entity;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+/**
+ * 对应数据库表(teacher_contracts):
+ */
+public class TeacherContracts {
+
+	/**  */
+	private Long id;
+	
+	/**  */
+	private Integer userId;
+	
+	/**  */
+	private String contractNo;
+	
+	/**  */
+	private String type;
+	
+	/**  */
+	private String url;
+	
+	/**  */
+	private String serialNo;
+	
+	/**  */
+	private java.util.Date createTime;
+	
+	/**  */
+	private Integer tenantId;
+	
+	public void setId(Long id){
+		this.id = id;
+	}
+	
+	public Long getId(){
+		return this.id;
+	}
+			
+	public void setUserId(Integer userId){
+		this.userId = userId;
+	}
+	
+	public Integer getUserId(){
+		return this.userId;
+	}
+			
+	public void setContractNo(String contractNo){
+		this.contractNo = contractNo;
+	}
+	
+	public String getContractNo(){
+		return this.contractNo;
+	}
+			
+	public void setType(String type){
+		this.type = type;
+	}
+	
+	public String getType(){
+		return this.type;
+	}
+			
+	public void setUrl(String url){
+		this.url = url;
+	}
+	
+	public String getUrl(){
+		return this.url;
+	}
+			
+	public void setSerialNo(String serialNo){
+		this.serialNo = serialNo;
+	}
+	
+	public String getSerialNo(){
+		return this.serialNo;
+	}
+			
+	public void setCreateTime(java.util.Date createTime){
+		this.createTime = createTime;
+	}
+	
+	public java.util.Date getCreateTime(){
+		return this.createTime;
+	}
+			
+	public void setTenantId(Integer tenantId){
+		this.tenantId = tenantId;
+	}
+	
+	public Integer getTenantId(){
+		return this.tenantId;
+	}
+			
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 159 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/TenantContractTemplate.java

@@ -0,0 +1,159 @@
+package com.ym.mec.biz.dal.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+/**
+ * 对应数据库表(tenant_contract_template):
+ */
+public class TenantContractTemplate {
+
+	@ApiModelProperty(value = "编号")
+	private Integer id;
+
+	@ApiModelProperty(value = "协议名称")
+	private String name;
+
+	@ApiModelProperty(value = "协议类型")
+	private String type;
+
+	@ApiModelProperty(value = "协议内容")
+	private String contractTemplateContent;
+
+	@ApiModelProperty(value = "原始协议文件url")
+	private String origanalFileUrl;
+
+	@ApiModelProperty(value = "协议号")
+	private String contractNo;
+
+	@ApiModelProperty(value = "是否启用(1-启用  0-不启用)")
+	private Boolean status;
+
+	@ApiModelProperty(value = "协议版本号")
+	private Integer version;
+
+	@ApiModelProperty(value = "最后修改人编号")
+	private Integer modifyBy;
+
+	@ApiModelProperty(value = "最后修改时间")
+	private java.util.Date updateTime;
+
+	@ApiModelProperty(value = "创建时间")
+	private java.util.Date createTime;
+
+	@ApiModelProperty(value = "甲方")
+	private String owner;
+	
+	private Integer tenantId;
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	public Integer getId() {
+		return this.id;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getName() {
+		return this.name;
+	}
+
+	public void setContractTemplateContent(String contractTemplateContent) {
+		this.contractTemplateContent = contractTemplateContent;
+	}
+
+	public String getContractTemplateContent() {
+		return this.contractTemplateContent;
+	}
+
+	public void setOriganalFileUrl(String origanalFileUrl) {
+		this.origanalFileUrl = origanalFileUrl;
+	}
+
+	public String getOriganalFileUrl() {
+		return this.origanalFileUrl;
+	}
+
+	public void setContractNo(String contractNo) {
+		this.contractNo = contractNo;
+	}
+
+	public String getContractNo() {
+		return this.contractNo;
+	}
+
+	public void setStatus(boolean status) {
+		this.status = status;
+	}
+
+	public boolean getStatus() {
+		return this.status;
+	}
+
+	public void setVersion(Integer version) {
+		this.version = version;
+	}
+
+	public Integer getVersion() {
+		return this.version;
+	}
+
+	public void setModifyBy(Integer modifyBy) {
+		this.modifyBy = modifyBy;
+	}
+
+	public Integer getModifyBy() {
+		return this.modifyBy;
+	}
+
+	public void setUpdateTime(java.util.Date updateTime) {
+		this.updateTime = updateTime;
+	}
+
+	public java.util.Date getUpdateTime() {
+		return this.updateTime;
+	}
+
+	public void setCreateTime(java.util.Date createTime) {
+		this.createTime = createTime;
+	}
+
+	public java.util.Date getCreateTime() {
+		return this.createTime;
+	}
+
+	public String getType() {
+		return type;
+	}
+
+	public void setType(String type) {
+		this.type = type;
+	}
+
+	public String getOwner() {
+		return owner;
+	}
+
+	public void setOwner(String owner) {
+		this.owner = owner;
+	}
+
+	public Integer getTenantId() {
+		return tenantId;
+	}
+
+	public void setTenantId(Integer tenantId) {
+		this.tenantId = tenantId;
+	}
+
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 17 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/page/TenantContractTemplateQueryInfo.java

@@ -0,0 +1,17 @@
+package com.ym.mec.biz.dal.page;
+
+import com.ym.mec.common.page.QueryInfo;
+
+public class TenantContractTemplateQueryInfo extends QueryInfo {
+
+    private Boolean status;
+
+	public Boolean getStatus() {
+		return status;
+	}
+
+	public void setStatus(Boolean status) {
+		this.status = status;
+	}
+
+}

+ 16 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/TeacherContractsService.java

@@ -0,0 +1,16 @@
+package com.ym.mec.biz.service;
+
+import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.biz.dal.entity.TeacherContracts;
+import com.ym.mec.common.service.BaseService;
+
+public interface TeacherContractsService extends BaseService<Long, TeacherContracts> {
+
+	TeacherContracts queryByUserId(Integer userId);
+	
+	boolean sign(SysUser user);
+	
+	boolean callback(String jsonStr);
+	
+	public void queryTeacherContractSignStatus();
+}

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

@@ -0,0 +1,45 @@
+package com.ym.mec.biz.service;
+
+import com.ym.mec.biz.dal.dto.TenantContractTemplateDto;
+import com.ym.mec.biz.dal.entity.TenantContractTemplate;
+import com.ym.mec.common.page.PageInfo;
+import com.ym.mec.common.page.QueryInfo;
+import com.ym.mec.common.service.BaseService;
+
+public interface TenantContractTemplateService extends BaseService<Integer, TenantContractTemplate> {
+	
+	/**
+	 * 分页查询
+	 * @param queryInfo
+	 * @return
+	 */
+	PageInfo<TenantContractTemplateDto> queryPageList(QueryInfo queryInfo);
+	
+	/**
+	 * 启用协议
+	 * @param id
+	 * @param userId 操作人
+	 * @return
+	 */
+	boolean enableContract(Integer id, Integer userId);
+
+	/**
+	 * 更新协议版本
+	 * @return
+	 */
+	boolean updateContractVersion();
+	
+	/**
+	 * 查询最新协议模板
+	 * @param tenantId
+	 * @param owner
+	 * @param type
+	 * @return
+	 */
+	TenantContractTemplate queryLatestContractTemplate(Integer tenantId, String owner, String type);
+	
+	boolean createContractTemplate(TenantContractTemplate tenantContractTemplate);
+	
+	boolean updateContractTempalte(TenantContractTemplate tenantContractTemplate);
+	
+}

+ 35 - 13
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ContractServiceImpl.java

@@ -16,6 +16,7 @@ import com.ym.mec.biz.service.*;
 import com.ym.mec.common.controller.BaseController;
 import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.exception.BizException;
+import com.ym.mec.common.tenant.TenantContextHolder;
 import com.ym.mec.thirdparty.eseal.ESealPlugin;
 import com.ym.mec.thirdparty.storage.StoragePluginContext;
 import com.ym.mec.thirdparty.storage.provider.KS3StoragePlugin;
@@ -25,6 +26,7 @@ import com.ym.mec.util.date.DateUtil;
 import com.ym.mec.util.freemarker.FreemarkerTemplateEngine;
 import com.ym.mec.util.money.MoneyUtil;
 import com.ym.mec.util.pdf.PDFUtil;
+
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
@@ -115,6 +117,9 @@ public class ContractServiceImpl implements ContractService, InitializingBean {
     
     @Autowired
     private TenantConfigService tenantConfigService;
+    
+    @Autowired
+    private TenantContractTemplateService tenantContractTemplateService;
 
     @Value("${contract.baseDir:/var/pdf}")
     private String contractBaseDir;
@@ -907,8 +912,18 @@ public class ContractServiceImpl implements ContractService, InitializingBean {
         if (Objects.nonNull(courseViewType)) {
             ownershipType = courseViewType;
         }
+		
+        // 查询最新协议模板
+		TenantContractTemplate tenantContractTemplate = tenantContractTemplateService.queryLatestContractTemplate(TenantContextHolder.getTenantId(), null, null);
+		if(tenantContractTemplate == null){
+			logger.error("最新协议模板查询失败");
+			return;
+		}
+		String mainContent = tenantContractTemplate.getContractTemplateContent();
+		params.put("contractMainContent", mainContent);
 
-        List<SysUserContracts> userContracts = sysUserContractsService.getUserContractWithType(userId, ContractType.PRODUCT, ownershipType.getContractVersion());
+        // 查询是否已生成协议
+        List<SysUserContracts> userContracts = sysUserContractsService.getUserContractWithType(userId, ContractType.PRODUCT, tenantContractTemplate.getVersion());
         if (!CollectionUtils.isEmpty(userContracts)) {
             return;
         }
@@ -923,20 +938,20 @@ public class ContractServiceImpl implements ContractService, InitializingBean {
 			throw new BizException("机构配置信息查询失败");
 		}
 		
-		params.put("compayName", tenantInfo.getTsignName());
+		params.put("companyName", tenantInfo.getTsignName());
 		params.put("sealPicture", tenantConfig.getCorporateChops());
         
 		if (studentInfo.getTenantId() == 1) {
 			if (OwnershipType.OWN.name().equals(params.get("ownershipType"))) {
-				params.put("compayName", "深圳大雅乐盟网络教育股份有限公司");
+				params.put("companyName", "深圳大雅乐盟网络教育股份有限公司");
 				params.put("sealPicture", "https://daya-online.oss-cn-beijing.aliyuncs.com/website/cachet.png");
 			} else {
-				params.put("compayName", "武汉长乐长风乐器销售有限公司");
+				params.put("companyName", "武汉长乐长风乐器销售有限公司");
 				params.put("sealPicture", "https://daya-online.oss-cn-beijing.aliyuncs.com/website/clcf.png");
 			}
 		}
 
-        templateEngine.render(params, "product" + ownershipType.getContractVersion() + ".ftl", srcFile);
+        templateEngine.render(params, "latest_contract_template.ftl", srcFile);
 
         // 生成借款协议PDF
         try {
@@ -979,7 +994,7 @@ public class ContractServiceImpl implements ContractService, InitializingBean {
         sysUserContracts.setType(ContractType.PRODUCT);
         sysUserContracts.setUrl(pdfFilePath);
         sysUserContracts.setUserId(userId);
-        sysUserContracts.setVersion(ownershipType.getContractVersion());
+        sysUserContracts.setVersion(tenantContractTemplate.getVersion());
 
         sysUserContractsService.insert(sysUserContracts);
 
@@ -1049,20 +1064,27 @@ public class ContractServiceImpl implements ContractService, InitializingBean {
 			throw new BizException("机构配置信息查询失败");
 		}
 		
-		params.put("compayName", tenantInfo.getTsignName());
+		params.put("companyName", tenantInfo.getTsignName());
 		params.put("sealPicture", tenantConfig.getCorporateChops());
         
 		if (studentInfo.getTenantId() == 1) {
 			if (OwnershipType.OWN.name().equals(params.get("ownershipType"))) {
-				//params.put("compayName", "深圳大雅乐盟网络教育股份有限公司");
+				//params.put("companyName", "深圳大雅乐盟网络教育股份有限公司");
 				//params.put("sealPicture", "https://daya-online.oss-cn-beijing.aliyuncs.com/website/cachet.png");
 			} else {
-				params.put("compayName", "武汉长乐长风乐器销售有限公司");
+				params.put("companyName", "武汉长乐长风乐器销售有限公司");
 				params.put("sealPicture", "https://daya-online.oss-cn-beijing.aliyuncs.com/website/clcf.png");
 			}
 		}
+		
+		TenantContractTemplate tenantContractTemplate = tenantContractTemplateService.queryLatestContractTemplate(TenantContextHolder.getTenantId(), null, null);
+		if(tenantContractTemplate == null){
+			throw new BizException("最新协议模板查询失败");
+		}
+		String mainContent = tenantContractTemplate.getContractTemplateContent();
+		params.put("contractMainContent", mainContent);
 
-        templateEngine.render(params, "product" + ownershipType.getContractVersion() + ".ftl", srcFile);
+        templateEngine.render(params, "latest_contract_template.ftl", srcFile);
 
         String html = "";
         try {
@@ -1143,15 +1165,15 @@ public class ContractServiceImpl implements ContractService, InitializingBean {
 			throw new BizException("机构配置信息查询失败");
 		}
 		
-		params.put("compayName", tenantInfo.getTsignName());
+		params.put("companyName", tenantInfo.getTsignName());
 		params.put("sealPicture", tenantConfig.getCorporateChops());
         
 		if (studentInfo.getTenantId() == 1) {
 			if (OwnershipType.OWN.name().equals(params.get("ownershipType"))) {
-				//params.put("compayName", "深圳大雅乐盟网络教育股份有限公司");
+				//params.put("companyName", "深圳大雅乐盟网络教育股份有限公司");
 				//params.put("sealPicture", "https://daya-online.oss-cn-beijing.aliyuncs.com/website/cachet.png");
 			} else {
-				params.put("compayName", "武汉长乐长风乐器销售有限公司");
+				params.put("companyName", "武汉长乐长风乐器销售有限公司");
 				params.put("sealPicture", "https://daya-online.oss-cn-beijing.aliyuncs.com/website/clcf.png");
 			}
 		}

+ 6 - 8
mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleTeacherSalaryServiceImpl.java

@@ -680,16 +680,14 @@ public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long
         Date date = DateUtil.addMonths(now, -1);
         String startDate = DateUtil.format(DateUtil.getFirstDayOfMonth(date),DateUtil.DEFAULT_PATTERN);
         String endDate = DateUtil.format(DateUtil.getLastDayOfMonth(date),DateUtil.DEFAULT_PATTERN);
-        //课程教师课酬
-        List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaries = courseScheduleTeacherSalaryDao.findTeacherCourseSalaryNoSettlement(startDate,endDate,"MUSIC",tenantId);
-
-        if (CollectionUtils.isEmpty(courseScheduleTeacherSalaries)) {
-            return;
-        }
-        List<Long> courseScheduleIds = courseScheduleTeacherSalaries.stream().map(CourseScheduleTeacherSalary::getCourseScheduleId).collect(Collectors.toList());
-
         //获取上个月的课程计划
         List<CourseSchedule> yesterdayCourseSchedules = courseScheduleDao.findCourseScheduleWithDate(startDate,endDate, tenantId);
+        List<Long> courseScheduleIds = yesterdayCourseSchedules.stream().map(CourseSchedule::getId).collect(Collectors.toList());
+        if (CollectionUtils.isEmpty(courseScheduleIds)) {
+            return;
+        }
+        //课程教师课酬
+        List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaries = courseScheduleTeacherSalaryDao.findByCourseSchedulesWithNoSettlement(courseScheduleIds);
 
         Set<Integer> schoolIds = yesterdayCourseSchedules.stream().map(CourseSchedule::getSchoolId).collect(Collectors.toSet());
         Map<Integer, School> idSchoolMap = new HashMap<>();

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

@@ -2045,7 +2045,7 @@ public class MusicGroupServiceImpl extends BaseServiceImpl<String, MusicGroup> i
         //如果发起退团申请的是乐团主管
         if (!currentOperatorRoleIds.contains(SysUserRoleEnum.ORGAN_MANAGER) && currentOperatorRoleIds.contains(SysUserRoleEnum.EDUCATION)) {
 
-            if (!StringUtils.equals(musicGroupQuit.getCurrentApproveRole(), SysUserRoleEnum.EDUCATION.ordinal() + "")) {
+            if (!StringUtils.equals(musicGroupQuit.getCurrentApproveRole(), SysUserRoleEnum.EDUCATION.ordinal() + 1 + "")) {
                 throw new BizException("只有分部经理才能审核");
             }
 
@@ -2055,7 +2055,7 @@ public class MusicGroupServiceImpl extends BaseServiceImpl<String, MusicGroup> i
         }
 
         if (currentOperatorRoleIds.contains(SysUserRoleEnum.ORGAN_MANAGER) && !currentOperatorRoleIds.contains(SysUserRoleEnum.EDUCATION)) {
-            if (!StringUtils.equals(musicGroupQuit.getCurrentApproveRole(), SysUserRoleEnum.ORGAN_MANAGER.ordinal() + "")) {
+            if (!StringUtils.equals(musicGroupQuit.getCurrentApproveRole(), SysUserRoleEnum.ORGAN_MANAGER.ordinal() + 1 + "")) {
                 throw new BizException("先需乐团主管审核");
             }
         }
@@ -3070,8 +3070,8 @@ public class MusicGroupServiceImpl extends BaseServiceImpl<String, MusicGroup> i
         Map<Integer, String> educationalTeacherNameMap = MapUtil.convertMybatisMap(teacherDao.queryNameByIds(StringUtils.join(educationalTeacherIds, ",")));
 
         // 获取运营主管编号列表
-        Set<Integer> teamTeacherIds = musicGroupList.stream().map(e -> e.getTeamTeacherId()).collect(Collectors.toSet());
-        Map<Integer, String> teamTeacherNameMap = MapUtil.convertMybatisMap(teacherDao.queryNameByIds(StringUtils.join(teamTeacherIds, ",")));
+        //Set<Integer> teamTeacherIds = musicGroupList.stream().map(e -> e.getTeamTeacherId()).collect(Collectors.toSet());
+        //Map<Integer, String> teamTeacherNameMap = MapUtil.convertMybatisMap(teacherDao.queryNameByIds(StringUtils.join(teamTeacherIds, ",")));
 
         // 获取乐队指导编号列表
         Set<Integer> directorUserIds = musicGroupList.stream().map(e -> e.getDirectorUserId()).collect(Collectors.toSet());
@@ -3096,6 +3096,9 @@ public class MusicGroupServiceImpl extends BaseServiceImpl<String, MusicGroup> i
 
         Map<String, Integer> payNumMap = JSONObject.parseObject(JSONObject.toJSONString(MapUtil.convertIntegerMap(studentRegistrationDao.countNormalNum(StringUtils.join(musicGroupIds, ",")))), HashMap.class);
 
+
+        Map<String, BigDecimal> chargeStandardMap = MapUtil.convertIntegerMap(musicGroupPaymentCalenderDao.queryChargeStandard(StringUtils.join(musicGroupIds, ",")));
+
         // 获取收费类型编号列表
         Set<Integer> chargeTypeIds = musicGroupList.stream().map(e -> e.getChargeTypeId()).collect(Collectors.toSet());
         if (chargeTypeIds == null) {
@@ -3120,7 +3123,7 @@ public class MusicGroupServiceImpl extends BaseServiceImpl<String, MusicGroup> i
             e.setOrganName(organNames.get(e.getOrganId()));
             e.setCooperationOrganName(cooperationOrganNames.get(e.getCooperationOrganId()));
             e.setEducationalTeacherName(educationalTeacherNameMap.get(e.getEducationalTeacherId()));
-            e.setTeamTeacherName(teamTeacherNameMap.get(e.getTeamTeacherId()));
+            //e.setTeamTeacherName(teamTeacherNameMap.get(e.getTeamTeacherId()));
             e.setRepairUserName(repairUserNameMap.get(e.getRepairUserId()));
             e.setDirectorUserName(directorUserNameMap.get(e.getDirectorUserId()));
             e.setPayNum(payNumMap.get(e.getId()) == null ? 0 : payNumMap.get(e.getId()));
@@ -3132,6 +3135,7 @@ public class MusicGroupServiceImpl extends BaseServiceImpl<String, MusicGroup> i
                     e.setIsRemedy(true);
                 }
             }
+            e.setChargeStandard(chargeStandardMap.get(e.getId()));
         }
         return musicGroupPageInfo;
     }

+ 121 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/TeacherContractsServiceImpl.java

@@ -0,0 +1,121 @@
+package com.ym.mec.biz.service.impl;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.JSONPath;
+import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.biz.dal.dao.TeacherContractsDao;
+import com.ym.mec.biz.dal.entity.TeacherContracts;
+import com.ym.mec.biz.service.TeacherContractsService;
+import com.ym.mec.common.dal.BaseDAO;
+import com.ym.mec.common.exception.BizException;
+import com.ym.mec.common.service.impl.BaseServiceImpl;
+import com.ym.mec.common.tenant.TenantContextHolder;
+import com.ym.mec.thirdparty.lingxinpay.ContractSignService;
+
+@Service
+public class TeacherContractsServiceImpl extends BaseServiceImpl<Long, TeacherContracts> implements TeacherContractsService {
+
+	private static final Logger logger = LoggerFactory.getLogger(TeacherContractsServiceImpl.class);
+
+	@Autowired
+	private TeacherContractsDao teacherContractsDao;
+
+	@Autowired
+	private ContractSignService contractSignService;
+
+	@Override
+	public BaseDAO<Long, TeacherContracts> getDAO() {
+		return teacherContractsDao;
+	}
+
+	@Override
+	public TeacherContracts queryByUserId(Integer userId) {
+		return teacherContractsDao.queryByUserId(userId);
+	}
+
+	@Override
+	@Transactional
+	public boolean sign(SysUser user) {
+
+		if (StringUtils.isBlank(user.getRealName()) || StringUtils.isBlank(user.getIdCardNo())) {
+			throw new BizException("请先实名认证");
+		}
+
+		TeacherContracts teacherContracts = new TeacherContracts();
+		teacherContracts.setUserId(user.getId());
+		teacherContracts.setCreateTime(new Date());
+		teacherContracts.setType(null);
+		teacherContracts.setTenantId(TenantContextHolder.getTenantId());
+		teacherContracts.setSerialNo(user.getId() + "_" + System.currentTimeMillis());
+
+		teacherContractsDao.insert(teacherContracts);
+
+		contractSignService.signContract(user.getRealName(), user.getIdCardNo(), user.getPhone(), teacherContracts.getSerialNo());
+
+		return true;
+	}
+
+	@Override
+	public boolean callback(String jsonStr) {
+		JSONObject jsonObject = JSONObject.parseObject(jsonStr);
+
+		String serialNo = (String) JSONPath.eval(jsonObject, "$.content.serialNo");
+
+		TeacherContracts teacherContracts = teacherContractsDao.queryBySerialNo(serialNo);
+		if (teacherContracts == null) {
+			return true;
+		}
+
+		if (StringUtils.equals("F", jsonObject.getString("return_code"))) {
+			teacherContractsDao.delete(teacherContracts.getId());
+			logger.error("老师签署协议回调异常:{}", jsonObject.getString("return_message"));
+			return true;
+		}
+
+		String contractResultNo = (String) JSONPath.eval(jsonObject, "$.content.contractResultNo");
+		String contractUrl = (String) JSONPath.eval(jsonObject, "$.content.contractUrl");
+
+		teacherContracts.setContractNo(contractResultNo);
+		teacherContracts.setUrl(contractUrl);
+		teacherContractsDao.update(teacherContracts);
+
+		return true;
+	}
+
+	@Override
+	public void queryTeacherContractSignStatus() {
+		
+		List<TeacherContracts> updateList = new ArrayList<TeacherContracts>();
+		
+		List<TeacherContracts> teacherContractsList = teacherContractsDao.queryNotUrlList();
+		
+		if(teacherContractsList != null && teacherContractsList.size() > 0){
+			for(TeacherContracts teacherContracts : teacherContractsList){
+				String url = contractSignService.querySignContractResult(teacherContracts.getSerialNo());
+				if(StringUtils.isNoneBlank(url)){
+					teacherContracts.setUrl(url);
+					updateList.add(teacherContracts);
+				}else{
+					teacherContractsDao.delete(teacherContracts.getId());
+				}
+			}
+			
+			if(updateList.size() > 0){
+				teacherContractsDao.batchUpdate(updateList);
+			}
+		}
+		
+	}
+
+}

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

@@ -16,13 +16,7 @@ import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Collectors;
 
-import com.ym.mec.biz.dal.dao.*;
-import com.ym.mec.biz.dal.dto.*;
-import com.ym.mec.biz.dal.page.*;
-
-import com.ym.mec.biz.service.TenantInfoService;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.poi.ss.formula.functions.T;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
@@ -30,9 +24,34 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 
 import com.alibaba.fastjson.JSONObject;
-import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.auth.api.enums.YesOrNoEnum;
+import com.ym.mec.biz.dal.dao.ClassGroupDao;
+import com.ym.mec.biz.dal.dao.CloudTeacherDao;
+import com.ym.mec.biz.dal.dao.DemoGroupDao;
+import com.ym.mec.biz.dal.dao.ImGroupDao;
+import com.ym.mec.biz.dal.dao.ImUserFriendDao;
+import com.ym.mec.biz.dal.dao.MusicGroupDao;
+import com.ym.mec.biz.dal.dao.OrganizationDao;
+import com.ym.mec.biz.dal.dao.SchoolDao;
+import com.ym.mec.biz.dal.dao.StudentDao;
+import com.ym.mec.biz.dal.dao.StudentExtracurricularExercisesSituationDao;
+import com.ym.mec.biz.dal.dao.StudentPaymentOrderDao;
+import com.ym.mec.biz.dal.dao.StudentRegistrationDao;
+import com.ym.mec.biz.dal.dao.SubjectDao;
+import com.ym.mec.biz.dal.dao.SysUserCashAccountDao;
+import com.ym.mec.biz.dal.dao.TeacherDao;
+import com.ym.mec.biz.dal.dto.BasicUserDto;
+import com.ym.mec.biz.dal.dto.ImUserFriendDto;
+import com.ym.mec.biz.dal.dto.MusicGroupStudentApplyDto;
+import com.ym.mec.biz.dal.dto.MusicGroupTeacherAttendanceDto;
+import com.ym.mec.biz.dal.dto.MusicGroupTeachersDto;
+import com.ym.mec.biz.dal.dto.TeacherBasicDto;
+import com.ym.mec.biz.dal.dto.TeacherCloseDto;
+import com.ym.mec.biz.dal.dto.TeacherDefaultSalaryDto;
+import com.ym.mec.biz.dal.dto.TeacherExercisesServiceDto;
+import com.ym.mec.biz.dal.dto.TeacherMusicStudentOverViewDto;
+import com.ym.mec.biz.dal.dto.TeacherStudentDataDto;
 import com.ym.mec.biz.dal.entity.CourseHomework;
 import com.ym.mec.biz.dal.entity.ImUserFriend;
 import com.ym.mec.biz.dal.entity.MusicGroup;
@@ -43,8 +62,16 @@ import com.ym.mec.biz.dal.entity.StudentPaymentOrder;
 import com.ym.mec.biz.dal.entity.SysUserCashAccount;
 import com.ym.mec.biz.dal.entity.Teacher;
 import com.ym.mec.biz.dal.enums.GroupType;
+import com.ym.mec.biz.dal.page.MusicGroupTeacherAttendanceQueryInfo;
+import com.ym.mec.biz.dal.page.MusicGroupTeachersQueryInfo;
+import com.ym.mec.biz.dal.page.TeacherCloseQueryInfo;
+import com.ym.mec.biz.dal.page.TeacherNameQueryInfo;
+import com.ym.mec.biz.dal.page.TeacherQueryInfo;
+import com.ym.mec.biz.dal.page.TeacherServeQueryInfo;
+import com.ym.mec.biz.dal.page.queryMusicGroupStudentQueryInfo;
 import com.ym.mec.biz.service.ClassGroupService;
 import com.ym.mec.biz.service.TeacherService;
+import com.ym.mec.biz.service.TenantInfoService;
 import com.ym.mec.common.constant.CommonConstants;
 import com.ym.mec.common.dal.BaseDAO;
 import com.ym.mec.common.entity.ImGroupModel;
@@ -56,6 +83,8 @@ import com.ym.mec.common.page.QueryInfo;
 import com.ym.mec.common.service.impl.BaseServiceImpl;
 import com.ym.mec.common.tenant.TenantContextHolder;
 import com.ym.mec.im.ImFeignService;
+import com.ym.mec.thirdparty.user.realname.RealnameAuthenticationPluginContext;
+import com.ym.mec.thirdparty.user.realname.provider.LinkfaceRealnameAuthenticationPlugin;
 import com.ym.mec.util.collection.MapUtil;
 import com.ym.mec.util.date.DateUtil;
 import com.ym.mec.util.idcard.IdcardValidator;
@@ -102,6 +131,9 @@ public class TeacherServiceImpl extends BaseServiceImpl<Integer, Teacher>  imple
 	@Autowired
 	private TenantInfoService tenantInfoService;
 
+    @Autowired
+    private RealnameAuthenticationPluginContext realnameAuthenticationPluginContext;
+
 	@Override
 	public BaseDAO<Integer, Teacher> getDAO() {
 		return teacherDao;
@@ -694,6 +726,8 @@ public class TeacherServiceImpl extends BaseServiceImpl<Integer, Teacher>  imple
 			throw new BizException("身份证校验失败");
 		}
 
+        realnameAuthenticationPluginContext.getRealnameAuthenticationPlugin(LinkfaceRealnameAuthenticationPlugin.getName()).verify(realName, idcardNo);
+
 		Date date = new Date();
 
 		teacher.setIdcardBackImg(idcardBackImg);
@@ -701,6 +735,12 @@ public class TeacherServiceImpl extends BaseServiceImpl<Integer, Teacher>  imple
 		teacher.setIdcardHandImg(idcardHandImg);
 		teacher.setUpdateTime(date);
 		teacherDao.update(teacher);
+		
+		user.setRealName(realName);
+		user.setIdCardNo(idcardNo);
+		user.setUpdateTime(date);
+		teacherDao.updateUser(user);
+		
 		return true;
 	}
 

+ 138 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/TenantContractTemplateServiceImpl.java

@@ -0,0 +1,138 @@
+package com.ym.mec.biz.service.impl;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.ym.mec.biz.dal.dao.TenantContractTemplateDao;
+import com.ym.mec.biz.dal.dao.TenantInfoDao;
+import com.ym.mec.biz.dal.dto.TenantContractTemplateDto;
+import com.ym.mec.biz.dal.entity.TenantContractTemplate;
+import com.ym.mec.biz.service.TenantContractTemplateService;
+import com.ym.mec.common.dal.BaseDAO;
+import com.ym.mec.common.exception.BizException;
+import com.ym.mec.common.page.PageInfo;
+import com.ym.mec.common.page.QueryInfo;
+import com.ym.mec.common.service.impl.BaseServiceImpl;
+import com.ym.mec.util.collection.MapUtil;
+
+@Service
+public class TenantContractTemplateServiceImpl extends BaseServiceImpl<Integer, TenantContractTemplate>  implements TenantContractTemplateService {
+	
+	@Autowired
+	private TenantContractTemplateDao tenantContractTemplateDao;
+	
+	@Autowired
+	private TenantInfoDao tenantInfoDao;
+
+	@Override
+	public BaseDAO<Integer, TenantContractTemplate> getDAO() {
+		return tenantContractTemplateDao;
+	}
+
+	@Override
+	public PageInfo<TenantContractTemplateDto> queryPageList(QueryInfo queryInfo) {
+		PageInfo<TenantContractTemplateDto> pageInfo = new PageInfo<TenantContractTemplateDto>(queryInfo.getPage(), queryInfo.getRows());
+		Map<String, Object> params = new HashMap<String, Object>();
+		MapUtil.populateMap(params, queryInfo);
+		
+		List<TenantContractTemplateDto> dataList = null;
+		int count = this.findCount(params);
+		if (count > 0) {
+			pageInfo.setTotal(count);
+			params.put("offset", pageInfo.getOffset());
+			dataList = tenantContractTemplateDao.queryPageList(params);
+		}
+		if (count == 0) {
+			dataList = new ArrayList<TenantContractTemplateDto>();
+		}
+		pageInfo.setRows(dataList);
+		return pageInfo;
+	}
+
+	@Override
+	@Transactional
+	public boolean enableContract(Integer id, Integer userId) {
+		TenantContractTemplate tenantContractTemplate = tenantContractTemplateDao.get(id);
+		
+		if(tenantContractTemplate == null){
+			throw new BizException("未查询到协议模板");
+		}
+		
+		if(tenantContractTemplate.getStatus()){
+			return true;
+		}
+		
+		tenantContractTemplateDao.disableContract(tenantContractTemplate.getOwner(), tenantContractTemplate.getType(), tenantContractTemplate.getTenantId());
+		
+		Date date = new Date();
+		
+		tenantContractTemplate.setStatus(true);
+		tenantContractTemplate.setUpdateTime(date);
+		tenantContractTemplate.setModifyBy(userId);
+		
+		tenantContractTemplateDao.update(tenantContractTemplate);
+		
+		return true;
+	}
+
+	@Override
+	public boolean updateContractVersion() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public TenantContractTemplate queryLatestContractTemplate(Integer tenantId, String owner, String type) {
+		TenantContractTemplate tenantContractTemplate = tenantContractTemplateDao.queryLatestContractTemplate(owner, type, tenantId);
+		
+		if(tenantContractTemplate == null){
+			throw new BizException("未查询到协议模板");
+		}
+		return tenantContractTemplate;
+	}
+
+	@Override
+	@Transactional
+	public boolean createContractTemplate(TenantContractTemplate tenantContractTemplate) {
+		
+		Integer tenantId = tenantContractTemplate.getTenantId();
+		tenantInfoDao.getLocked(tenantId);
+		
+		Integer maxVersion = tenantContractTemplateDao.queryMaxVersion();
+		int version = maxVersion == null ? 1 : maxVersion + 1;
+		
+		tenantContractTemplate.setVersion(version);
+		Date date = new Date();
+		tenantContractTemplate.setCreateTime(date);
+		tenantContractTemplate.setUpdateTime(date);
+		insert(tenantContractTemplate);
+		
+		return true;
+	}
+
+	@Override
+	@Transactional
+	public boolean updateContractTempalte(TenantContractTemplate tenantContractTemplate) {
+		
+		Integer tenantId = tenantContractTemplate.getTenantId();
+		tenantInfoDao.getLocked(tenantId);
+		
+		Integer maxVersion = tenantContractTemplateDao.queryMaxVersion();
+		int version = maxVersion == null ? 1 : maxVersion + 1;
+		
+		tenantContractTemplate.setVersion(version);
+		Date date = new Date();
+		tenantContractTemplate.setUpdateTime(date);
+		
+		update(tenantContractTemplate);
+		return true;
+	}
+	
+}

+ 140 - 0
mec-biz/src/main/resources/config/contracts/latest_contract_template.ftl

@@ -0,0 +1,140 @@
+<!DOCTYPE html>
+<html lang="en">
+<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>产品与服务协议</title>
+    <style>
+        body { margin: 0; }
+        header {
+            height: 40px;
+            line-height: .40px;
+            color: #000;
+            font-size: 17px;
+            background: #fff;
+            box-shadow: 0px 1px 8px 0px rgba(0, 0, 0, 0.07);
+            text-align: center;
+        }
+        header .back {
+            width: 20px;
+            height: 20px;
+            position: absolute;
+            left: 12px;
+            top: 10px;
+        }
+        .container {
+            padding: 22px 20px 3px;
+            font-size: 14px;
+        }
+        h1 {
+            font-size: 18px;
+            text-align: center;
+            margin-bottom: 8px;
+        }
+        h2 {
+            font-size: 16px;
+            font-weight: bold;
+            padding-top: 15px;
+        }
+        h3 {
+            font-size: 14px;
+            font-weight: bold;
+        }
+        .signature {
+            padding-top: 50px;
+        }
+        .signature .sign {
+            position: relative;
+            width: 49%;
+            display: inline-block;
+        }
+        .signature span {
+            display: block;
+        }
+        .signature .cachet {
+            position: absolute;
+            top: -60px;
+            left: 0;
+            width: 150px;
+            height: 150px;
+        }
+        .iInfo {
+            display: flex;
+        }
+        .iInfo span {
+            flex: 1;
+        }
+        .iInfoContent, .iInfoContent span {
+            display: block;
+        }
+
+        .underline {
+            text-decoration: underline;
+        }
+        .bold {
+            font-weight: bold;
+        }
+    </style>
+</head>
+<body style="font-family:'SimSun'">
+    <div class="container">
+        <h1>《产品与服务协议》</h1>
+                            甲方:${companyName} <br/>
+
+        <div style="display: flex;">乙方:
+            <div style="flex: 1 auto;">
+                <div class="iInfo">
+                    <span>家长姓名:${studentInfo.realName!}</span>
+                    <span>电话:${studentInfo.phone!}</span>
+                </div>
+                <#if studentInfo.certificateType == 'IDENTITY'>
+                    <div class="iInfo">
+                        <span>身份证号:${studentInfo.idCardNo!}</span>
+                    </div>
+                </#if>
+                <div class="iInfo">
+                    <span>学生姓名:${studentInfo.username!}</span>
+                </div>
+                <#if studentInfo.grade?default("")?trim?length gt 1>
+                <div class="iInfo">
+                    <span>所在班级:${studentInfo.grade!} ${studentInfo.clazz!}</span>
+                </div>
+                </#if>
+                <#if studentInfo.subject.name?default("")?trim?length gt 1>
+                <div class="iInfo">
+                    <span>所在声部:${studentInfo.subject.name!}</span>
+                </div>
+                </#if>
+            </div>
+        </div>
+        <div>(本协议中“乙方“指学员及家长;”乙方学员“指购买甲方产品或服务的学员;”乙方家长“仅指乙方学员的法定监护人。)</div>
+
+        <p class="underline bold">重要须知:在注册或购买使用甲方提供的产品、服务之前,请您务必审慎阅读、充分理解本使用协议各条款内容, 特别是免除或者限制甲方责任的条款、对您权利进行限制的条款、约定争议解决方式和司法管辖的条款等。 限制、免责条款或者其他涉及您重大权益的条款可能以加粗、加下划线等形式提示您重点注意。您注册或购买使用甲方提供的产品和服务,均视为您同意本使用协议,以及同意接受本使用协议的约束。</p>
+        <p class="underline bold">如无特别说明 ,下列术语在本协议中的定义为:管乐迷平台(下称“本平台”),即管乐迷APP;(下称“本平台”)指由甲方提供的器乐教学全流程辅助系统,包括媒体资料,教师点评,课前、课中、课后管理等服务;乐器练习云教练 (下称“本系统”),指由甲方提供和维护的器乐辅助练习系统;具体以该系统实际提供为准。该系统将根据实际需要进行调整和增减,乙方使用平台时需遵守本服务协议。</p>
+
+		${contractMainContent!}
+        
+        <div class="signature">
+        	<#if isShowVisualSeal>
+            <div class="sign">甲方签章:${companyName}<img class="cachet" src="${sealPicture!}" alt="" />
+                <span>日期:${.now?string("yyyy年MM月dd日")}</span>
+            </div>
+            <div class="sign">乙方签章:${studentInfo.realName!}
+                <span>日期:${.now?string("yyyy年MM月dd日")} </span>
+            </div>
+        	<#else>
+            <div class="sign">甲方签章:${companyName}
+                <span>日期:${.now?string("yyyy年MM月dd日")}</span>
+            </div>
+            <div class="sign">乙方签章:
+                <span>日期:${.now?string("yyyy年MM月dd日")} </span>
+            </div>
+        	</#if>
+        </div>
+    </div>
+</body>
+</html>

+ 3 - 3
mec-biz/src/main/resources/config/contracts/product4.ftl

@@ -83,7 +83,7 @@
 <body style="font-family:'SimSun'">
     <div class="container">
         <h1>《产品与服务协议》</h1>
-                            甲方:${compayName} <br/>
+                            甲方:${companyName} <br/>
         <!-- <#if ownershipType == 'OWN'>
 		甲方:深圳大雅乐盟网络教育股份有限公司
 		<#else>
@@ -179,14 +179,14 @@
 
         <div class="signature">
         	<#if isShowVisualSeal>
-            <div class="sign">甲方签章:${compayName}<img class="cachet" src="${sealPicture!}" alt="" />
+            <div class="sign">甲方签章:${companyName}<img class="cachet" src="${sealPicture!}" alt="" />
                 <span>日期:${.now?string("yyyy年MM月dd日")}</span>
             </div>
             <div class="sign">乙方签章:${studentInfo.realName!}
                 <span>日期:${.now?string("yyyy年MM月dd日")} </span>
             </div>
         	<#else>
-            <div class="sign">甲方签章:${compayName}
+            <div class="sign">甲方签章:${companyName}
                 <span>日期:${.now?string("yyyy年MM月dd日")}</span>
             </div>
             <div class="sign">乙方签章:

+ 8 - 0
mec-biz/src/main/resources/config/mybatis/MusicGroupPaymentCalenderMapper.xml

@@ -688,4 +688,12 @@
         ORDER BY mgpc.id_ DESC
         <include refid="global.limit"/>
     </select>
+    
+    <select id="queryChargeStandard" resultType="java.util.Map">
+        SELECT `music_group_id_` 'key',`current_total_amount_` 'value'  FROM `music_group_payment_calender` WHERE `id_` in
+		(
+		SELECT max(pc.`id_`)   FROM `music_group_payment_calender` pc WHERE pc.`payment_type_` in ('MUSIC_APPLY','MUSIC_RENEW') and FIND_IN_SET(pc.music_group_id_, #{musicGroupIdList})
+		GROUP BY pc.`music_group_id_` 
+		    )
+    </select>
 </mapper>

+ 126 - 0
mec-biz/src/main/resources/config/mybatis/TeacherContractsMapper.xml

@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<!-- 这个文件是自动生成的。 不要修改此文件。所有改动将在下次重新自动生成时丢失。 -->
+<mapper namespace="com.ym.mec.biz.dal.dao.TeacherContractsDao">
+
+	<resultMap type="com.ym.mec.biz.dal.entity.TeacherContracts"
+		id="TeacherContracts">
+		<result column="id_" property="id" />
+		<result column="user_id_" property="userId" />
+		<result column="contract_no_" property="contractNo" />
+		<result column="type_" property="type" />
+		<result column="url_" property="url" />
+		<result column="serial_no_" property="serialNo" />
+		<result column="create_time_" property="createTime" />
+		<result column="tenant_id_" property="tenantId" />
+	</resultMap>
+
+	<!-- 根据主键查询一条记录 -->
+	<select id="get" resultMap="TeacherContracts">
+		SELECT * FROM
+		teacher_contracts WHERE id_ = #{id}
+	</select>
+
+	<!-- 全查询 -->
+	<select id="findAll" resultMap="TeacherContracts">
+		SELECT * FROM teacher_contracts
+		ORDER BY id_
+	</select>
+
+	<!-- 向数据库增加一条记录 -->
+	<insert id="insert" parameterType="com.ym.mec.biz.dal.entity.TeacherContracts"
+		useGeneratedKeys="true" keyColumn="id" keyProperty="id">
+		<!-- <selectKey resultClass="int" keyProperty="id" > SELECT SEQ_WSDEFINITION_ID.nextval 
+			AS ID FROM DUAL </selectKey> -->
+		INSERT INTO teacher_contracts
+		(id_,user_id_,contract_no_,type_,url_,serial_no_,create_time_,tenant_id_)
+		VALUES(#{id},#{userId},#{contractNo},#{type},#{url},#{serialNo},#{createTime},#{tenantId})
+	</insert>
+
+	<!-- 根据主键查询一条记录 -->
+	<update id="update" parameterType="com.ym.mec.biz.dal.entity.TeacherContracts">
+		UPDATE teacher_contracts
+		<set>
+			<if test="userId != null">
+				user_id_ = #{userId},
+			</if>
+			<if test="serialNo != null">
+				serial_no_ = #{serialNo},
+			</if>
+			<if test="url != null">
+				url_ = #{url},
+			</if>
+			<if test="tenantId != null">
+				tenant_id_ = #{tenantId},
+			</if>
+			<if test="contractNo != null">
+				contract_no_ = #{contractNo},
+			</if>
+			<if test="type != null">
+				type_ = #{type},
+			</if>
+			<if test="createTime != null">
+				create_time_ = #{createTime},
+			</if>
+		</set>
+		WHERE id_ = #{id}
+	</update>
+	
+	<update id="batchUpdate" parameterType="java.util.List">
+        <foreach collection="list" item="item" index="index" open="" close="" separator=";">
+			UPDATE teacher_contracts
+			<set>
+				<if test="item.userId != null">
+					user_id_ = #{item.userId},
+				</if>
+				<if test="item.serialNo != null">
+					serial_no_ = #{item.serialNo},
+				</if>
+				<if test="item.url != null">
+					url_ = #{item.url},
+				</if>
+				<if test="item.contractNo != null">
+					contract_no_ = #{item.contractNo},
+				</if>
+				<if test="item.type != null">
+					type_ = #{item.type},
+				</if>
+				<if test="item.createTime != null">
+					create_time_ = #{item.createTime},
+				</if>
+			</set>
+			WHERE id_ = #{item.id} and tenant_id_ = #{item.tenantId}
+        </foreach>
+	</update>
+
+	<!-- 根据主键删除一条记录 -->
+	<delete id="delete">
+		DELETE FROM teacher_contracts WHERE id_ =
+		#{id}
+	</delete>
+
+	<!-- 分页查询 -->
+	<select id="queryPage" resultMap="TeacherContracts"
+		parameterType="map">
+		SELECT * FROM teacher_contracts ORDER BY id_
+		<include refid="global.limit" />
+	</select>
+
+	<!-- 查询当前表的总记录数 -->
+	<select id="queryCount" resultType="int">
+		SELECT COUNT(*) FROM
+		teacher_contracts
+	</select>
+
+	<select id="queryByUserId" resultMap="TeacherContracts">
+		SELECT * FROM teacher_contracts where user_id_ = #{userId}
+	</select>
+
+	<select id="queryBySerialNo" resultMap="TeacherContracts">
+		SELECT * FROM teacher_contracts where serial_no_ = #{serialNo}
+	</select>
+
+	<select id="queryNotUrlList" resultMap="TeacherContracts">
+		SELECT * FROM teacher_contracts where url_ is null or url_ = ''
+	</select>
+</mapper>

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

@@ -340,6 +340,9 @@
             <if test="realName != null">
                 real_name_ = #{realName},
             </if>
+            <if test="idCardNo != null and idCardNo != ''">
+                id_card_no_ = #{idCardNo},
+            </if>
             <if test="userType != null">
                 user_type_ = #{userType},
             </if>

+ 155 - 0
mec-biz/src/main/resources/config/mybatis/TenantContractTemplateMapper.xml

@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<!-- 这个文件是自动生成的。 不要修改此文件。所有改动将在下次重新自动生成时丢失。 -->
+<mapper namespace="com.ym.mec.biz.dal.dao.TenantContractTemplateDao">
+
+	<resultMap type="com.ym.mec.biz.dal.entity.TenantContractTemplate"
+		id="TenantContractTemplate">
+		<result column="id_" property="id" />
+		<result column="name_" property="name" />
+		<result column="type_" property="type" />
+		<result column="contract_template_content_" property="contractTemplateContent" />
+		<result column="origanal_file_url_" property="origanalFileUrl" />
+		<result column="contract_no_" property="contractNo" />
+		<result column="status_" property="status" />
+		<result column="version_" property="version" />
+		<result column="modify_by_" property="modifyBy" />
+		<result column="update_time_" property="updateTime" />
+		<result column="create_time_" property="createTime" />
+		<result column="owner_" property="owner" />
+		<result column="tenant_id_" property="tenantId" />
+	</resultMap>
+	
+	<resultMap type="com.ym.mec.biz.dal.dto.TenantContractTemplateDto"
+		id="TenantContractTemplateDto">
+		<result column="latest_operator_" property="latestOperator" />
+	</resultMap>
+
+	<!-- 根据主键查询一条记录 -->
+	<select id="get" resultMap="TenantContractTemplate">
+		SELECT * FROM tenant_contract_template WHERE id_ = #{id}
+	</select>
+
+	<!-- 全查询 -->
+	<select id="findAll" resultMap="TenantContractTemplate">
+		SELECT * FROM tenant_contract_template ORDER BY id_
+	</select>
+
+	<!-- 向数据库增加一条记录 -->
+	<insert id="insert" parameterType="com.ym.mec.biz.dal.entity.TenantContractTemplate"
+		useGeneratedKeys="true" keyColumn="id" keyProperty="id">
+		<!-- <selectKey resultClass="int" keyProperty="id" > SELECT SEQ_WSDEFINITION_ID.nextval 
+			AS ID FROM DUAL </selectKey> -->
+		INSERT INTO tenant_contract_template
+		(id_,name_,type_,contract_template_content_,origanal_file_url_,contract_no_,status_,version_,modify_by_,update_time_,create_time_,owner_,tenant_id_)
+		VALUES(#{id},#{name},#{type},#{contractTemplateContent},#{origanalFileUrl},#{contractNo},#{status},#{version},#{modifyBy},#{updateTime},#{createTime},#{owner},#{tenantId})
+	</insert>
+
+	<!-- 根据主键查询一条记录 -->
+	<update id="update" parameterType="com.ym.mec.biz.dal.entity.TenantContractTemplate">
+		UPDATE tenant_contract_template
+		<set>
+			<if test="contractTemplateContent != null">
+				contract_template_content_ = #{contractTemplateContent},
+			</if>
+			<if test="status != null">
+				status_ = #{status},
+			</if>
+			<if test="type != null">
+				type_ = #{type},
+			</if>
+			<if test="origanalFileUrl != null">
+				origanal_file_url_ = #{origanalFileUrl},
+			</if>
+			<if test="id != null">
+				id_ = #{id},
+			</if>
+			<if test="updateTime != null">
+				update_time_ = #{updateTime},
+			</if>
+			<if test="version != null">
+				version_ = #{version},
+			</if>
+			<if test="modifyBy != null">
+				modify_by_ = #{modifyBy},
+			</if>
+			<if test="contractNo != null">
+				contract_no_ = #{contractNo},
+			</if>
+			<if test="name != null">
+				name_ = #{name},
+			</if>
+			<if test="createTime != null">
+				create_time_ = #{createTime},
+			</if>
+			<if test="owner != null">
+				owner_ = #{owner},
+			</if>
+		</set>
+		WHERE id_ = #{id} and tenant_id_ = #{tenantId}
+	</update>
+
+	<!-- 根据主键删除一条记录 -->
+	<delete id="delete">
+		DELETE FROM tenant_contract_template WHERE id_ = #{id}
+	</delete>
+
+	<!-- 分页查询 -->
+	<select id="queryPageList" resultMap="TenantContractTemplateDto"
+		parameterType="map">
+		SELECT tct.*,u.real_name_ latest_operator_ FROM tenant_contract_template tct left join sys_user u on tct.modify_by_ = u.id_ 
+		<where>
+			<if test="status != null">
+				and tct.status_ = #{status}
+			</if>
+			<if test="type != null">
+				and tct.type_ = #{type}
+			</if>
+			<if test="owner != null">
+				and tct.owner_ = #{owner}
+			</if>
+		</where>
+		ORDER BY id_
+		<include refid="global.limit" />
+	</select>
+
+	<!-- 查询当前表的总记录数 -->
+	<select id="queryCount" resultType="int">
+		SELECT COUNT(tct.id_) FROM tenant_contract_template tct
+		<where>
+			<if test="status != null">
+				and tct.status_ = #{status}
+			</if>
+			<if test="type != null">
+				and tct.type_ = #{type}
+			</if>
+			<if test="owner != null">
+				and tct.owner_ = #{owner}
+			</if>
+		</where>
+	</select>
+	
+	<select id="queryLatestContractTemplate" resultMap="TenantContractTemplate" parameterType="map">
+		SELECT * FROM tenant_contract_template where status_ = 1 and tenant_id_ = #{tenantId}
+		<if test="type != null">
+			and type_ = #{type}
+		</if>
+		<if test="owner != null">
+			and owner_ = #{owner}
+		</if>
+	</select>
+	
+	<update id="disableContract" parameterType="map">
+		update tenant_contract_template set status_ = 0 where status_ = 1 and tenant_id_ = #{tenantId}
+		<if test="type != null">
+			and type_ = #{type}
+		</if>
+		<if test="owner != null">
+			and owner_ = #{owner}
+		</if>
+	</update>
+	
+	<select id="queryMaxVersion" resultType="java.lang.Integer">
+		SELECT max(version_) FROM tenant_contract_template 
+	</select>
+</mapper>

+ 4 - 0
mec-biz/src/main/resources/config/mybatis/TenantInfoMapper.xml

@@ -54,6 +54,10 @@
         <result column="student_up_limit_" jdbcType="INTEGER" property="studentUpLimit"/>
         <result column="expiry_date_" jdbcType="TIMESTAMP" property="expireDate"/>
     </resultMap>
+    
+    <select id="getLocked" resultMap="TenantInfoInfoResult">
+    	select * from tenant_info WHERE id_ = #{tenantId} for update
+    </select>
 
     <select id="queryPage" parameterType="map" resultMap="TenantInfoInfoResult">
         SELECT a.`id_`,

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

@@ -239,4 +239,8 @@ public interface TaskRemoteService {
 	/** 兑换码分配数量底告警 */
 	@GetMapping("task/redemptionCodeWarn")
 	void redemptionCodeWarn();
+
+	/** 查询老师协议签订状态 */
+	@GetMapping("task/queryTeacherContractSignStatus")
+	public void queryTeacherContractSignStatus();
 }

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

@@ -289,4 +289,9 @@ public class TaskRemoteServiceFallback implements TaskRemoteService {
     public void redemptionCodeWarn() {
         logger.error("兑换码分配数量底告警");
     }
+
+	@Override
+	public void queryTeacherContractSignStatus() {
+		logger.error("查询老师协议签订状态失败");
+	}
 }

+ 3 - 8
mec-common/common-core/src/main/java/com/ym/mec/common/service/BaseService.java

@@ -8,17 +8,12 @@ package com.ym.mec.common.service;
  * @create 2015年7月13日
  */
 import java.io.Serializable;
-import java.math.BigDecimal;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.util.*;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
 
 import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.page.QueryInfo;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.ibatis.session.SqlSession;
-import org.springframework.util.CollectionUtils;
 
 public interface BaseService<PK extends Serializable, T> {
 	/**

+ 19 - 0
mec-task/src/main/java/com/ym/mec/task/jobs/TeacherContractTask.java

@@ -0,0 +1,19 @@
+package com.ym.mec.task.jobs;
+
+import com.ym.mec.task.TaskRemoteService;
+import com.ym.mec.task.core.BaseTask;
+import com.ym.mec.task.core.TaskException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class TeacherContractTask extends BaseTask {
+
+	@Autowired
+	private TaskRemoteService taskRemoteService;
+
+	@Override
+	public void execute() throws TaskException {
+		taskRemoteService.queryTeacherContractSignStatus();
+	}
+}

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

@@ -32,7 +32,7 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
 				.and()
 				.authorizeRequests()
 				.antMatchers("/v2/api-docs", "/code/*", "/teacher/queryStudentApply", "/teacher/querySubByMusicGroupId", "/studentRegistration/updateSubject",
-						"/studyReport/createEvaluate", "/teacherOrder/*","/teacher/getRegisterOrPreList").permitAll().anyRequest().authenticated().and().httpBasic();
+						"/studyReport/createEvaluate", "/teacherOrder/*","/teacher/getRegisterOrPreList","/teacherContract/callback").permitAll().anyRequest().authenticated().and().httpBasic();
 	}
 
 	@Override

+ 80 - 0
mec-teacher/src/main/java/com/ym/mec/teacher/controller/TeacherContractController.java

@@ -0,0 +1,80 @@
+package com.ym.mec.teacher.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.io.IOUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+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.biz.dal.entity.TeacherContracts;
+import com.ym.mec.biz.service.TeacherContractsService;
+import com.ym.mec.common.controller.BaseController;
+import com.ym.mec.common.entity.HttpResponseResult;
+
+@RequestMapping("teacherContract")
+@Api(tags = "教师协议服务")
+@RestController
+public class TeacherContractController extends BaseController {
+
+	@Autowired
+	private TeacherContractsService teacherContractsService;
+
+	@Autowired
+	private SysUserFeignService sysUserFeignService;
+
+	@ApiOperation(value = "是否需要签订协议")
+	@GetMapping("/isRequireSign")
+	public HttpResponseResult<Boolean> isRequireSign() {
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		if (sysUser == null || sysUser.getId() == null) {
+			return failed(HttpStatus.FORBIDDEN, "请重新登录");
+		}
+
+		if (sysUser.getTenantId() == 1) {
+			TeacherContracts teacherContracts = teacherContractsService.queryByUserId(sysUser.getId());
+			if (teacherContracts == null) {
+				return succeed(true);
+			}
+		}
+		return succeed(false);
+	}
+
+	@ApiOperation(value = "签订协议")
+	@PostMapping("/sign")
+	public HttpResponseResult<Boolean> sign() {
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		if (sysUser == null || sysUser.getId() == null) {
+			return failed(HttpStatus.FORBIDDEN, "请重新登录");
+		}
+
+		return succeed(teacherContractsService.sign(sysUser));
+	}
+
+	@ApiOperation(value = "异步通知")
+	@PostMapping("/callback")
+	public void callback(HttpServletRequest request, HttpServletResponse response) throws IOException {
+		String jsonStr = IOUtils.toString(request.getInputStream(), "UTF-8");
+		teacherContractsService.callback(jsonStr);
+		returnMsg("success", response);
+	}
+	
+	private void returnMsg(String msg, HttpServletResponse response) throws IOException {
+		response.addHeader("Content-Type", "text/html;charset=UTF-8");
+		PrintWriter print = response.getWriter();
+		print.print(msg);
+		print.flush();
+	}
+}

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

@@ -182,7 +182,7 @@ public class TeacherController extends BaseController {
 			@ApiImplicitParam(name = "idcardHandImg", value = "手持身份证照", required = true, dataType = "String") })
 	public Object realNameAuthentication(String realName, String idcardNo, String idcardFrontImg, String idcardBackImg, String idcardHandImg) {
 		SysUser user = sysUserFeignService.queryUserInfo();
-		if (user == null) {
+		if (user == null || user.getId() == null) {
 			return failed(HttpStatus.FORBIDDEN, "请登录");
 		}
 		teacherService.realNameAuthentication(user.getId(), realName, idcardNo, idcardFrontImg, idcardBackImg, idcardHandImg);

+ 128 - 0
mec-thirdparty/src/main/java/com/ym/mec/thirdparty/lingxinpay/ContractSignService.java

@@ -0,0 +1,128 @@
+package com.ym.mec.thirdparty.lingxinpay;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.JSONPath;
+import com.ym.mec.thirdparty.exception.ThirdpartyException;
+import com.ym.mec.util.http.HttpUtil;
+
+@Service
+public class ContractSignService {
+
+	private static final Logger logger = LoggerFactory.getLogger(ContractSignService.class);
+
+	@Value("${teacher.contract.publicKey:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYT5eCY6r8sGWgbiId/VqSZmS6XkBNGMkzUqTIkpkecOzsFBxFXTQmgDeR991YfgqmyOaHsJ/ons/H+e8l+RmHsOm4eErFU+9qXFq+k195YFV1vAR9O7MIG+FR5vmLDuhgimPsgqscWhUrGinc8RUpi5KwClgx7d+d8ZJ4GmkR0QIDAQAB}")
+	private String publicKey;
+
+	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+
+	@Value("${teacher.contract.contractNo:1164462240733069312}")
+	private String contractNo;// 模板协议号
+
+	@Value("${teacher.contract.memberNo:1491663782974988288}")
+	private String outMemberNo;// 商户号
+	
+	@Value("${teacher.contract.notifyUrl:http://www.baidu.com}")
+	private String notifyUrl;
+	
+	@Value("${teacher.contract.apiUrl:http://39.107.15.64:8095}")
+	private String apiUrl;
+
+	public boolean signContract(String realName, String idcard, String mobileNo, String serialNo) {
+		JSONObject jsonObject = new JSONObject();
+		jsonObject.put("signType", "RSA");
+		jsonObject.put("service", "bpotop.zx.contract");
+		jsonObject.put("charset", "UTF-8");
+		jsonObject.put("version", "1.0");
+		jsonObject.put("createTime", sdf.format(new Date()));
+
+		jsonObject.put("outMemberNo", outMemberNo);// 公司商户号
+		jsonObject.put("serialNo", serialNo);// 流水号(商户唯一标识)
+		jsonObject.put("contractNo", contractNo);// 合同模板号
+		jsonObject.put("notifyUrl", notifyUrl);// 返回结果异步通知地址
+
+		JSONObject jsonObject2 = new JSONObject();
+		jsonObject2.put("name", realName);
+		jsonObject2.put("phone", mobileNo);
+		jsonObject2.put("identityId", idcard);
+		jsonObject2.put("citizenship", "0");
+		jsonObject2.put("signTime", sdf.format(new Date()));
+		jsonObject.put("contractSignInfo", jsonObject2);
+		String jsonStr = JSONObject.toJSONString(jsonObject);
+
+		try {
+			String encryptStr = RSA.encryptPub(jsonStr, publicKey);
+			jsonObject.put("sign", encryptStr);
+		} catch (Exception e) {
+			logger.error("加密失败", e);
+			throw new ThirdpartyException("加密失败:{}", e.getMessage());
+		}
+		logger.info("[合同签署]请求参数:{}", jsonObject.toJSONString());
+		try {
+			String s = HttpUtil.postForHttp(apiUrl + "/api/signContract", jsonObject.toJSONString(), null);
+			logger.info("请求[合同签署]响应参数:{}", s);
+
+			jsonObject = JSONObject.parseObject(s);
+			if (StringUtils.equals(jsonObject.getString("return_code"), "T")) {
+				return true;
+			}
+
+			throw new ThirdpartyException("合同签署失败:{}", jsonObject.getString("content"));
+
+		} catch (IOException e) {
+			logger.error("请求[合同签署]接口报错", e);
+			throw new ThirdpartyException("请求[合同签署]接口报错:{}", e.getMessage());
+		}
+	}
+
+	public String querySignContractResult(String serialNo) {
+		JSONObject jsonObject = new JSONObject();
+		jsonObject.put("outMemberNo", outMemberNo);
+		jsonObject.put("serialNo", serialNo);
+		jsonObject.put("contractNo", contractNo);
+		try {
+			String encryptStr = RSA.encryptPub(JSONObject.toJSONString(jsonObject), publicKey);
+			jsonObject.put("sign", encryptStr);
+		} catch (Exception e) {
+			logger.error("加密失败", e);
+			throw new ThirdpartyException("加密失败:{}", e.getMessage());
+		}
+		jsonObject.put("signType", "RSA");
+		jsonObject.put("service", "bpotop.zx.contract");
+		jsonObject.put("charset", "UTF-8");
+		jsonObject.put("version", "1.0");
+		jsonObject.put("createTime", sdf.format(new Date()));
+		try {
+			String s = HttpUtil.postForHttp(apiUrl + "/api/queryContractInfo", jsonObject.toJSONString(), null);
+
+			logger.info("[合同查询]响应参数:{}", s);
+
+			jsonObject = JSONObject.parseObject(s);
+			if (StringUtils.equals(jsonObject.getString("return_code"), "T")) {
+				return (String) JSONPath.eval(jsonObject, "$.content.contractUrl");
+			}
+
+			//throw new ThirdpartyException("查询合同签署结果失败:{}", JSONPath.eval(jsonObject, "$.content.message"));
+		} catch (IOException e) {
+			logger.error("请求[合同查询]接口报错", e);
+			//throw new ThirdpartyException("请求[合同查询]接口报错:{}", e.getMessage());
+		}
+		return null;
+	}
+
+	public static void main(String[] args) {
+		ContractSignService service = new ContractSignService();
+		// service.signContract("何亮", "130423199206192818", "17600220933","11");
+
+		service.querySignContractResult("11");
+	}
+}

+ 443 - 0
mec-thirdparty/src/main/java/com/ym/mec/thirdparty/lingxinpay/RSA.java

@@ -0,0 +1,443 @@
+package com.ym.mec.thirdparty.lingxinpay;
+
+import org.apache.commons.codec.binary.Base64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.crypto.Cipher;
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.security.*;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ * <p>
+ * RSA签名,加解密处理核心文件,注意:密钥长度1024
+ * </p>
+ * 
+ * @author leelun
+ * @version $Id: RSA.java, v 0.1 2013-11-15 下午2:33:53 lilun Exp $
+ */
+public class RSA {
+
+	/**
+	 * 签名算法
+	 */
+	public static final String SIGNATURE_ALGORITHM = "SHA1withRSA";
+	/**
+	 * 加密算法RSA
+	 */
+	public static final String KEY_ALGORITHM = "RSA";
+	/**
+	 * RSA最大加密明文大小
+	 */
+	private static final int MAX_ENCRYPT_BLOCK = 117;
+
+	/**
+	 * RSA最大解密密文大小
+	 */
+	private static final int MAX_DECRYPT_BLOCK = 128;
+
+	/**
+	 * 获取公钥的key
+	 */
+	public static final String PUBLIC_KEY = "RSAPublicKey";
+
+	/**
+	 * 获取私钥的key
+	 */
+	public static final String PRIVATE_KEY = "RSAPrivateKey";
+
+	private static Logger logger = LoggerFactory.getLogger(RSA.class);
+
+	/**
+	 * <p>
+	 * 生成密钥对(公钥和私钥)
+	 * </p>
+	 *
+	 * @return
+	 * @throws Exception
+	 */
+	public static Map<String, Object> genKeyPair() throws Exception {
+		KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
+		keyPairGen.initialize(1024);
+		KeyPair keyPair = keyPairGen.generateKeyPair();
+		RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
+		RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
+		Map<String, Object> keyMap = new HashMap<String, Object>(2);
+		keyMap.put(PUBLIC_KEY, publicKey);
+		keyMap.put(PRIVATE_KEY, privateKey);
+		return keyMap;
+
+	}
+
+	/**
+	 * 签名字符串
+	 *
+	 * @param text
+	 *            需要签名的字符串
+	 * @param privateKey
+	 *            私钥(BASE64编码)
+	 *
+	 * @param input_charset
+	 *            编码格式
+	 * @return 签名结果(BASE64编码)
+	 */
+	public static String sign(String text, String privateKey, String charset) throws Exception {
+
+		byte[] keyBytes = Base64.decodeBase64(privateKey);
+		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
+		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
+		PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
+		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
+		signature.initSign(privateK);
+		signature.update(getContentBytes(text, charset));
+		byte[] result = signature.sign();
+		return Base64.encodeBase64String(result);
+
+	}
+
+	/**
+	 * 签名字符串
+	 *
+	 * @param text
+	 *            需要签名的字符串
+	 * @param sign
+	 *            客户签名结果
+	 * @param publicKey
+	 *            公钥(BASE64编码)
+	 * @param input_charset
+	 *            编码格式
+	 * @return 验签结果
+	 */
+	public static boolean verify(String text, String sign, String publicKey, String charset) throws Exception {
+		byte[] keyBytes = Base64.decodeBase64(publicKey);
+		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
+		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
+		PublicKey publicK = keyFactory.generatePublic(keySpec);
+
+		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
+		signature.initVerify(publicK);
+		signature.update(getContentBytes(text, charset));
+		return signature.verify(Base64.decodeBase64(sign));
+
+	}
+
+	/**
+	 * <P>
+	 * 私钥解密
+	 * </p>
+	 *
+	 * @param encryptedData
+	 *            已加密数据
+	 * @param privateKey
+	 *            私钥(BASE64编码)
+	 * @return
+	 * @throws Exception
+	 */
+	public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception {
+		byte[] keyBytes = Base64.decodeBase64(privateKey);
+		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
+		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
+		Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
+		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
+		cipher.init(Cipher.DECRYPT_MODE, privateK);
+		int inputLen = encryptedData.length;
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		int offSet = 0;
+		byte[] cache;
+		int i = 0;
+		// 对数据分段解密
+		while (inputLen - offSet > 0) {
+			if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
+				cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
+			} else {
+				cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
+			}
+			out.write(cache, 0, cache.length);
+			i++;
+			offSet = i * MAX_DECRYPT_BLOCK;
+		}
+		byte[] decryptedData = out.toByteArray();
+		out.close();
+		return decryptedData;
+
+	}
+
+	/**
+	 * <p>
+	 * 公钥解密
+	 * </p>
+	 *
+	 * @param encryptedData
+	 *            已加密数据
+	 * @param publicKey
+	 *            公钥(BASE64编码)
+	 * @return
+	 * @throws Exception
+	 */
+	public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception {
+		byte[] keyBytes = Base64.decodeBase64(publicKey);
+		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
+		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
+		Key publicK = keyFactory.generatePublic(x509KeySpec);
+		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
+		cipher.init(Cipher.DECRYPT_MODE, publicK);
+		int inputLen = encryptedData.length;
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		int offSet = 0;
+		byte[] cache;
+		int i = 0;
+		// 对数据分段解密
+		while (inputLen - offSet > 0) {
+			if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
+				cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
+			} else {
+				cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
+			}
+			out.write(cache, 0, cache.length);
+			i++;
+			offSet = i * MAX_DECRYPT_BLOCK;
+		}
+		byte[] decryptedData = out.toByteArray();
+		out.close();
+		return decryptedData;
+
+	}
+
+	/**
+	 * <p>
+	 * 公钥加密
+	 * </p>
+	 *
+	 * @param data
+	 *            源数据
+	 * @param publicKey
+	 *            公钥(BASE64编码)
+	 * @return
+	 * @throws Exception
+	 */
+	public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
+		byte[] keyBytes = Base64.decodeBase64(publicKey);
+		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
+		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
+		Key publicK = keyFactory.generatePublic(x509KeySpec);
+		// 对数据加密
+		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
+		cipher.init(Cipher.ENCRYPT_MODE, publicK);
+		int inputLen = data.length;
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		int offSet = 0;
+		byte[] cache;
+		int i = 0;
+		// 对数据分段加密
+		while (inputLen - offSet > 0) {
+			if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
+				cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
+			} else {
+				cache = cipher.doFinal(data, offSet, inputLen - offSet);
+			}
+			out.write(cache, 0, cache.length);
+			i++;
+			offSet = i * MAX_ENCRYPT_BLOCK;
+		}
+		byte[] encryptedData = out.toByteArray();
+		out.close();
+		return encryptedData;
+
+	}
+
+	/**
+	 * <p>
+	 * 私钥加密
+	 * </p>
+	 *
+	 * @param data
+	 *            源数据
+	 * @param privateKey
+	 *            私钥(BASE64编码)
+	 * @return
+	 * @throws Exception
+	 */
+	public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception {
+		byte[] keyBytes = Base64.decodeBase64(privateKey);
+		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
+		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
+		Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
+		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
+		cipher.init(Cipher.ENCRYPT_MODE, privateK);
+		int inputLen = data.length;
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		int offSet = 0;
+		byte[] cache;
+		int i = 0;
+		// 对数据分段加密
+		while (inputLen - offSet > 0) {
+			if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
+				cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
+			} else {
+				cache = cipher.doFinal(data, offSet, inputLen - offSet);
+			}
+			out.write(cache, 0, cache.length);
+			i++;
+			offSet = i * MAX_ENCRYPT_BLOCK;
+		}
+		byte[] encryptedData = out.toByteArray();
+		out.close();
+		return encryptedData;
+
+	}
+
+	/**
+	 * @param content
+	 * @param charset
+	 * @return
+	 * @throws SignatureException
+	 * @throws UnsupportedEncodingException
+	 */
+	private static byte[] getContentBytes(String content, String charset) {
+		if (charset == null || "".equals(charset)) {
+			return content.getBytes();
+		}
+		try {
+			return content.getBytes(charset);
+		} catch (UnsupportedEncodingException e) {
+			throw new RuntimeException("签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);
+		}
+	}
+
+	/**
+	 * <p>
+	 * 获取私钥
+	 * </p>
+	 *
+	 * @param keyMap
+	 *            密钥对
+	 * @return
+	 * @throws Exception
+	 */
+	public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
+		Key key = (Key) keyMap.get(PRIVATE_KEY);
+		return Base64.encodeBase64String(key.getEncoded());
+	}
+
+	/**
+	 * <p>
+	 * 获取公钥
+	 * </p>
+	 *
+	 * @param keyMap
+	 *            密钥对
+	 * @return
+	 * @throws Exception
+	 */
+	public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
+		Key key = (Key) keyMap.get(PUBLIC_KEY);
+		return Base64.encodeBase64String(key.getEncoded());
+	}
+
+	public static void main(String[] args) throws Exception {
+		Map<String, Object> stringObjectMap = genKeyPair();
+		String publicKey = getPublicKey(stringObjectMap);
+		String privateKey = getPrivateKey(stringObjectMap);
+
+		System.out.println(publicKey);
+		System.out.println(privateKey);
+		// String jiami =
+		String jiami = "{'cardAttribute':'1','cardType':'DC','certificateNo':'340323199401163311','charset':'UTF-8','md5Key':'819ee10adc87e33486c8df1aa299c0b6','mobile':'18621542144','name':'崔','notifyUrl':'test','outMemberNo':'1136225387043356673','outerOrderNo':'111111','payAccount':'12345678','payType':'1','predictAmount':10,'projectName':'测试','salaryType':'1','service':'1dada','signType':'RSA','version':'1.0'}";
+		//String jiami = "{'cardAttribute':'1'}";
+
+		/*
+		 * byte[] bytes1 = encryptByPublicKey(jiami.getBytes(), publicKey); String bytes
+		 * = RSAUtils.decryptByPrivateKey(bytes1, privateKey);
+		 * System.out.println(bytes);
+		 */
+
+		/*
+		 * byte[] encryptPub = encryptByPublicKey(jiami.getBytes(), publicKey); byte[]
+		 * decryptPri =
+		 * decryptByPrivateKey(Base64.decodeBase64(Base64.encodeBase64(encryptPub)),
+		 * privateKey); System.out.println(decryptPri);
+		 */
+		/*String encryptPub = encryptPub(jiami, publicKey);
+		String decryptPri = decryptPri(encryptPub, privateKey);
+*/
+		String encryptPub = encryptPub(jiami, publicKey);
+		String decryptPri = decryptPri(encryptPub, privateKey);
+		System.out.println(decryptPri);
+
+	}
+
+	public static String encryptPub(String str, String publicKey) throws Exception {
+		// base64编码的公钥
+		byte[] decoded = Base64.decodeBase64(publicKey);
+		RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA")
+				.generatePublic(new X509EncodedKeySpec(decoded));
+		// RSA加密
+		Cipher cipher = Cipher.getInstance("RSA");
+		cipher.init(Cipher.ENCRYPT_MODE, pubKey);
+		int inputLen = str.getBytes("utf-8").length;
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		int offSet = 0;
+		byte[] cache;
+		int i = 0;
+		// 对数据分段加密
+		while (inputLen - offSet > 0) {
+			if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
+				cache = cipher.doFinal(str.getBytes("UTF-8"), offSet, MAX_ENCRYPT_BLOCK);
+			} else {
+				cache = cipher.doFinal(str.getBytes("UTF-8"), offSet, inputLen - offSet);
+			}
+			out.write(cache, 0, cache.length);
+			i++;
+			offSet = i * MAX_ENCRYPT_BLOCK;
+		}
+		byte[] encryptedData = out.toByteArray();
+		out.close();
+		// String outStr =
+		// Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
+		String outStr = Base64.encodeBase64String(encryptedData);
+		return outStr;
+	}
+
+	public static String decryptPri(String str, String privateKey) throws Exception {
+		// 64位解码加密后的字符串
+		byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
+		// base64编码的私钥
+		byte[] decoded = Base64.decodeBase64(privateKey);
+		RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
+				.generatePrivate(new PKCS8EncodedKeySpec(decoded));
+		// RSA解密
+		Cipher cipher = Cipher.getInstance("RSA");
+		cipher.init(Cipher.DECRYPT_MODE, priKey);
+
+		int inputLen = inputByte.length;
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		int offSet = 0;
+		byte[] cache;
+		int i = 0;
+		// 对数据分段解密
+		while (inputLen - offSet > 0) {
+			if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
+				cache = cipher.doFinal(inputByte, offSet, MAX_DECRYPT_BLOCK);
+			} else {
+				cache = cipher.doFinal(inputByte, offSet, inputLen - offSet);
+			}
+			out.write(cache, 0, cache.length);
+			i++;
+			offSet = i * MAX_DECRYPT_BLOCK;
+		}
+		byte[] decryptedData = out.toByteArray();
+		out.close();
+		// String outStr = new String(cipher.doFinal(inputByte));
+		String outStr = new String(decryptedData);
+		return outStr;
+	}
+
+}

+ 36 - 1
mec-util/src/main/java/com/ym/mec/util/freemarker/FreemarkerTemplateEngine.java

@@ -9,6 +9,7 @@ import java.util.Map;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import freemarker.cache.StringTemplateLoader;
 import freemarker.template.Configuration;
 import freemarker.template.DefaultObjectWrapper;
 import freemarker.template.Template;
@@ -17,7 +18,7 @@ public class FreemarkerTemplateEngine {
 	private static final Logger LOGGER = LoggerFactory.getLogger(FreemarkerTemplateEngine.class);
 
 	private final static FreemarkerTemplateEngine templateEngine = new FreemarkerTemplateEngine();
-
+	
 	private static Configuration cfg;
 
 	private FreemarkerTemplateEngine() {
@@ -94,4 +95,38 @@ public class FreemarkerTemplateEngine {
 		}
 	}
 
+	public void renderByString(Map<String, Object> data, String templateStr, File outputFile) {
+
+		FileWriter fw = null;
+		BufferedWriter bw = null;
+		String templateFileName = outputFile.getName();
+		try {
+			StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();
+			stringTemplateLoader.putTemplate(templateFileName, templateStr);
+			cfg.setTemplateLoader(stringTemplateLoader);
+			Template temp = cfg.getTemplate(templateFileName);
+			fw = new FileWriter(outputFile);
+			bw = new BufferedWriter(fw);
+			temp.process(data, bw);
+			bw.flush();
+		} catch (Exception e) {
+			LOGGER.warn("模板渲染失败", e);
+		} finally {
+			if (bw != null) {
+				try {
+					bw.close();
+				} catch (IOException e) {
+					LOGGER.warn("BufferedWriter关闭异常");
+				}
+			}
+			if (fw != null) {
+				try {
+					fw.close();
+				} catch (IOException e) {
+					LOGGER.warn("FileWriter关闭异常");
+				}
+			}
+		}
+	}
+
 }

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

@@ -194,10 +194,10 @@ public class ExportController extends BaseController {
         OutputStream outputStream = response.getOutputStream();
         try {
             HSSFWorkbook workbook = POIUtil.exportExcel(new String[]{"分部", "乐团编号", "乐团名称","合作单位", "乐团状态",
-                    "收费模式","收费类型","乐团主管","成团人数", "在读人数", "申请时间", "成团时间", "清单状态"}, new String[]{
+                    "收费模式","收费类型","乐团主管","成团人数", "在读人数", "申请时间", "成团时间", "清单状态", "收费标准"}, new String[]{
                     "organName", "id", "name","cooperationOrganName", "status.msg", "courseViewType.msg","chargeTypeName",
-                    "educationalTeacherName", "teamTeacherName", "groupMemberNum","payNum"
-                    ,"createTime","updateTime","hasVerifyMusicalList?'已确认':'未确认'"}, rows);
+                    "educationalTeacherName", "groupMemberNum","payNum"
+                    ,"createTime","updateTime","hasVerifyMusicalList?'已确认':'未确认'", "chargeStandard"}, rows);
             response.setContentType("application/octet-stream");
             response.setHeader("Content-Disposition", "attac:wq" +
                     "hment;filename=classGroup-" + DateUtil.getDate(new Date()) + ".xls");

+ 62 - 15
mec-web/src/main/java/com/ym/mec/web/controller/TaskController.java

@@ -1,5 +1,24 @@
 package com.ym.mec.web.controller;
 
+import io.swagger.annotations.ApiOperation;
+
+import java.io.File;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.ym.mec.biz.dal.dao.MusicGroupSchoolTermCourseDetailDao;
@@ -7,27 +26,46 @@ import com.ym.mec.biz.dal.entity.MusicGroupSchoolTermCourseDetail;
 import com.ym.mec.biz.dal.entity.TenantInfo;
 import com.ym.mec.biz.dal.enums.IndexDataType;
 import com.ym.mec.biz.event.source.CourseEventSource;
-import com.ym.mec.biz.service.*;
+import com.ym.mec.biz.service.AppRedemptionCodeService;
+import com.ym.mec.biz.service.ClassGroupService;
+import com.ym.mec.biz.service.CourseHomeworkService;
+import com.ym.mec.biz.service.CourseReviewService;
+import com.ym.mec.biz.service.CourseScheduleEvaluateService;
+import com.ym.mec.biz.service.CourseScheduleService;
+import com.ym.mec.biz.service.CourseScheduleTeacherSalaryService;
+import com.ym.mec.biz.service.CoursesGroupService;
+import com.ym.mec.biz.service.ExtracurricularExercisesService;
+import com.ym.mec.biz.service.GoodsService;
+import com.ym.mec.biz.service.IndexBaseMonthDataService;
+import com.ym.mec.biz.service.IndexErrDataRecordService;
+import com.ym.mec.biz.service.InspectionItemPlanService;
+import com.ym.mec.biz.service.MusicGroupPaymentCalenderDetailService;
+import com.ym.mec.biz.service.MusicGroupPaymentCalenderService;
+import com.ym.mec.biz.service.MusicGroupSchoolTermCourseDetailService;
+import com.ym.mec.biz.service.MusicGroupStudentFeeService;
+import com.ym.mec.biz.service.OperatingReportService;
+import com.ym.mec.biz.service.PracticeGroupService;
+import com.ym.mec.biz.service.StudentCourseHomeworkService;
+import com.ym.mec.biz.service.StudentGoodsSellService;
+import com.ym.mec.biz.service.StudentInstrumentService;
+import com.ym.mec.biz.service.StudentPaymentOrderService;
+import com.ym.mec.biz.service.StudentServeService;
+import com.ym.mec.biz.service.StudentService;
+import com.ym.mec.biz.service.SysMessageService;
+import com.ym.mec.biz.service.SysMusicCompareRecordService;
+import com.ym.mec.biz.service.TeacherAttendanceService;
+import com.ym.mec.biz.service.TeacherContractsService;
+import com.ym.mec.biz.service.TeacherCourseStatisticsService;
+import com.ym.mec.biz.service.TenantInfoService;
+import com.ym.mec.biz.service.TenantOrderRecordService;
+import com.ym.mec.biz.service.TenantPaymentOrderService;
+import com.ym.mec.biz.service.VipGroupService;
 import com.ym.mec.common.controller.BaseController;
-import com.ym.mec.common.entity.UploadReturnBean;
 import com.ym.mec.common.redis.service.RedisCache;
 import com.ym.mec.common.tenant.TenantContextHolder;
 import com.ym.mec.im.ImFeignService;
 import com.ym.mec.util.date.DateUtil;
 import com.yonge.log.service.HistoryMessageService;
-import io.swagger.annotations.ApiOperation;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.io.File;
-import java.net.URL;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
 
 @RequestMapping("task")
 @RestController
@@ -109,6 +147,9 @@ public class TaskController extends BaseController {
     private TenantOrderRecordService tenantOrderRecordService;
 	@Autowired
 	private AppRedemptionCodeService appRedemptionCodeService;
+	
+	@Autowired
+	private TeacherContractsService teacherContractsService;
 
 	@GetMapping(value = "/syncImHistoryMessageTask")
 	// 同步即时通讯聊天记录
@@ -552,4 +593,10 @@ public class TaskController extends BaseController {
     public void checkTenantState(){
         tenantInfoService.checkTenantState();
     }
+
+    @ApiOperation("查询老师协议签订状态")
+    @GetMapping(value = "/queryTeacherContractSignStatus")
+    public void queryTeacherContractSignStatus(){
+    	teacherContractsService.queryTeacherContractSignStatus();
+    }
 }

+ 43 - 0
mec-web/src/main/java/com/ym/mec/web/controller/TeacherContractController.java

@@ -0,0 +1,43 @@
+package com.ym.mec.web.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.ym.mec.biz.service.TeacherContractsService;
+import com.ym.mec.common.controller.BaseController;
+import com.ym.mec.common.page.QueryInfo;
+
+@RequestMapping("teacherContract")
+@Api(tags = "教师协议服务")
+@RestController
+public class TeacherContractController extends BaseController {
+
+    @Autowired
+    private TeacherContractsService teacherContractsService;
+
+    @ApiOperation(value = "分页查询协议列表")
+    @GetMapping("/queryPage")
+    @PreAuthorize("@pcs.hasPermissions('teacherContract/queryPage')")
+    public Object queryPage(QueryInfo queryInfo) {
+        return succeed(teacherContractsService.queryPage(queryInfo));
+    }
+
+    @ApiOperation(value = "根据教师编号查询教师协议")
+    @GetMapping("/get")
+    @ApiParam(value = "教师编号", required = true)
+    @PreAuthorize("@pcs.hasPermissions('teacherContract/get')")
+    @ApiImplicitParams({@ApiImplicitParam(name = "teacherId", value = "教师编号", required = true, dataType = "Integer")})
+    public Object get(Integer teacherId) {
+        return succeed(teacherContractsService.queryByUserId(teacherId));
+    }
+    
+}

+ 83 - 0
mec-web/src/main/java/com/ym/mec/web/controller/TenantContractTemplateController.java

@@ -0,0 +1,83 @@
+package com.ym.mec.web.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.security.access.prepost.PreAuthorize;
+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.biz.dal.dto.TenantContractTemplateDto;
+import com.ym.mec.biz.dal.entity.TenantContractTemplate;
+import com.ym.mec.biz.dal.page.TenantContractTemplateQueryInfo;
+import com.ym.mec.biz.service.TenantContractTemplateService;
+import com.ym.mec.common.controller.BaseController;
+import com.ym.mec.common.entity.HttpResponseResult;
+import com.ym.mec.common.page.PageInfo;
+import com.ym.mec.common.tenant.TenantContextHolder;
+
+@RequestMapping("tenantContractTemplate")
+@Api(tags = "机构协议模板")
+@RestController
+public class TenantContractTemplateController extends BaseController {
+
+	@Autowired
+	private TenantContractTemplateService tenantContractTemplateService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+	@ApiOperation("分页查询")
+	@GetMapping(value = "/list")
+	@PreAuthorize("@pcs.hasPermissions('tenantContractTemplate/list')")
+	public HttpResponseResult<PageInfo<TenantContractTemplateDto>> getList(TenantContractTemplateQueryInfo queryInfo) {
+		return succeed(tenantContractTemplateService.queryPageList(queryInfo));
+	}
+
+	@ApiOperation("单查询")
+	@ApiImplicitParam(name = "id", value = "ID编号", required = true, dataType = "Integer", paramType = "path")
+	@GetMapping(value = "/query")
+	@PreAuthorize("@pcs.hasPermissions('tenantContractTemplate/query')")
+	public HttpResponseResult<TenantContractTemplate> query(Integer id) {
+		return succeed(tenantContractTemplateService.get(id));
+	}
+
+	@ApiOperation("新增")
+	@PostMapping(value = "/add", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+	@PreAuthorize("@pcs.hasPermissions('tenantContractTemplate/add')")
+	public Object add(TenantContractTemplate tenantContractTemplate) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+		
+		tenantContractTemplate.setStatus(false);
+		tenantContractTemplate.setModifyBy(sysUser.getId());
+		tenantContractTemplate.setTenantId(TenantContextHolder.getTenantId());
+		tenantContractTemplateService.createContractTemplate(tenantContractTemplate);
+		return succeed();
+	}
+
+	@ApiOperation("更新")
+	@PostMapping(value = "/update", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+	@PreAuthorize("@pcs.hasPermissions('tenantContractTemplate/update')")
+	public Object update(TenantContractTemplate tenantContractTemplate) {
+		tenantContractTemplateService.update(tenantContractTemplate);
+		return succeed();
+	}
+
+	@ApiOperation("启用协议")
+	@PostMapping(value = "/updateStatus", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+	@PreAuthorize("@pcs.hasPermissions('tenantContractTemplate/updateStatus')")
+	public Object enableContract(int id) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        
+		tenantContractTemplateService.enableContract(id, sysUser.getId());
+		return succeed();
+	}
+
+}

+ 4 - 0
mec-web/src/main/java/com/ym/mec/web/controller/education/EduMusicScoreController.java

@@ -52,6 +52,10 @@ public class EduMusicScoreController extends BaseController {
         
         TenantConfig tenantConfig = tenantConfigService.getOne(new QueryWrapper<TenantConfig>().eq("tenant_id_", sysUser.getTenantId()));
         
+        if(tenantConfig == null){
+        	return failed("当前用户所在机构信息查询失败");
+        }
+        
         return succeed(sysMusicScoreCategoriesService.queryCategoriesTreeList(tenantConfig.getTeachingMaterialId()));
     }