浏览代码

Merge branch 'music_score' into online1

# Conflicts:
#	mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentDao.java
Joburgess 3 年之前
父节点
当前提交
ba2f687a5f
共有 41 个文件被更改,包括 1035 次插入43 次删除
  1. 9 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentDao.java
  2. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/CourseHomeworkStudentDetailDto.java
  3. 47 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/SoundCheckHelper.java
  4. 6 6
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/WebSocketClientDetail.java
  5. 7 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/WebSocketInfo.java
  6. 10 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysMusicCompareRecord.java
  7. 3 3
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/HeardLevelEnum.java
  8. 7 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/MessageTypeEnum.java
  9. 3 3
      mec-biz/src/main/java/com/ym/mec/biz/handler/WebSocketHandler.java
  10. 10 1
      mec-biz/src/main/java/com/ym/mec/biz/service/SysMusicCompareRecordService.java
  11. 6 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ExtracurricularExercisesReplyServiceImpl.java
  12. 29 6
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SoundCheckHandler.java
  13. 4 4
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SoundCompareHandler.java
  14. 5 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentCourseHomeworkServiceImpl.java
  15. 95 10
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysMusicCompareRecordServiceImpl.java
  16. 4 0
      mec-biz/src/main/resources/config/mybatis/StudentMapper.xml
  17. 5 2
      mec-biz/src/main/resources/config/mybatis/SysMusicCompareRecordMapper.xml
  18. 4 0
      mec-client-api/src/main/java/com/ym/mec/task/TaskRemoteService.java
  19. 5 0
      mec-client-api/src/main/java/com/ym/mec/task/fallback/TaskRemoteServiceFallback.java
  20. 1 1
      mec-gateway/mec-gateway-web/src/main/resources/bootstrap-test.properties
  21. 2 2
      mec-student/src/main/java/com/ym/mec/student/controller/SysMusicCompareRecordController.java
  22. 19 0
      mec-task/src/main/java/com/ym/mec/task/jobs/StudentWeekTrainRemindTask.java
  23. 2 2
      mec-teacher/src/main/java/com/ym/mec/teacher/controller/SysMusicCompareRecordController.java
  24. 9 0
      mec-web/src/main/java/com/ym/mec/web/controller/TaskController.java
  25. 2 2
      mec-web/src/main/java/com/ym/mec/web/controller/education/SysMusicCompareRecordController.java
  26. 83 0
      mec-websocket/pom.xml
  27. 49 0
      mec-websocket/src/main/java/com/ym/mec/web/WebSocketApplication.java
  28. 52 0
      mec-websocket/src/main/java/com/ym/mec/web/config/PermissionCheckService.java
  29. 44 0
      mec-websocket/src/main/java/com/ym/mec/web/config/ResourceServerConfig.java
  30. 48 0
      mec-websocket/src/main/java/com/ym/mec/web/config/WebMvcConfig.java
  31. 41 0
      mec-websocket/src/main/java/com/ym/mec/web/config/WebSocketConfig.java
  32. 61 0
      mec-websocket/src/main/java/com/ym/mec/web/controller/WebsocketController.java
  33. 33 0
      mec-websocket/src/main/java/com/ym/mec/web/interceptor/OperationLogInterceptor.java
  34. 28 0
      mec-websocket/src/main/java/com/ym/mec/web/interceptor/WebSocketHandshakeInterceptor.java
  35. 143 0
      mec-websocket/src/main/resources/application.yml
  36. 16 0
      mec-websocket/src/main/resources/bootstrap-dev.properties
  37. 16 0
      mec-websocket/src/main/resources/bootstrap-dev_server.properties
  38. 16 0
      mec-websocket/src/main/resources/bootstrap-prod.properties
  39. 16 0
      mec-websocket/src/main/resources/bootstrap-test.properties
  40. 83 0
      mec-websocket/src/main/resources/logback-spring.xml
  41. 1 0
      pom.xml

+ 9 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentDao.java

@@ -363,4 +363,13 @@ public interface StudentDao extends com.ym.mec.common.dal.BaseDAO<Integer, Stude
      * @return
      */
     List<Map<Integer, String>> queryStudentOrganNameMap(@Param("userIdList") List<Integer> userIdList);
+
+    /**
+     * @describe 获取生效中的学员编号
+     * @author Joburgess
+     * @date 2021/8/27 0027
+     * @param :
+     * @return java.util.Set<java.lang.Integer>
+     */
+    Set<Integer> getValidVipStudentIds();
 }

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

@@ -1,5 +1,6 @@
 package com.ym.mec.biz.dal.dto;
 
+import com.ym.mec.biz.dal.entity.SysMusicScore;
 import com.ym.mec.biz.dal.enums.YesOrNoEnum;
 import io.swagger.annotations.ApiModelProperty;
 
@@ -66,6 +67,16 @@ public class CourseHomeworkStudentDetailDto {
 
     private Integer hasMember;
 
+    private SysMusicScore sysMusicScore;
+
+    public SysMusicScore getSysMusicScore() {
+        return sysMusicScore;
+    }
+
+    public void setSysMusicScore(SysMusicScore sysMusicScore) {
+        this.sysMusicScore = sysMusicScore;
+    }
+
     public Integer getHasMember() {
         return hasMember;
     }

+ 47 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/SoundCheckHelper.java

@@ -0,0 +1,47 @@
+package com.ym.mec.biz.dal.dto;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @Author Joburgess
+ * @Date 2021/8/26 0026
+ */
+public class SoundCheckHelper {
+
+    private double frequency;
+
+    private int rightSize;
+
+    private AtomicInteger errorNum = new AtomicInteger(0);
+
+    public SoundCheckHelper() {
+    }
+
+    public SoundCheckHelper(double frequency) {
+        this.frequency = frequency;
+    }
+
+    public double getFrequency() {
+        return frequency;
+    }
+
+    public void setFrequency(double frequency) {
+        this.frequency = frequency;
+    }
+
+    public int getRightSize() {
+        return rightSize;
+    }
+
+    public void setRightSize(int rightSize) {
+        this.rightSize = rightSize;
+    }
+
+    public AtomicInteger getErrorNum() {
+        return errorNum;
+    }
+
+    public void setErrorNum(AtomicInteger errorNum) {
+        this.errorNum = errorNum;
+    }
+}

+ 6 - 6
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/WebSocketClientDetail.java

@@ -13,16 +13,16 @@ public class WebSocketClientDetail {
 
     private WebSocketSession session;
 
-    @ApiModelProperty(value = "用户登录时间")
-    private Date loginTime;
+    @ApiModelProperty(value = "用户登录时间")
+    private long loginTime;
 
-    @ApiModelProperty(value = "用户退出或断开时间")
+    @ApiModelProperty(value = "用户退出或断开时间")
     private Date logoutTime;
 
     public WebSocketClientDetail() {
     }
 
-    public WebSocketClientDetail(WebSocketSession session, Date loginTime) {
+    public WebSocketClientDetail(WebSocketSession session, long loginTime) {
         this.session = session;
         this.loginTime = loginTime;
     }
@@ -35,11 +35,11 @@ public class WebSocketClientDetail {
         this.session = session;
     }
 
-    public Date getLoginTime() {
+    public long getLoginTime() {
         return loginTime;
     }
 
-    public void setLoginTime(Date loginTime) {
+    public void setLoginTime(long loginTime) {
         this.loginTime = loginTime;
     }
 

+ 7 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/WebSocketInfo.java

@@ -3,6 +3,8 @@ package com.ym.mec.biz.dal.dto;
 import com.ym.mec.biz.dal.enums.WebsocketTypeEnum;
 import org.springframework.http.HttpStatus;
 
+import java.util.HashMap;
+
 /**
  * @Author Joburgess
  * @Date 2021/6/17 0017
@@ -74,6 +76,11 @@ public class WebSocketInfo<T> {
         return new WebSocketInfo(new Head(commond));
     }
 
+    public static WebSocketInfo success(String commond, String bodyKey, Object bodyValue){
+        WebSocketInfo webSocketInfo = new WebSocketInfo(new Head(commond));
+        webSocketInfo.setBody(new HashMap<String, Object>(){{put(bodyKey, bodyValue);}});
+        return webSocketInfo;
+    }
 
     public Head getHeader() {
         return header;

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

@@ -34,6 +34,8 @@ public class SysMusicCompareRecord {
 	/** 评分数据 */
 	private String scoreData;
 
+	private int notesDataIndex;
+
 	/** 总分 */
 	private BigDecimal score;
 
@@ -127,6 +129,14 @@ public class SysMusicCompareRecord {
 		return this.scoreData;
 	}
 
+	public int getNotesDataIndex() {
+		return notesDataIndex;
+	}
+
+	public void setNotesDataIndex(int notesDataIndex) {
+		this.notesDataIndex = notesDataIndex;
+	}
+
 	public BigDecimal getScore() {
 		return score;
 	}

+ 3 - 3
mec-biz/src/main/java/com/ym/mec/biz/dal/enums/HeardLevelEnum.java

@@ -3,9 +3,9 @@ package com.ym.mec.biz.dal.enums;
 import com.ym.mec.common.enums.BaseEnum;
 
 public enum HeardLevelEnum implements BaseEnum<String, HeardLevelEnum> {
-    BEGINNER("BEGINNER","初学者", 9, 0.05f, 0),
-    ADVANCED("ADVANCED","进阶", 3, 0.09f, 0),
-    PERFORMER("PERFORMER","小演奏家", 1, 0.3f, 0);
+    BEGINNER("BEGINNER","入门级", 9, 0.05f, 0),
+    ADVANCED("ADVANCED","进阶", 3, 0.09f, 0),
+    PERFORMER("PERFORMER","大师级", 1, 0.3f, 0);
 
     private String code;
 

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

@@ -186,7 +186,13 @@ public enum MessageTypeEnum implements BaseEnum<String, MessageTypeEnum> {
     CHILDREN_DAY_NOTICE_MSG("CHILDREN_DAY_NOTICE_MSG", "技能评测考级报名短信"),
     NO_BUY_CLOUD_TEACHER_MSG("NO_BUY_CLOUD_TEACHER_MSG", "未购买买云教练短信"),
     OA_NOTICE_PUSH("OA_NOTICE_PUSH", "待审批提醒"),
-    OA_CC_NOTICE_PUSH("OA_CC_NOTICE_PUSH", "审批抄送提醒");
+    OA_CC_NOTICE_PUSH("OA_CC_NOTICE_PUSH", "审批抄送提醒"),
+
+    //云教练
+    TRAIN_NO_RANK_STUDENT_PUSH("TRAIN_NO_RANK_STUDENT_PUSH", "云教练训练提醒"),
+    TRAIN_RANK_STUDENT_PUSH("TRAIN_RANK_STUDENT_PUSH", "云教练训练提醒"),
+    NO_TRAIN_STUDENT_PUSH("NO_TRAIN_STUDENT_PUSH", "云教练训练提醒"),
+    ;
 
     MessageTypeEnum(String code, String msg) {
         this.code = code;

+ 3 - 3
mec-biz/src/main/java/com/ym/mec/biz/handler/WebSocketHandler.java

@@ -57,7 +57,7 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
     public void afterConnectionEstablished(WebSocketSession session) throws Exception {
         String phone = session.getPrincipal().getName().split(":")[1];
         LOGGER.info("{}上线", phone);
-        WS_CLIENTS.put(phone, new WebSocketClientDetail(session, new Date()));
+        WS_CLIENTS.put(phone, new WebSocketClientDetail(session, System.currentTimeMillis()));
         appMap.values().forEach(e->e.afterConnectionEstablished(session, phone));
         super.afterConnectionEstablished(session);
     }
@@ -96,7 +96,7 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
     public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
         String phone = session.getPrincipal().getName().split(":")[1];
         session.close();
-        LOGGER.info("发生了错误,移除客户端: {}", phone);
+        LOGGER.info("发生了错误,移除客户端: {}", phone, exception);
         appMap.values().forEach(e->e.afterConnectionClosed(session, phone));
         exception.printStackTrace();
         if(!WS_CLIENTS.containsKey(phone)){
@@ -109,7 +109,7 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
     public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
         super.afterConnectionClosed(session, status);
         String phone = session.getPrincipal().getName().split(":")[1];
-        LOGGER.info("{}离线: {}s", phone, (System.currentTimeMillis() - WS_CLIENTS.get(phone).getLoginTime().getTime())*1000);
+        LOGGER.info("{}离线: {}s", phone, (System.currentTimeMillis() - WS_CLIENTS.get(phone).getLoginTime())/1000);
         appMap.values().forEach(e->e.afterConnectionClosed(session, phone));
         WS_CLIENTS.remove(phone);
     }

+ 10 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/SysMusicCompareRecordService.java

@@ -29,7 +29,7 @@ public interface SysMusicCompareRecordService extends BaseService<Long, SysMusic
      * @param userId:
      * @return java.util.List<com.ym.mec.biz.dal.dto.MusicalNotesPlayStatDto>
      */
-    Object getLastEvaluationMusicalNotesPlayStats(Integer userId);
+    Object getLastEvaluationMusicalNotesPlayStats(Integer userId, Long recordId);
 
     /**
      * @describe 云教练排行榜
@@ -41,6 +41,15 @@ public interface SysMusicCompareRecordService extends BaseService<Long, SysMusic
     StatDto rankingList(SysMusicCompareRecordQueryInfo queryInfo);
 
     /**
+     * @describe 本周学员训练提醒
+     * @author Joburgess
+     * @date 2021/8/27 0027
+     * @param :
+     * @return void
+     */
+    void curWeekStudentTrainRemind();
+
+    /**
      * @describe 学员训练数据统计
      * @author Joburgess
      * @date 2021/8/12 0012

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

@@ -55,6 +55,8 @@ public class ExtracurricularExercisesReplyServiceImpl extends BaseServiceImpl<Lo
 	@Autowired
 	private CourseScheduleDao courseScheduleDao;
 	@Autowired
+	private SysMusicScoreDao sysMusicScoreDao;
+	@Autowired
 	private StudentServeService studentServeService;
 
 	@Override
@@ -103,6 +105,10 @@ public class ExtracurricularExercisesReplyServiceImpl extends BaseServiceImpl<Lo
 		detail.setStudentName(extraExerciseReply.getStudentName());
 		detail.setExpiryDate(extraExerciseReply.getExpireDate());
 		detail.setType("EXTRA");
+		if(extraExerciseReply.getMusicScoreId() != null){
+			detail.setSysMusicScore(sysMusicScoreDao.get(extraExerciseReply.getMusicScoreId()));
+		}
+
 		String configValue = sysConfigDao.findConfigValue(SysConfigService.HOMEWORK_OPEN_FLAG);
 		if(StringUtils.isEmpty(configValue)){
 			configValue = "0";

+ 29 - 6
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SoundCheckHandler.java

@@ -10,6 +10,7 @@ import be.tarsos.dsp.util.PitchConverter;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.ym.mec.biz.dal.dto.MusicPitchDetailDto;
+import com.ym.mec.biz.dal.dto.SoundCheckHelper;
 import com.ym.mec.biz.dal.dto.SoundCheckInfoDto;
 import com.ym.mec.biz.dal.dto.WebSocketInfo;
 import com.ym.mec.biz.dal.enums.WebsocketTypeEnum;
@@ -17,6 +18,9 @@ import com.ym.mec.biz.handler.WebSocketHandler;
 import com.ym.mec.biz.service.SoundSocketService;
 import com.ym.mec.biz.service.WebSocketEventHandler;
 import com.ym.mec.common.exception.BizException;
+import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 import org.springframework.web.socket.BinaryMessage;
 import org.springframework.web.socket.TextMessage;
@@ -36,10 +40,12 @@ import java.util.concurrent.ConcurrentHashMap;
 @Service
 public class SoundCheckHandler implements WebSocketEventHandler {
 
-    private static final double COMPARE_FREQUENCY = 525;
+    private final Logger LOGGER = LoggerFactory.getLogger(SoundCheckHandler.class);
+
+    private final int SIZE = 44100;
 
     /** 校音数据 */
-    private Map<String, Integer> userSoundCheckInfo = new ConcurrentHashMap<>();
+    private Map<String, SoundCheckHelper> userSoundCheckInfo = new ConcurrentHashMap<>();
 
     public SoundCheckHandler() {
         WebSocketHandler.regist(WebsocketTypeEnum.SOUND_CHECK, this);
@@ -57,7 +63,11 @@ public class SoundCheckHandler implements WebSocketEventHandler {
                 userSoundCheckInfo.remove(phone);
                 break;
             default:
-                userSoundCheckInfo.put(phone, 0);
+                userSoundCheckInfo.put(phone, new SoundCheckHelper(442));
+                JSONObject body = (JSONObject) message.getBody();
+                if(body.containsKey("frequency")){
+                    userSoundCheckInfo.get(phone).setFrequency(body.getDoubleValue("frequency"));
+                }
                 break;
         }
     }
@@ -70,17 +80,30 @@ public class SoundCheckHandler implements WebSocketEventHandler {
         try {
             AudioDispatcher dispatcher = AudioDispatcherFactory.fromByteArray(message.getPayload().array(), SoundCompareHandler.soundCompareConfig.audioFormat, SoundCompareHandler.soundCompareConfig.simpleSize, SoundCompareHandler.soundCompareConfig.overlap);
             dispatcher.addAudioProcessor(new PitchProcessor(SoundCompareHandler.soundCompareConfig.algo, SoundCompareHandler.soundCompareConfig.simpleRate, SoundCompareHandler.soundCompareConfig.simpleSize, (pitchDetectionResult, audioEvent) -> {
+                if(!userSoundCheckInfo.containsKey(phone)){
+                    return;
+                }
                 if(pitchDetectionResult.getPitch()<=0){
                     return;
                 }
-                double normalCents = PitchConverter.hertzToAbsoluteCent(COMPARE_FREQUENCY);
+                double normalCents = PitchConverter.hertzToAbsoluteCent(userSoundCheckInfo.get(phone).getFrequency());
                 double recordCents = PitchConverter.hertzToAbsoluteCent(pitchDetectionResult.getPitch());
                 if(Math.abs(normalCents - recordCents)<3){
-                    WebSocketHandler.sendTextMessage(phone, WebSocketInfo.success("checkDone"));
-                    userSoundCheckInfo.remove(phone);
+                    userSoundCheckInfo.get(phone).setRightSize(userSoundCheckInfo.get(phone).getRightSize() + audioEvent.getBufferSize());
+                    userSoundCheckInfo.get(phone).getErrorNum().set(0);
+                    WebSocketHandler.sendTextMessage(phone, WebSocketInfo.success("checking", "trend", 0));
+                }else if(Math.abs(normalCents - recordCents)>=3){
+                    userSoundCheckInfo.get(phone).getErrorNum().getAndIncrement();
+                    WebSocketHandler.sendTextMessage(phone, WebSocketInfo.success("checking", "trend", normalCents>recordCents?-1:1));
                 }
             }));
             dispatcher.run();
+            if(userSoundCheckInfo.get(phone).getRightSize()>SIZE){
+                WebSocketHandler.sendTextMessage(phone, WebSocketInfo.success("checkDone"));
+                userSoundCheckInfo.remove(phone);
+            }else if(userSoundCheckInfo.get(phone).getErrorNum().get()>5){
+                userSoundCheckInfo.get(phone).setRightSize(0);
+            }
         } catch (UnsupportedAudioFileException e) {
             throw new BizException("{}校音异常:{}", phone, e);
         }

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

@@ -343,9 +343,9 @@ public class SoundCompareHandler implements WebSocketEventHandler {
                     }
                     cadenceValidNum++;
                     //如果频率差值在节奏误差范围内
-                    if(Math.abs(recordInfo.getFrequency()-musicXmlInfo.getFrequency())<=soundCompareConfig.integrityFrequencyRange){
-                        integrityValidNum++;
-                    }
+//                    if(Math.abs(recordInfo.getFrequency()-musicXmlInfo.getFrequency())<=soundCompareConfig.integrityFrequencyRange){
+//                        integrityValidNum++;
+//                    }
                 }
 
                 //非正常频率次数
@@ -418,7 +418,7 @@ public class SoundCompareHandler implements WebSocketEventHandler {
                     cadenceRight = true;
                 }
                 //音准、完成度
-                if (!CollectionUtils.isEmpty(measureSoundPitchInfos)){
+                if (cadenceRight && !CollectionUtils.isEmpty(measureSoundPitchInfos)){
                     //音准
                     Double avgPitch = measureSoundPitchInfos.stream().filter(pitch -> Math.abs((pitch.getFrequency()-musicXmlInfo.getFrequency()))<5).collect(Collectors.averagingDouble(pitch -> pitch.getFrequency()));
                     //音分

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

@@ -74,6 +74,8 @@ public class StudentCourseHomeworkServiceImpl extends BaseServiceImpl<Long, Stud
     private ExtracurricularExercisesReplyDao extracurricularExercisesReplyDao;
     @Autowired
     private SysConfigDao sysConfigDao;
+    @Autowired
+    private SysMusicScoreDao sysMusicScoreDao;
 
     @Override
     public BaseDAO<Long, StudentCourseHomework> getDAO() {
@@ -208,6 +210,9 @@ public class StudentCourseHomeworkServiceImpl extends BaseServiceImpl<Long, Stud
                 courseHomeworkStudentDetail.setTeacherId(courseSchedule.getActualTeacherId());
                 courseHomeworkStudentDetail.setTeacherName(teacher.getRealName());
             }
+            if(courseHomeworkStudentDetail.getMusicScoreId() != null){
+                courseHomeworkStudentDetail.setSysMusicScore(sysMusicScoreDao.get(courseHomeworkStudentDetail.getMusicScoreId()));
+            }
         }
         courseHomeworkStudentDetail.setType("HOMEWORK");
         String configValue = sysConfigDao.findConfigValue(SysConfigService.HOMEWORK_OPEN_FLAG);

+ 95 - 10
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysMusicCompareRecordServiceImpl.java

@@ -3,19 +3,20 @@ package com.ym.mec.biz.service.impl;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.ym.mec.auth.api.entity.SysUser;
-import com.ym.mec.biz.dal.dao.StudentDao;
-import com.ym.mec.biz.dal.dao.SysMusicCompareRecordDao;
-import com.ym.mec.biz.dal.dao.TeacherDao;
+import com.ym.mec.biz.dal.dao.*;
 import com.ym.mec.biz.dal.dto.*;
 import com.ym.mec.biz.dal.entity.IndexBaseMonthData;
 import com.ym.mec.biz.dal.entity.SysMusicCompareRecord;
-import com.ym.mec.biz.dal.enums.FeatureType;
-import com.ym.mec.biz.dal.enums.IndexDataType;
+import com.ym.mec.biz.dal.entity.SysMusicScore;
+import com.ym.mec.biz.dal.enums.*;
 import com.ym.mec.biz.dal.page.SysMusicCompareRecordQueryInfo;
+import com.ym.mec.biz.service.SysConfigService;
+import com.ym.mec.biz.service.SysMessageService;
 import com.ym.mec.biz.service.SysMusicCompareRecordService;
 import com.ym.mec.common.dal.BaseDAO;
 import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.service.impl.BaseServiceImpl;
+import com.ym.mec.thirdparty.message.MessageSenderPluginContext;
 import com.ym.mec.util.collection.MapUtil;
 import com.ym.mec.util.date.DateUtil;
 import io.swagger.models.auth.In;
@@ -36,9 +37,16 @@ public class SysMusicCompareRecordServiceImpl extends BaseServiceImpl<Long, SysM
 	@Autowired
 	private SysMusicCompareRecordDao sysMusicCompareRecordDao;
 	@Autowired
+	private SysMusicScoreDao sysMusicScoreDao;
+	@Autowired
 	private TeacherDao teacherDao;
 	@Autowired
 	private StudentDao studentDao;
+	@Autowired
+	private SysMessageService sysMessageService;
+
+	@Autowired
+	private SysConfigDao sysConfigDao;
 
 	@Override
 	public BaseDAO<Long, SysMusicCompareRecord> getDAO() {
@@ -90,16 +98,33 @@ public class SysMusicCompareRecordServiceImpl extends BaseServiceImpl<Long, SysM
 	}
 
 	@Override
-	public Object getLastEvaluationMusicalNotesPlayStats(Integer userId) {
-		SysMusicCompareRecord userLastEvaluationData = sysMusicCompareRecordDao.getUserLastEvaluationData(userId);
+	public Object getLastEvaluationMusicalNotesPlayStats(Integer userId, Long recordId) {
+		SysMusicCompareRecord userLastEvaluationData;
+		if(Objects.nonNull(recordId)){
+			userLastEvaluationData = sysMusicCompareRecordDao.get(recordId);
+		}else{
+			userLastEvaluationData = sysMusicCompareRecordDao.getUserLastEvaluationData(userId);
+		}
+		if(Objects.isNull(userLastEvaluationData)){
+			return null;
+		}
 		if(StringUtils.isBlank(userLastEvaluationData.getScoreData())){
 			return null;
 		}
+
 		JSONObject jsonObject = JSON.parseObject(userLastEvaluationData.getScoreData());
-		if(!jsonObject.containsKey("musicalNotesPlayStats")){
-			return null;
+		jsonObject.put("recordId", userLastEvaluationData.getId());
+		jsonObject.put("score", userLastEvaluationData.getScore());
+		jsonObject.put("cadence", userLastEvaluationData.getCadence());
+		jsonObject.put("intonation", userLastEvaluationData.getIntonation());
+		jsonObject.put("integrity", userLastEvaluationData.getIntegrity());
+		jsonObject.put("heardLevel", userLastEvaluationData.getHeardLevel());
+
+		SysMusicScore sysMusicScore = sysMusicScoreDao.get(userLastEvaluationData.getSysMusicScoreId());
+		if(Objects.nonNull(sysMusicScore)){
+			jsonObject.put("sysMusicScoreName", sysMusicScore.getName());
 		}
-		return jsonObject.get("musicalNotesPlayStats");
+		return jsonObject;
 	}
 
 	@Override
@@ -148,6 +173,63 @@ public class SysMusicCompareRecordServiceImpl extends BaseServiceImpl<Long, SysM
 	}
 
 	@Override
+	public void curWeekStudentTrainRemind() {
+		Set<Integer> validVipStudentIds = studentDao.getValidVipStudentIds();
+		LocalDate monday = LocalDate.now().with(DateUtil.weekFields.dayOfWeek(), DayOfWeek.MONDAY.getValue());
+		LocalDate sunday = LocalDate.now().with(DateUtil.weekFields.dayOfWeek(), DayOfWeek.SUNDAY.getValue());
+		List<MusicCompareRankingDto> userTrainStat = sysMusicCompareRecordDao.getUserTrainStat(monday.toString(), sunday.toString(), null);
+
+		Set<Integer> trainStudentIds = new HashSet<>();
+		Set<Integer> ranStudentIds = new HashSet<>();
+
+		if(!CollectionUtils.isEmpty(userTrainStat)){
+			trainStudentIds = userTrainStat.stream().map(MusicCompareRankingDto::getUserId).collect(Collectors.toSet());
+			//时长榜
+			Set<Integer> collect1 = userTrainStat.stream().sorted(Comparator.comparing(MusicCompareRankingDto::getTrainTime, Comparator.reverseOrder())).limit(10).map(MusicCompareRankingDto::getUserId).collect(Collectors.toSet());
+			ranStudentIds.addAll(collect1);
+			Set<Integer> collect2 = userTrainStat.stream().sorted(Comparator.comparing(MusicCompareRankingDto::getTrainDays, Comparator.reverseOrder())).limit(10).map(MusicCompareRankingDto::getUserId).collect(Collectors.toSet());
+			ranStudentIds.addAll(collect2);
+		}
+		List<MusicCompareRankingDto> userTrainStat3 = sysMusicCompareRecordDao.getUserTrainStat(monday.toString(), sunday.toString(), HeardLevelEnum.BEGINNER);
+		if(!CollectionUtils.isEmpty(userTrainStat3)){
+			Set<Integer> collect3 = userTrainStat3.stream().sorted(Comparator.comparing(MusicCompareRankingDto::getScore, Comparator.reverseOrder())).limit(10).map(MusicCompareRankingDto::getUserId).collect(Collectors.toSet());
+			ranStudentIds.addAll(collect3);
+		}
+		List<MusicCompareRankingDto> userTrainStat4 = sysMusicCompareRecordDao.getUserTrainStat(monday.toString(), sunday.toString(), HeardLevelEnum.ADVANCED);
+		if(!CollectionUtils.isEmpty(userTrainStat4)){
+			Set<Integer> collect4 = userTrainStat4.stream().sorted(Comparator.comparing(MusicCompareRankingDto::getScore, Comparator.reverseOrder())).limit(10).map(MusicCompareRankingDto::getUserId).collect(Collectors.toSet());
+			ranStudentIds.addAll(collect4);
+		}
+		List<MusicCompareRankingDto> userTrainStat5 = sysMusicCompareRecordDao.getUserTrainStat(monday.toString(), sunday.toString(), HeardLevelEnum.PERFORMER);
+		if(!CollectionUtils.isEmpty(userTrainStat5)){
+			Set<Integer> collect5 = userTrainStat5.stream().sorted(Comparator.comparing(MusicCompareRankingDto::getScore, Comparator.reverseOrder())).limit(10).map(MusicCompareRankingDto::getUserId).collect(Collectors.toSet());
+			ranStudentIds.addAll(collect5);
+		}
+
+		Map<Integer, String> userMap1 = new HashMap<>();
+		Map<Integer, String> userMap2 = new HashMap<>();
+		Map<Integer, String> userMap3 = new HashMap<>();
+		for (Integer studentId : validVipStudentIds) {
+			if (trainStudentIds.contains(studentId) && !ranStudentIds.contains(studentId)){
+				userMap1.put(studentId, studentId.toString());
+			}
+			if(ranStudentIds.contains(studentId)){
+				userMap2.put(studentId, studentId.toString());
+			}
+			if(!trainStudentIds.contains(studentId)){
+				userMap3.put(studentId, studentId.toString());
+			}
+		}
+		String baseApiUrl = sysConfigDao.findConfigValue("base_api_url");
+		sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.TRAIN_NO_RANK_STUDENT_PUSH,userMap1,
+				null, 0, "5?"+baseApiUrl+"/#/cloudRanking", "STUDENT");
+		sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.TRAIN_RANK_STUDENT_PUSH,userMap2,
+				null, 0, "5?"+baseApiUrl+"/#/cloudRanking", "STUDENT");
+		sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.NO_TRAIN_STUDENT_PUSH,userMap3,
+				null, 0, "5?"+baseApiUrl+"/#/cloudRanking", "STUDENT");
+	}
+
+	@Override
 	public Map<String, Object> studentTrainData(SysMusicCompareRecordQueryInfo queryInfo) {
 		StudentTrainOverviewDto userTrainOverView = new StudentTrainOverviewDto();
 
@@ -198,6 +280,9 @@ public class SysMusicCompareRecordServiceImpl extends BaseServiceImpl<Long, SysM
 			trainNumData.add(new IndexBaseMonthData(trainDate, null, new BigDecimal(data.getTrainNum())));
 		}
 
+		trainNumData.sort(Comparator.comparing(IndexBaseMonthData::getMonth));
+		trainTimeData.sort(Comparator.comparing(IndexBaseMonthData::getMonth));
+
 		userTrainChartResult.add(new IndexBaseDto(IndexDataType.CLOUD_STUDY_TRAIN_TIME, trainTimeData));
 		userTrainChartResult.add(new IndexBaseDto(IndexDataType.CLOUD_STUDY_TRAIN_NUM, trainNumData));
 

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

@@ -1217,6 +1217,10 @@
         </foreach>
     </select>
 
+    <select id="getValidVipStudentIds" resultType="java.lang.Integer">
+        SELECT user_id_ FROM student WHERE member_rank_setting_id_ IS NOT NULl OR experience_member_rank_setting_id_ IS NOT NULL
+    </select>
+
     <update id="updateGrade"><![CDATA[
         UPDATE student SET current_grade_num_=current_grade_num_+1
         WHERE current_grade_num_>=1

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

@@ -14,6 +14,7 @@
 		<result column="sys_music_score_name_" property="sysMusicScoreName" />
 		<result column="behavior_id_" property="behaviorId"/>
 		<result column="score_data_" property="scoreData" />
+		<result column="notes_data_index_" property="notesDataIndex"/>
 		<result column="score_" property="score" />
 		<result column="intonation_" property="intonation" />
 		<result column="cadence_" property="cadence" />
@@ -120,7 +121,9 @@
 	<!-- 分页查询 -->
 	<select id="queryPage" resultMap="SysMusicCompareRecord" parameterType="map">
 		SELECT
-			smcr.id_, smcr.user_id_, smcr.sys_music_score_id_,smcr.heard_level_, smcr.score_, smcr.intonation_, smcr.cadence_,
+			smcr.id_, smcr.user_id_, smcr.sys_music_score_id_, smcr.heard_level_,
+			LOCATE('musicalNotesPlayStats', smcr.score_data_) notes_data_index_,
+		       smcr.score_, smcr.intonation_, smcr.cadence_,
 		       smcr.integrity_, smcr.record_file_path_, smcr.client_id_, smcr.device_type_, smcr.play_time_,
 		       smcr.monday_, smcr.create_time_,
 			sms.name_ sys_music_score_name_
@@ -379,6 +382,6 @@
 	</select>
 
     <select id="getUserLastEvaluationData" resultMap="SysMusicCompareRecord">
-		SELECT * FROM sys_music_compare_record WHERE user_id_=#{userId} ORDER BY create_time_ DESC LIMIT 1
+		SELECT * FROM sys_music_compare_record WHERE user_id_=#{userId} AND feature_ = 'CLOUD_STUDY_EVALUATION' ORDER BY create_time_ DESC LIMIT 1
 	</select>
 </mapper>

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

@@ -219,4 +219,8 @@ public interface TaskRemoteService {
 	/** 清理学员云教练连续使用天数 */
 	@GetMapping("task/cleanStudentCloudStudySequenceDays")
 	void cleanStudentCloudStudySequenceDays();
+
+	/** 本周学员训练提醒 */
+	@GetMapping("task/curWeekStudentTrainRemind")
+	void curWeekStudentTrainRemind();
 }

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

@@ -272,4 +272,9 @@ public class TaskRemoteServiceFallback implements TaskRemoteService {
 	public void cleanStudentCloudStudySequenceDays() {
 		logger.error("清理学员云教练连续使用天数失败");
 	}
+
+	@Override
+	public void curWeekStudentTrainRemind() {
+		logger.error("本周学员训练提醒失败");
+	}
 }

+ 1 - 1
mec-gateway/mec-gateway-web/src/main/resources/bootstrap-test.properties

@@ -3,7 +3,7 @@
 #\u670d\u52a1\u5668\u5730\u5740
 spring.cloud.nacos.config.server-addr=47.114.1.200:8848
 #\u9ed8\u8ba4\u4e3aPublic\u547d\u540d\u7a7a\u95f4,\u53ef\u4ee5\u7701\u7565\u4e0d\u5199
-spring.cloud.nacos.config.namespace=f753d9d9-4bb2-4df6-a483-da9e169617c4
+spring.cloud.nacos.config.namespace=46f06363-b9d6-46f0-9cd7-7b33dcf26bb0
 #\u6307\u5b9a\u914d\u7f6e\u7fa4\u7ec4 --\u5982\u679c\u662fPublic\u547d\u540d\u7a7a\u95f4 \u5219\u53ef\u4ee5\u7701\u7565\u7fa4\u7ec4\u914d\u7f6e
 spring.cloud.nacos.config.group=DEFAULT_GROUP
 #\u6587\u4ef6\u540d -- \u5982\u679c\u6ca1\u6709\u914d\u7f6e\u5219\u9ed8\u8ba4\u4e3a ${spring.appliction.name}

+ 2 - 2
mec-student/src/main/java/com/ym/mec/student/controller/SysMusicCompareRecordController.java

@@ -50,12 +50,12 @@ public class SysMusicCompareRecordController extends BaseController {
 
     @ApiOperation(value = "用户最后一次评测数据")
     @GetMapping("getLastEvaluationMusicalNotesPlayStats")
-    public HttpResponseResult getLastEvaluationMusicalNotesPlayStats(){
+    public HttpResponseResult getLastEvaluationMusicalNotesPlayStats(Long recordId){
         SysUser sysUser = sysUserFeignService.queryUserInfo();
         if(sysUser == null){
             throw new BizException("请登录");
         }
-        return succeed(sysMusicCompareRecordService.getLastEvaluationMusicalNotesPlayStats(sysUser.getId()));
+        return succeed(sysMusicCompareRecordService.getLastEvaluationMusicalNotesPlayStats(sysUser.getId(), recordId));
     }
 
 }

+ 19 - 0
mec-task/src/main/java/com/ym/mec/task/jobs/StudentWeekTrainRemindTask.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 StudentWeekTrainRemindTask extends BaseTask {
+
+	@Autowired
+	private TaskRemoteService taskRemoteService;
+
+	@Override
+	public void execute() throws TaskException {
+		taskRemoteService.curWeekStudentTrainRemind();
+	}
+}

+ 2 - 2
mec-teacher/src/main/java/com/ym/mec/teacher/controller/SysMusicCompareRecordController.java

@@ -50,12 +50,12 @@ public class SysMusicCompareRecordController extends BaseController {
 
     @ApiOperation(value = "用户最后一次评测数据")
     @GetMapping("getLastEvaluationMusicalNotesPlayStats")
-    public HttpResponseResult getLastEvaluationMusicalNotesPlayStats(){
+    public HttpResponseResult getLastEvaluationMusicalNotesPlayStats(Long recordId){
         SysUser sysUser = sysUserFeignService.queryUserInfo();
         if(sysUser == null){
             throw new BizException("请登录");
         }
-        return succeed(sysMusicCompareRecordService.getLastEvaluationMusicalNotesPlayStats(sysUser.getId()));
+        return succeed(sysMusicCompareRecordService.getLastEvaluationMusicalNotesPlayStats(sysUser.getId(), recordId));
     }
 
 }

+ 9 - 0
mec-web/src/main/java/com/ym/mec/web/controller/TaskController.java

@@ -131,6 +131,9 @@ public class TaskController extends BaseController {
 	@Autowired
 	private MusicGroupSchoolTermCourseDetailService musicGroupSchoolTermCourseDetailService;
 
+	@Autowired
+	private SysMusicCompareRecordService sysMusicCompareRecordService;
+
 	@GetMapping(value = "/syncImHistoryMessageTask")
 	// 同步即时通讯聊天记录
 	public void syncImHistoryMessageTask(String date) throws Exception {
@@ -491,4 +494,10 @@ public class TaskController extends BaseController {
 	public void cleanStudentCloudStudySequenceDays(){
 		studentService.cleanStudentCloudStudySequenceDays();
 	}
+
+	@ApiOperation("本周学员训练提醒")
+	@GetMapping(value = "/curWeekStudentTrainRemind")
+	public void curWeekStudentTrainRemind(){
+		sysMusicCompareRecordService.curWeekStudentTrainRemind();
+	}
 }

+ 2 - 2
mec-web/src/main/java/com/ym/mec/web/controller/education/SysMusicCompareRecordController.java

@@ -50,12 +50,12 @@ public class SysMusicCompareRecordController extends BaseController {
 
     @ApiOperation(value = "用户最后一次评测数据")
     @GetMapping("getLastEvaluationMusicalNotesPlayStats")
-    public HttpResponseResult getLastEvaluationMusicalNotesPlayStats(){
+    public HttpResponseResult getLastEvaluationMusicalNotesPlayStats(Long recordId){
         SysUser sysUser = sysUserFeignService.queryUserInfo();
         if(sysUser == null){
             throw new BizException("请登录");
         }
-        return succeed(sysMusicCompareRecordService.getLastEvaluationMusicalNotesPlayStats(sysUser.getId()));
+        return succeed(sysMusicCompareRecordService.getLastEvaluationMusicalNotesPlayStats(sysUser.getId(), recordId));
     }
 
 }

+ 83 - 0
mec-websocket/pom.xml

@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<project
+		xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+		xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>com.ym</groupId>
+		<artifactId>mec</artifactId>
+		<version>1.0</version>
+	</parent>
+	<artifactId>mec-websocket</artifactId>
+	<name>mec-websocket</name>
+	<url>http://maven.apache.org</url>
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-security</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-sleuth-zipkin</artifactId>
+		</dependency>
+
+		<!-- swagger-spring-boot -->
+		<dependency>
+			<groupId>com.spring4all</groupId>
+			<artifactId>swagger-spring-boot-starter</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.alibaba</groupId>
+			<artifactId>druid-spring-boot-starter</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>mysql</groupId>
+			<artifactId>mysql-connector-java</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.ym</groupId>
+			<artifactId>mec-biz</artifactId>
+		</dependency>
+		
+		<dependency>
+			<groupId>com.yonge.log</groupId>
+			<artifactId>audit-log</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>com.github.whvcse</groupId>
+			<artifactId>easy-captcha</artifactId>
+			<version>1.6.2</version>
+		</dependency>
+
+	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-maven-plugin</artifactId>
+			</plugin>
+			<plugin>
+				<groupId>com.spotify</groupId>
+				<artifactId>docker-maven-plugin</artifactId>
+			</plugin>
+		</plugins>
+	</build>
+</project>

+ 49 - 0
mec-websocket/src/main/java/com/ym/mec/web/WebSocketApplication.java

@@ -0,0 +1,49 @@
+package com.ym.mec.web;
+
+import com.spring4all.swagger.EnableSwagger2Doc;
+import com.ym.mec.common.filters.EmojiEncodingFilter;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableAsync;
+
+import javax.servlet.Filter;
+
+@SpringBootApplication
+@EnableDiscoveryClient
+@EnableFeignClients("com.ym.mec")
+@MapperScan("com.ym.mec.biz.dal.dao")
+@ComponentScan(basePackages = {"com.ym.mec", "com.yonge.log"})
+@Configuration
+@EnableSwagger2Doc
+@EnableAsync
+public class WebSocketApplication {
+
+	public static void main(String[] args) {
+		SpringApplication.run(WebSocketApplication.class, args);
+	}
+
+	/**
+	 * 注册filter
+	 * @return
+	 */
+	@Bean
+	public FilterRegistrationBean<Filter> filterRegistrationBean() {
+		FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<Filter>();
+		// 注入过滤器
+		registration.setFilter(new EmojiEncodingFilter());
+		// 过滤器名称
+		registration.setName("emojiEncodingFilter");
+		// 拦截规则
+		registration.addUrlPatterns("/*");
+		// 过滤器顺序(值越小,优先级越高)
+		registration.setOrder(1);
+		return registration;
+	}
+}

+ 52 - 0
mec-websocket/src/main/java/com/ym/mec/web/config/PermissionCheckService.java

@@ -0,0 +1,52 @@
+package com.ym.mec.web.config;
+
+import java.util.Collection;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.stereotype.Component;
+
+import com.ym.mec.auth.api.client.SysUserFeignService;
+import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.common.security.SecurityUtils;
+
+@Component("pcs")
+public class PermissionCheckService {
+	
+	@Autowired
+	@Lazy
+	private SysUserFeignService sysUserFeignService;
+
+	public boolean hasPermissions(String... permissions) {
+		Authentication authentication = SecurityUtils.getAuthentication();
+		if (authentication == null) {
+			return false;
+		}
+
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if(user.getIsSuperAdmin()){
+			return true;
+		}
+
+		Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
+
+		for (String perm : permissions) {
+			for (GrantedAuthority authority : authorities) {
+				if (StringUtils.equalsIgnoreCase(perm, authority.getAuthority())) {
+					return true;
+				}
+			}
+		}
+
+		return false;
+	}
+
+	public boolean hasRoles(String... roles) {
+
+		return hasPermissions(roles);
+	}
+
+}

+ 44 - 0
mec-websocket/src/main/java/com/ym/mec/web/config/ResourceServerConfig.java

@@ -0,0 +1,44 @@
+package com.ym.mec.web.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
+import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
+
+import com.ym.mec.common.security.BaseAccessDeniedHandler;
+import com.ym.mec.common.security.BaseAuthenticationEntryPoint;
+
+@Configuration
+@EnableResourceServer
+@EnableGlobalMethodSecurity(prePostEnabled = true)
+public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
+
+    @Autowired
+    private BaseAccessDeniedHandler baseAccessDeniedHandler;
+
+    @Autowired
+    private BaseAuthenticationEntryPoint baseAuthenticationEntryPoint;
+
+    @Override
+    public void configure(HttpSecurity http) throws Exception {
+        http.csrf()
+                .disable()
+                .exceptionHandling()
+                .accessDeniedHandler(baseAccessDeniedHandler)
+                .authenticationEntryPoint(baseAuthenticationEntryPoint)
+                .and()
+                .authorizeRequests()
+                .antMatchers("/task/**")
+                .hasIpAddress("0.0.0.0/0")
+                .antMatchers("/v2/api-docs").permitAll().anyRequest().authenticated().and().httpBasic();
+    }
+
+    @Override
+    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
+        resources.authenticationEntryPoint(baseAuthenticationEntryPoint).accessDeniedHandler(baseAccessDeniedHandler);
+    }
+
+}

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

@@ -0,0 +1,48 @@
+package com.ym.mec.web.config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.format.FormatterRegistry;
+import org.springframework.http.MediaType;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import com.ym.mec.common.config.EnumConverterFactory;
+import com.ym.mec.common.config.LocalFastJsonHttpMessageConverter;
+import com.ym.mec.web.interceptor.OperationLogInterceptor;
+
+@Configuration
+public class WebMvcConfig implements WebMvcConfigurer {
+
+	@Autowired
+	private OperationLogInterceptor operationLogInterceptor;
+
+	/**
+	 * 枚举类的转换器 addConverterFactory
+	 */
+	@Override
+	public void addFormatters(FormatterRegistry registry) {
+		registry.addConverterFactory(new EnumConverterFactory());
+	}
+
+	@Override
+	public void addInterceptors(InterceptorRegistry registry) {
+
+		registry.addInterceptor(operationLogInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
+	}
+
+	@Bean
+	public HttpMessageConverters fastJsonHttpMessageConverters() {
+		LocalFastJsonHttpMessageConverter converter = new LocalFastJsonHttpMessageConverter();
+		List<MediaType> fastMediaTypes = new ArrayList<MediaType>();
+		fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
+		converter.setSupportedMediaTypes(fastMediaTypes);
+		return new HttpMessageConverters(converter);
+	}
+
+}

+ 41 - 0
mec-websocket/src/main/java/com/ym/mec/web/config/WebSocketConfig.java

@@ -0,0 +1,41 @@
+package com.ym.mec.web.config;
+
+import com.ym.mec.biz.handler.WebSocketHandler;
+import com.ym.mec.web.interceptor.WebSocketHandshakeInterceptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.config.annotation.EnableWebSocket;
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
+import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
+import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;
+
+/**
+ * @Author Joburgess
+ * @Date 2021/6/8 0008
+ */
+@Configuration
+@EnableWebSocket
+public class WebSocketConfig implements WebSocketConfigurer {
+
+    @Autowired
+    private WebSocketHandler webSocketHandler;
+    @Autowired
+    private WebSocketHandshakeInterceptor webSocketHandshakeInterceptor;
+
+    @Override
+    public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
+        webSocketHandlerRegistry.addHandler(webSocketHandler, "/audioEvaluate")
+                .addInterceptors(webSocketHandshakeInterceptor)
+                .setAllowedOrigins("*");
+    }
+
+    @Bean
+    public ServletServerContainerFactoryBean createWebSocketContainer() {
+        ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
+        container.setMaxTextMessageBufferSize(8192*4);
+        container.setMaxBinaryMessageBufferSize(8192*4);
+        return container;
+    }
+
+}

+ 61 - 0
mec-websocket/src/main/java/com/ym/mec/web/controller/WebsocketController.java

@@ -0,0 +1,61 @@
+package com.ym.mec.web.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.ym.mec.biz.dal.dto.MusicPitchDetailDto;
+import com.ym.mec.biz.handler.WebSocketHandler;
+import com.ym.mec.biz.service.SoundService;
+import com.ym.mec.common.controller.BaseController;
+import com.ym.mec.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.socket.TextMessage;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * @Author Joburgess
+ * @Date 2021/5/19 0019
+ */
+@Api(tags = "音频服务")
+@RequestMapping("ws")
+@RestController
+public class WebsocketController extends BaseController {
+
+    @ApiOperation(value = "获取在线人数")
+    @GetMapping("getOnlineUserNum")
+    public HttpResponseResult getOnlineUserNum(){
+        return succeed(WebSocketHandler.WS_CLIENTS.keySet());
+    }
+
+    @RequestMapping("sendToUser")
+    public HttpResponseResult sendToUser(String phone, String message) throws IOException {
+        if(!WebSocketHandler.WS_CLIENTS.containsKey(phone)){
+            return failed("未上线");
+        }
+        if(!WebSocketHandler.WS_CLIENTS.get(phone).getSession().isOpen()){
+            return failed("已离线");
+        }
+        WebSocketHandler.WS_CLIENTS.get(phone).getSession().sendMessage(new TextMessage(message));
+        return succeed();
+    }
+
+    @RequestMapping("closeWebSocket")
+    public HttpResponseResult closeWebSocket(String phone) throws IOException {
+        if(!WebSocketHandler.WS_CLIENTS.containsKey(phone)){
+            return failed("未上线");
+        }
+        if(!WebSocketHandler.WS_CLIENTS.get(phone).getSession().isOpen()){
+            return failed("已离线");
+        }
+        WebSocketHandler.WS_CLIENTS.get(phone).getSession().close();
+        return succeed();
+    }
+
+}

+ 33 - 0
mec-websocket/src/main/java/com/ym/mec/web/interceptor/OperationLogInterceptor.java

@@ -0,0 +1,33 @@
+package com.ym.mec.web.interceptor;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+
+import com.ym.mec.auth.api.client.SysUserFeignService;
+import com.ym.mec.auth.api.entity.SysUser;
+import com.yonge.log.interceptor.AuditLogInterceptor;
+
+@Component
+public class OperationLogInterceptor extends AuditLogInterceptor {
+
+	@Autowired
+	@Lazy
+	private SysUserFeignService sysUserFeignService;
+
+	@Override
+	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		if (sysUser != null) {
+			setUsername(sysUser.getRealName(),sysUser.getId());
+		}
+		return true;
+	}
+
+}

+ 28 - 0
mec-websocket/src/main/java/com/ym/mec/web/interceptor/WebSocketHandshakeInterceptor.java

@@ -0,0 +1,28 @@
+package com.ym.mec.web.interceptor;
+
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.stereotype.Component;
+import org.springframework.web.socket.WebSocketHandler;
+import org.springframework.web.socket.server.HandshakeInterceptor;
+
+import java.util.Map;
+
+/**
+ * @Author Joburgess
+ * @Date 2021/6/9 0009
+ */
+@Component
+public class WebSocketHandshakeInterceptor implements HandshakeInterceptor {
+
+    @Override
+    public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {
+        return true;
+    }
+
+    @Override
+    public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {
+
+    }
+
+}

+ 143 - 0
mec-websocket/src/main/resources/application.yml

@@ -0,0 +1,143 @@
+server:
+  port: 8005
+  connection-timeout: 60000
+  tomcat:
+    min-spare-threads: 50
+    max-threads: 500
+    accesslog:
+      enabled: true
+      buffered: true
+      directory: /var/logs
+      file-date-format: -yyyy-MM-dd
+      pattern: common
+      prefix: tomcat-websocket
+      rename-on-rotate: false
+      request-attributes-enabled: false
+      rotate: true
+      suffix: .log
+
+eureka:
+  client:
+    serviceUrl:
+      defaultZone: http://admin:admin123@localhost:8761/eureka/eureka/
+    instance:
+      lease-renewal-interval-in-seconds: 5
+      prefer-ip-address: true
+
+spring:
+  servlet:
+    multipart:
+      max-file-size: 150MB
+      max-request-size: 150MB
+  application:
+    name: websocket-server
+
+  data:
+    mongodb:
+      uri: mongodb://root:dayayuemeng2019@47.114.1.200:27017/mec_dev
+
+  datasource:
+    name: test
+    url: jdbc:mysql://rm-bp13774a2o87ti8c7mo.mysql.rds.aliyuncs.com:3306/mec_pro?useUnicode=true&characterEncoding=UTF8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
+    username: mec_pro
+    password: mec@Pro9
+    # 使用druid数据源
+    type: com.alibaba.druid.pool.DruidDataSource
+    druid:
+      connection-init-sqls: SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    filters: stat
+    maxActive: 50
+    initialSize: 10
+    maxWait: 60000
+    minIdle: 1
+    timeBetweenEvictionRunsMillis: 60000
+    minEvictableIdleTimeMillis: 300000
+    validationQuery: select 'x'
+    testWhileIdle: true
+    testOnBorrow: false
+    testOnReturn: false
+    poolPreparedStatements: true
+    maxOpenPreparedStatements: 20
+
+  redis:
+    host: 47.114.1.200
+    port: 6379
+    password: dyym
+    database: 1
+    #连接超时时间(毫秒)
+    timeout: 10000
+    jedis:
+      pool:
+        #连接池最大连接数(使用负值表示没有限制)
+        max-active: 20
+        #连接池最大阻塞等待时间(使用负值表示没有限制)
+        max-wait: 10000
+        #连接池中的最大空闲连接
+        max-idle: 10
+        #连接池中的最小空闲连接
+        min-idle: 5
+
+mybatis:
+  mapperLocations: classpath:config/mybatis/*.xml
+#  configuration:
+#    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+
+swagger:
+  base-package: com.ym.mec.web.controller
+
+##认证
+security:
+  oauth2:
+    client:
+      client-id: app
+      client-secret: app
+    resource:
+      token-info-uri: http://localhost:8001/oauth/check_token
+
+#spring boot admin 相关配置
+management:
+  endpoints:
+    web:
+      exposure:
+        include: "*"
+  endpoint:
+    health:
+      show-details: ALWAYS
+
+
+ribbon:
+  ReadTimeout: 600000
+  ConnectTimeout: 60000
+
+logging:
+  level:
+    com.ym.mec.auth.api.client.SysUserFeignService: INFO
+
+message:
+  debugMode: true
+
+##支付流水隐藏
+payment:
+  hiddenMode: false
+  #隐藏的支付方式
+  channel: YQPAY
+
+eseal:
+  tsign:
+    projectid: 4438776254
+    projectSecret: a94cf63d6361084d232f345d71321691
+    apisUrl: http://smlitsm.tsign.cn:8080/tgmonitor/rest/app!getAPIInfo2
+
+push:
+  jiguang:
+    reqURL: https://api.jpush.cn/v3/push
+    appKey:
+      student: 0e7422e1d6e73637e678716a
+      teacher: 7e0282ca92c12c8c45a93bb3
+      system: 496fc1007dea59b1b4252d2b
+    masterSecret:
+      student: c2361016604eab56ab2db2ac
+      teacher: d47430e2f4755ef5dc050ac5
+      system: a5e51e9cdb25417463afbf7a
+    apns_production: false

+ 16 - 0
mec-websocket/src/main/resources/bootstrap-dev.properties

@@ -0,0 +1,16 @@
+#\u6307\u5b9a\u5f00\u53d1\u73af\u5883
+#spring.profiles.active=dev
+#\u670d\u52a1\u5668\u5730\u5740
+spring.cloud.nacos.config.server-addr=47.114.1.200:8848
+#\u9ed8\u8ba4\u4e3aPublic\u547d\u540d\u7a7a\u95f4,\u53ef\u4ee5\u7701\u7565\u4e0d\u5199
+spring.cloud.nacos.config.namespace=a5c10b43-0c4d-4e3b-a0ad-9af651cfe89c
+#\u6307\u5b9a\u914d\u7f6e\u7fa4\u7ec4 --\u5982\u679c\u662fPublic\u547d\u540d\u7a7a\u95f4 \u5219\u53ef\u4ee5\u7701\u7565\u7fa4\u7ec4\u914d\u7f6e
+spring.cloud.nacos.config.group=DEFAULT_GROUP
+#\u6587\u4ef6\u540d -- \u5982\u679c\u6ca1\u6709\u914d\u7f6e\u5219\u9ed8\u8ba4\u4e3a ${spring.appliction.name}
+spring.cloud.nacos.config.prefix=websocket
+#\u6307\u5b9a\u6587\u4ef6\u540e\u7f00
+spring.cloud.nacos.config.file-extension=yaml
+#\u662f\u5426\u52a8\u6001\u5237\u65b0
+spring.cloud.nacos.config.refresh.enabled=true
+#\u662f\u5426\u542f\u7528nacos\u914d\u7f6e\u4e2d\u5fc3
+spring.cloud.nacos.config.enabled=true

+ 16 - 0
mec-websocket/src/main/resources/bootstrap-dev_server.properties

@@ -0,0 +1,16 @@
+#\u6307\u5b9a\u5f00\u53d1\u73af\u5883
+#spring.profiles.active=dev
+#\u670d\u52a1\u5668\u5730\u5740
+spring.cloud.nacos.config.server-addr=47.114.1.200:8848
+#\u9ed8\u8ba4\u4e3aPublic\u547d\u540d\u7a7a\u95f4,\u53ef\u4ee5\u7701\u7565\u4e0d\u5199
+spring.cloud.nacos.config.namespace=fd352683-69df-439a-802f-c44f0c21329c
+#\u6307\u5b9a\u914d\u7f6e\u7fa4\u7ec4 --\u5982\u679c\u662fPublic\u547d\u540d\u7a7a\u95f4 \u5219\u53ef\u4ee5\u7701\u7565\u7fa4\u7ec4\u914d\u7f6e
+spring.cloud.nacos.config.group=DEFAULT_GROUP
+#\u6587\u4ef6\u540d -- \u5982\u679c\u6ca1\u6709\u914d\u7f6e\u5219\u9ed8\u8ba4\u4e3a ${spring.appliction.name}
+spring.cloud.nacos.config.prefix=websocket
+#\u6307\u5b9a\u6587\u4ef6\u540e\u7f00
+spring.cloud.nacos.config.file-extension=yaml
+#\u662f\u5426\u52a8\u6001\u5237\u65b0
+spring.cloud.nacos.config.refresh.enabled=true
+#\u662f\u5426\u542f\u7528nacos\u914d\u7f6e\u4e2d\u5fc3
+spring.cloud.nacos.config.enabled=true

+ 16 - 0
mec-websocket/src/main/resources/bootstrap-prod.properties

@@ -0,0 +1,16 @@
+#\u6307\u5b9a\u5f00\u53d1\u73af\u5883
+#spring.profiles.active=dev
+#\u670d\u52a1\u5668\u5730\u5740
+spring.cloud.nacos.config.server-addr=47.96.80.97:8848
+#\u9ed8\u8ba4\u4e3aPublic\u547d\u540d\u7a7a\u95f4,\u53ef\u4ee5\u7701\u7565\u4e0d\u5199
+spring.cloud.nacos.config.namespace=f40a7594-4bd0-4bc6-8397-9353c6d2e63a
+#\u6307\u5b9a\u914d\u7f6e\u7fa4\u7ec4 --\u5982\u679c\u662fPublic\u547d\u540d\u7a7a\u95f4 \u5219\u53ef\u4ee5\u7701\u7565\u7fa4\u7ec4\u914d\u7f6e
+spring.cloud.nacos.config.group=DEFAULT_GROUP
+#\u6587\u4ef6\u540d -- \u5982\u679c\u6ca1\u6709\u914d\u7f6e\u5219\u9ed8\u8ba4\u4e3a ${spring.appliction.name}
+spring.cloud.nacos.config.prefix=websocket
+#\u6307\u5b9a\u6587\u4ef6\u540e\u7f00
+spring.cloud.nacos.config.file-extension=yaml
+#\u662f\u5426\u52a8\u6001\u5237\u65b0
+spring.cloud.nacos.config.refresh.enabled=true
+#\u662f\u5426\u542f\u7528nacos\u914d\u7f6e\u4e2d\u5fc3
+spring.cloud.nacos.config.enabled=true

+ 16 - 0
mec-websocket/src/main/resources/bootstrap-test.properties

@@ -0,0 +1,16 @@
+#\u6307\u5b9a\u5f00\u53d1\u73af\u5883
+#spring.profiles.active=dev
+#\u670d\u52a1\u5668\u5730\u5740
+spring.cloud.nacos.config.server-addr=47.114.1.200:8848
+#\u9ed8\u8ba4\u4e3aPublic\u547d\u540d\u7a7a\u95f4,\u53ef\u4ee5\u7701\u7565\u4e0d\u5199
+spring.cloud.nacos.config.namespace=46f06363-b9d6-46f0-9cd7-7b33dcf26bb0
+#\u6307\u5b9a\u914d\u7f6e\u7fa4\u7ec4 --\u5982\u679c\u662fPublic\u547d\u540d\u7a7a\u95f4 \u5219\u53ef\u4ee5\u7701\u7565\u7fa4\u7ec4\u914d\u7f6e
+spring.cloud.nacos.config.group=DEFAULT_GROUP
+#\u6587\u4ef6\u540d -- \u5982\u679c\u6ca1\u6709\u914d\u7f6e\u5219\u9ed8\u8ba4\u4e3a ${spring.appliction.name}
+spring.cloud.nacos.config.prefix=websocket
+#\u6307\u5b9a\u6587\u4ef6\u540e\u7f00
+spring.cloud.nacos.config.file-extension=yaml
+#\u662f\u5426\u52a8\u6001\u5237\u65b0
+spring.cloud.nacos.config.refresh.enabled=true
+#\u662f\u5426\u542f\u7528nacos\u914d\u7f6e\u4e2d\u5fc3
+spring.cloud.nacos.config.enabled=true

+ 83 - 0
mec-websocket/src/main/resources/logback-spring.xml

@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration scan="true" scanPeriod="10 seconds">
+
+	<property name="LOG_HOME" value="/mdata/logs/websocket-%d{yyyy-MM-dd_HH}-%i.log" />
+	<property name="CONSOLE_LOG_PATTERN"
+			  value="[%X{username} %X{ip} %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}] : %msg%n" />
+
+	<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
+		<encoder charset="UTF-8">
+			<pattern>${CONSOLE_LOG_PATTERN}</pattern>
+		</encoder>
+	</appender>
+
+	<appender name="file"
+			  class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+			<FileNamePattern>${LOG_HOME}</FileNamePattern>
+			<MaxHistory>90</MaxHistory>
+			<TimeBasedFileNamingAndTriggeringPolicy
+					class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+				<MaxFileSize>20MB</MaxFileSize>
+			</TimeBasedFileNamingAndTriggeringPolicy>
+		</rollingPolicy>
+
+		<encoder>
+			<pattern>${CONSOLE_LOG_PATTERN}</pattern>
+		</encoder>
+	</appender>
+
+	<appender name="messagefile"
+			  class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+			<FileNamePattern>/mdata/logs/web-message-%d{yyyy-MM-dd_HH}-%i.log</FileNamePattern>
+			<MaxHistory>90</MaxHistory>
+			<TimeBasedFileNamingAndTriggeringPolicy
+					class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+				<MaxFileSize>20MB</MaxFileSize>
+			</TimeBasedFileNamingAndTriggeringPolicy>
+		</rollingPolicy>
+
+		<encoder>
+			<pattern>${CONSOLE_LOG_PATTERN}</pattern>
+		</encoder>
+	</appender>
+
+	<logger name="com.ym.mec" level="INFO" />
+
+	<logger name="com.ym.mec.thirdparty" level="INFO"
+			additivity="false">
+		<appender-ref ref="messagefile" />
+	</logger>
+
+	<!--开发环境:打印控制台 -->
+	<springProfile name="dev">
+		<root level="WARN">
+			<appender-ref ref="stdout" />
+			<appender-ref ref="file" />
+		</root>
+	</springProfile>
+
+	<springProfile name="test">
+		<root level="WARN">
+			<appender-ref ref="stdout" />
+			<appender-ref ref="file" />
+		</root>
+	</springProfile>
+
+	<springProfile name="dev_server">
+		<root level="INFO">
+			<appender-ref ref="stdout" />
+			<appender-ref ref="file" />
+		</root>
+	</springProfile>
+
+	<!--生产环境:输出到文件 -->
+	<springProfile name="prod">
+		<root level="WARN">
+			<appender-ref ref="stdout" />
+			<appender-ref ref="file" />
+		</root>
+	</springProfile>
+
+</configuration>

+ 1 - 0
pom.xml

@@ -362,6 +362,7 @@
 		<module>mec-task</module>
 		<module>codegen</module>
 		<module>mec-web</module>
+		<module>mec-websocket</module>
 		<module>cms</module>
 		<module>mec-im</module>
 		<module>workflowy</module>