Explorar el Código

Merge remote-tracking branch 'origin/master'

周箭河 hace 5 años
padre
commit
11eb8e11a4
Se han modificado 57 ficheros con 1958 adiciones y 87 borrados
  1. 1 1
      edu-auth/edu-auth-server/src/main/java/com/keao/edu/auth/web/controller/SysMessageController.java
  2. 1 1
      edu-auth/edu-auth-server/src/main/java/com/keao/edu/auth/web/controller/TokenController.java
  3. 3 2
      edu-common/src/main/java/com/keao/edu/common/service/impl/SysMessageServiceImpl.java
  4. 0 8
      edu-im/edu-im-api/src/main/java/com/keao/edu/im/api/client/ImFeignService.java
  5. 2 6
      edu-im/edu-im-api/src/main/java/com/keao/edu/im/api/client/callback/ImFeignServiceFallback.java
  6. 11 11
      edu-im/edu-im-server/src/main/java/com/keao/edu/im/controller/RoomController.java
  7. 21 7
      edu-im/edu-im-server/src/main/java/com/keao/edu/im/mec/im/IMHelper.java
  8. 7 7
      edu-im/edu-im-server/src/main/java/com/keao/edu/im/service/Impl/RoomServiceImpl.java
  9. 2 2
      edu-im/edu-im-server/src/main/java/com/keao/edu/im/service/RoomService.java
  10. 48 0
      edu-user/edu-student-server/pom.xml
  11. 0 13
      edu-user/edu-student-server/src/main/java/com/keao/edu/App.java
  12. 25 0
      edu-user/edu-student-server/src/main/java/com/keao/edu/StudentServerApplication.java
  13. 49 0
      edu-user/edu-student-server/src/main/java/com/keao/edu/config/PermissionCheckService.java
  14. 39 0
      edu-user/edu-student-server/src/main/java/com/keao/edu/config/ResourceServerConfig.java
  15. 55 0
      edu-user/edu-student-server/src/main/java/com/keao/edu/config/WebMvcConfig.java
  16. 14 0
      edu-user/edu-student-server/src/main/java/com/keao/edu/config/WebSocketConfig.java
  17. 36 0
      edu-user/edu-student-server/src/main/java/com/keao/edu/controller/ExamCertificationController.java
  18. 34 0
      edu-user/edu-student-server/src/main/java/com/keao/edu/controller/ExamMusicTheoryController.java
  19. 171 0
      edu-user/edu-student-server/src/main/java/com/keao/edu/controller/ExamOrderController.java
  20. 128 0
      edu-user/edu-student-server/src/main/java/com/keao/edu/controller/ExamRegistrationController.java
  21. 43 0
      edu-user/edu-student-server/src/main/java/com/keao/edu/controller/ExamRoomStudentRelationController.java
  22. 34 0
      edu-user/edu-student-server/src/main/java/com/keao/edu/controller/ExamSongController.java
  23. 32 0
      edu-user/edu-student-server/src/main/java/com/keao/edu/controller/ExamSubjectController.java
  24. 50 0
      edu-user/edu-student-server/src/main/java/com/keao/edu/controller/ExamSubjectSongController.java
  25. 31 0
      edu-user/edu-student-server/src/main/java/com/keao/edu/controller/ExaminationBasicController.java
  26. 46 0
      edu-user/edu-student-server/src/main/java/com/keao/edu/controller/StudentController.java
  27. 30 0
      edu-user/edu-student-server/src/main/java/com/keao/edu/controller/SubjectController.java
  28. 30 0
      edu-user/edu-student-server/src/main/java/com/keao/edu/controller/SysSuggestionController.java
  29. 45 0
      edu-user/edu-student-server/src/main/java/com/keao/edu/controller/UploadFileController.java
  30. 120 0
      edu-user/edu-student-server/src/main/resources/application.yml
  31. 16 0
      edu-user/edu-student-server/src/main/resources/bootstrap-dev.properties
  32. 16 0
      edu-user/edu-student-server/src/main/resources/bootstrap-prod.properties
  33. 38 0
      edu-user/edu-student-server/src/main/resources/logback-spring.xml
  34. 48 0
      edu-user/edu-teacher-server/pom.xml
  35. 0 13
      edu-user/edu-teacher-server/src/main/java/com/keao/edu/App.java
  36. 29 0
      edu-user/edu-teacher-server/src/main/java/com/keao/edu/TeacherApplication.java
  37. 49 0
      edu-user/edu-teacher-server/src/main/java/com/keao/edu/config/PermissionCheckService.java
  38. 39 0
      edu-user/edu-teacher-server/src/main/java/com/keao/edu/config/ResourceServerConfig.java
  39. 55 0
      edu-user/edu-teacher-server/src/main/java/com/keao/edu/config/WebMvcConfig.java
  40. 14 0
      edu-user/edu-teacher-server/src/main/java/com/keao/edu/config/WebSocketConfig.java
  41. 32 0
      edu-user/edu-teacher-server/src/main/java/com/keao/edu/controller/EmployeeController.java
  42. 27 0
      edu-user/edu-teacher-server/src/main/java/com/keao/edu/controller/ExamCertificationController.java
  43. 51 0
      edu-user/edu-teacher-server/src/main/java/com/keao/edu/controller/ExamReviewController.java
  44. 66 0
      edu-user/edu-teacher-server/src/main/java/com/keao/edu/controller/ExamRoomController.java
  45. 47 0
      edu-user/edu-teacher-server/src/main/java/com/keao/edu/controller/ExamRoomStudentRelationController.java
  46. 50 0
      edu-user/edu-teacher-server/src/main/java/com/keao/edu/controller/StudentExamResultController.java
  47. 36 0
      edu-user/edu-teacher-server/src/main/java/com/keao/edu/controller/TenantInfoController.java
  48. 120 0
      edu-user/edu-teacher-server/src/main/resources/application.yml
  49. 16 0
      edu-user/edu-teacher-server/src/main/resources/bootstrap-dev.properties
  50. 16 0
      edu-user/edu-teacher-server/src/main/resources/bootstrap-prod.properties
  51. 38 0
      edu-user/edu-teacher-server/src/main/resources/logback-spring.xml
  52. 18 0
      edu-user/edu-user-biz/src/main/java/com/keao/edu/user/dao/StudentExamResultDao.java
  53. 5 2
      edu-user/edu-user-biz/src/main/java/com/keao/edu/user/service/impl/ExaminationBasicServiceImpl.java
  54. 9 10
      edu-user/edu-user-biz/src/main/java/com/keao/edu/user/service/impl/StudentExamResultServiceImpl.java
  55. 2 2
      edu-user/edu-user-biz/src/main/resources/config/mybatis/ExamCertificationMapper.xml
  56. 6 0
      edu-user/edu-user-biz/src/main/resources/config/mybatis/StudentExamResultMapper.xml
  57. 7 2
      edu-zuul/src/main/resources/application.yml

+ 1 - 1
edu-auth/edu-auth-server/src/main/java/com/keao/edu/auth/web/controller/SysMessageController.java

@@ -90,7 +90,7 @@ public class SysMessageController extends BaseController {
         if(!sysUser.getIsSuperAdmin()){
             queryInfo.setUserId(sysUser.getId());
         }
-        queryInfo.setType(MessageSendMode.SEO.getCode());
+        queryInfo.setType(MessageSendMode.PUSH.getCode());
         PageInfo<SysMessage> pageInfo = sysMessageService.queryPage(queryInfo);
         return succeed(pageInfo);
     }

+ 1 - 1
edu-auth/edu-auth-server/src/main/java/com/keao/edu/auth/web/controller/TokenController.java

@@ -127,7 +127,7 @@ public class TokenController extends BaseController {
 		return succeed(objectMapper.readValue(resp.getBody(), Map.class));
 	}
 
-	@PostMapping(value = "exit",consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
+	@PostMapping(value = "exit")
 	@ApiOperation(value = "退出登录")
 	public HttpResponseResult logout(@RequestHeader(value = HttpHeaders.AUTHORIZATION) String authHeader) {
 		if (StringUtils.isBlank(authHeader)) {

+ 3 - 2
edu-common/src/main/java/com/keao/edu/common/service/impl/SysMessageServiceImpl.java

@@ -15,6 +15,7 @@ import com.keao.edu.common.service.SysMessageConfigService;
 import com.keao.edu.common.service.SysMessageService;
 import com.keao.edu.thirdparty.message.MessageSenderPlugin;
 import com.keao.edu.thirdparty.message.MessageSenderPluginContext;
+import com.keao.edu.thirdparty.message.SendMode;
 import com.keao.edu.thirdparty.message.provider.YimeiSmsPlugin;
 import com.keao.edu.util.string.MessageFormatter;
 
@@ -240,9 +241,9 @@ public class SysMessageServiceImpl extends BaseServiceImpl<Long, SysMessage> imp
 		}
 		MessageSenderPlugin senderPlugin = messageSenderPluginContext.getMessageSenderPlugin(jpushType);
 		MessageSendMode mode = MessageSendMode.SMS;
-		if (senderPlugin.getSendMode().equals("PUSH")) {
+		if (senderPlugin.getSendMode().name().equals("PUSH")) {
 			mode = MessageSendMode.PUSH;
-		} else if (senderPlugin.getSendMode().equals("EMAIL")) {
+		} else if (senderPlugin.getSendMode().name().equals("EMAIL")) {
 			mode = MessageSendMode.EMAIL;
 		}
 		addMessage(receivers, messageConfig.getDescription(), MessageFormatter.arrayFormat(messageConfig.getContent(), args), triggerTime, mode, status, errorMsg, readStatus,

+ 0 - 8
edu-im/edu-im-api/src/main/java/com/keao/edu/im/api/client/ImFeignService.java

@@ -97,14 +97,6 @@ public interface ImFeignService {
 	Object privateSend(@RequestBody ImPrivateMessage privateMessage);
 
 	/**
-	 * 退出教室
-	 * @param reqUserData
-	 * @return
-	 */
-	@PostMapping(value = "room/leave")
-	void leaveRoom(@RequestBody ReqUserData reqUserData);
-
-	/**
 	 * 踢出教室
 	 * @param reqUserData
 	 * @return

+ 2 - 6
edu-im/edu-im-api/src/main/java/com/keao/edu/im/api/client/callback/ImFeignServiceFallback.java

@@ -1,11 +1,10 @@
 package com.keao.edu.im.api.client.callback;
 
-import java.util.List;
-
+import com.keao.edu.im.api.client.ImFeignService;
 import com.keao.edu.im.api.entity.*;
 import org.springframework.stereotype.Component;
 
-import com.keao.edu.im.api.client.ImFeignService;
+import java.util.List;
 
 @Component
 public class ImFeignServiceFallback implements ImFeignService {
@@ -61,9 +60,6 @@ public class ImFeignServiceFallback implements ImFeignService {
     }
 
     @Override
-    public void leaveRoom(ReqUserData reqUserData) {}
-
-    @Override
     public void kickRoom(ReqUserData reqUserData) {
 
     }

+ 11 - 11
edu-im/edu-im-server/src/main/java/com/keao/edu/im/controller/RoomController.java

@@ -75,7 +75,7 @@ public class RoomController{
     @RequestMapping(value = "/leave", method = RequestMethod.POST)
     public Object leaveRoom(@RequestBody ReqUserData data)
             throws ApiException, Exception {
-        boolean result = roomService.leaveRoom(data.getRegistrationId(),data.getUserId(),data.getRoomId());
+        boolean result = roomService.leaveRoom(data.getRegistrationId(),data.getRoomId());
         return new BaseResponse<>(result);
     }
 
@@ -89,20 +89,20 @@ public class RoomController{
     public Object statusSync(@RequestBody String body) throws Exception {
         ChannelStateNotify notify = JSONObject.parseObject(body, ChannelStateNotify.class);
         log.info("statusSyncParam: {}",JSONObject.toJSON(notify));
-        String extra = notify.getExtra();
-//        boolean result = false;
+
         if(notify.getEvent() == 1){
-            /*if(StringUtils.isEmpty(extra)){
-                roomService.configRecord(notify.getChannelId(),notify.getUserId());
-            }else {
-                roomService.startRecord(notify.getChannelId(),notify.getUserId());
-            }*/
+            //同步房间信息
         }else if(notify.getEvent() == 2){
-
+            //房间创建
         }else if(notify.getEvent() == 3){
-
+            //房间销毁
         }else if(notify.getEvent() == 11){
-
+            //成员加入
+        }else if(notify.getEvent() == 12){
+            //成员退出
+            roomService.leaveRoom(null,notify.getChannelId());
+        }else if(notify.getEvent() == 20){
+            //资源发生变动
         }
         return new BaseResponse<>();
     }

+ 21 - 7
edu-im/edu-im-server/src/main/java/com/keao/edu/im/mec/im/IMHelper.java

@@ -238,7 +238,7 @@ public class IMHelper {
      * @throws Exception
      */
     @Async
-    public IMApiResultInfo startRecord(String roomId, Long registrationId, List<RoomMember> roomMembers) throws Exception {
+    public IMApiResultInfo startRecord(String hostUserId, String roomId, Long registrationId, List<RoomMember> roomMembers) throws Exception {
         if (roomId == null) {
             throw new IllegalArgumentException("Paramer 'roomId' is required");
         }
@@ -247,7 +247,21 @@ public class IMHelper {
         jsonObject.put("videoFormat","mp4");
         jsonObject.put("audioFormat","mp3");
         jsonObject.put("videoResolution","640x480");
-        jsonObject.put("mixLayout",1);
+        jsonObject.put("mixLayout",3);
+        jsonObject.put("sliceMin",60);
+        jsonObject.put("hostUserId",hostUserId);
+        JSONObject json = new JSONObject();
+        json.put("sessionId",roomQuery(roomId));
+        json.put("config",jsonObject);
+
+
+
+        /*JSONObject jsonObject = new JSONObject();
+        jsonObject.put("mode",3);
+        jsonObject.put("videoFormat","mp4");
+        jsonObject.put("audioFormat","mp3");
+        jsonObject.put("videoResolution","640x480");
+        jsonObject.put("mixLayout",2);
         jsonObject.put("sliceMin",30);
         jsonObject.put("renderMode",1);
         jsonObject.put("hostUserId","");
@@ -277,7 +291,7 @@ public class IMHelper {
         }
         JSONObject jsonObject1 = new JSONObject();
         jsonObject1.put("video",jsonArray);
-        jsonObject.put("input",jsonObject1);
+        jsonObject.put("input",jsonObject1);*/
 
 
         json.put("sessionId",roomQuery(roomId));
@@ -360,7 +374,7 @@ public class IMHelper {
      * @return
      * @throws Exception
      */
-    public IMApiResultInfo stopRecord(String roomId) throws Exception {
+    public IMApiResultInfo stopRecord(String hostUserId, String roomId) throws Exception {
         if (roomId == null) {
             throw new IllegalArgumentException("Paramer 'roomId' is required");
         }
@@ -368,17 +382,17 @@ public class IMHelper {
 //        if (hostUserId == null) {
 //            throw new IllegalArgumentException("Paramer 'groupId' is required");
 //        }
-        /*JSONObject jsonObject = new JSONObject();
+        JSONObject jsonObject = new JSONObject();
         jsonObject.put("mode",3);
         jsonObject.put("videoFormat","mp4");
         jsonObject.put("audioFormat","mp3");
         jsonObject.put("videoResolution","640x480");
         jsonObject.put("mixLayout",2);
         jsonObject.put("sliceMin",30);
-        jsonObject.put("hostUserId",hostUserId);*/
+        jsonObject.put("hostUserId",hostUserId);
         JSONObject json = new JSONObject();
         json.put("sessionId",roomQuery(roomId));
-//        json.put("config",jsonObject);
+        json.put("config",jsonObject);
 
         String body = json.toJSONString();
 

+ 7 - 7
edu-im/edu-im-server/src/main/java/com/keao/edu/im/service/Impl/RoomServiceImpl.java

@@ -109,9 +109,9 @@ public class RoomServiceImpl implements RoomService {
     }
 
     @Override
-    public void stopRecord(String roomId) throws Exception {
+    public void stopRecord(String userId,String roomId) throws Exception {
 //        SysUser sysUser = sysUserFeignService.queryUserInfo();
-        imHelper.stopRecord(roomId);
+        imHelper.stopRecord(userId,roomId);
     }
 
     @Override
@@ -368,7 +368,7 @@ public class RoomServiceImpl implements RoomService {
             }
             this.publishMessage(eduUserFeignService.getPublishMessage(registrationId));
             eduUserFeignService.upsetStudentAttendance(registrationId,0);
-//            imHelper.startRecord(roomId, registrationId,roomMembers);
+            imHelper.startRecord(userId,roomId, registrationId,roomMembers);
 //            eduUserFeignService.updateSessionId(registrationId,imApiResultInfo.getSessionId());
         }else {
             eduUserFeignService.upsetTeacherAttendance(examRoom.getId(),sysUser.getId(),0);
@@ -407,7 +407,7 @@ public class RoomServiceImpl implements RoomService {
 
     @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
     @Override
-    public Boolean leaveRoom(Long registrationId,String userId,String roomId) throws Exception {
+    public Boolean leaveRoom(Long registrationId,String roomId) throws Exception {
         if(registrationId != null){
             StudentExamResultApiDto examResult = eduUserFeignService.getExamResult(registrationId);
             /*Integer recordFlag = examResult.getRecordFlag();
@@ -418,7 +418,7 @@ public class RoomServiceImpl implements RoomService {
         }
 
         SysUser user = sysUserFeignService.queryUserInfo();
-        userId = user.getId().toString();
+        String userId = user.getId().toString();
         /*if(StringUtils.isEmpty(userId)){
             user = sysUserFeignService.queryUserInfo();
             userId = user.getId().toString();
@@ -692,7 +692,7 @@ public class RoomServiceImpl implements RoomService {
                 if("3".equals(e.getRid())){
                     try {
                         eduUserFeignService.upsetStudentAttendance(e.getExamRegistrationId(),1);
-                        imHelper.stopRecord(e.getRid());
+                        imHelper.stopRecord(e.getUid(),e.getRid());
                     } catch (Exception e1) {
                         e1.printStackTrace();
                     }
@@ -730,7 +730,7 @@ public class RoomServiceImpl implements RoomService {
             if("recorded".equals(data.getType())){
                 msg.setRoomId("recorded" + roomId);
             }*/
-            imHelper.stopRecord(roomId);
+            imHelper.stopRecord(userId,roomId);
             IMApiResultInfo apiResultInfo = imHelper.publishMessage(userId, roomId, msg, 1);
             if (!apiResultInfo.isSuccess()) {
                 throw new ApiException(ErrorEnum.ERR_MESSAGE_ERROR);

+ 2 - 2
edu-im/edu-im-server/src/main/java/com/keao/edu/im/service/RoomService.java

@@ -23,9 +23,9 @@ public interface RoomService {
 
     void startRecord(String roomId,String userId) throws Exception;
 
-    void stopRecord(String roomId) throws Exception;
+    void stopRecord(String userId,String roomId) throws Exception;
 
-    public Boolean leaveRoom(Long registrationId,String userId,String roomId) throws ApiException, Exception;
+    public Boolean leaveRoom(Long registrationId,String roomId) throws ApiException, Exception;
 
     //only host
     public Boolean downgrade(String roomId, List<ReqChangeUserRoleData.ChangedUser> users) throws ApiException, Exception;

+ 48 - 0
edu-user/edu-student-server/pom.xml

@@ -22,5 +22,53 @@
       <version>3.8.1</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.springframework.cloud</groupId>
+      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-websocket</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.springframework.cloud</groupId>
+      <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-web</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.cloud</groupId>
+      <artifactId>spring-cloud-openfeign-core</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.spring4all</groupId>
+      <artifactId>swagger-spring-boot-starter</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.keao.edu</groupId>
+      <artifactId>edu-user-biz</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>javax.servlet-api</artifactId>
+    </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>

+ 0 - 13
edu-user/edu-student-server/src/main/java/com/keao/edu/App.java

@@ -1,13 +0,0 @@
-package com.keao.edu;
-
-/**
- * Hello world!
- *
- */
-public class App 
-{
-    public static void main( String[] args )
-    {
-        System.out.println( "Hello World!" );
-    }
-}

+ 25 - 0
edu-user/edu-student-server/src/main/java/com/keao/edu/StudentServerApplication.java

@@ -0,0 +1,25 @@
+package com.keao.edu;
+
+import com.spring4all.swagger.EnableSwagger2Doc;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableAsync;
+
+@SpringBootApplication
+@EnableDiscoveryClient
+@EnableFeignClients({"com.keao.edu"})
+@MapperScan({"com.keao.edu.user.dao", "com.keao.edu.common.dao"})
+@Configuration
+@EnableSwagger2Doc
+@EnableAsync
+public class StudentServerApplication{
+
+    public static void main(String[] args) {
+        SpringApplication.run(StudentServerApplication.class, args);
+    }
+
+}

+ 49 - 0
edu-user/edu-student-server/src/main/java/com/keao/edu/config/PermissionCheckService.java

@@ -0,0 +1,49 @@
+package com.keao.edu.config;
+
+import com.keao.edu.auth.api.client.SysUserFeignService;
+import com.keao.edu.auth.api.entity.SysUser;
+import com.keao.edu.auth.api.util.SecurityUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.stereotype.Component;
+
+import java.util.Collection;
+
+@Component("pcs")
+public class PermissionCheckService {
+
+	@Autowired
+	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);
+	}
+
+}

+ 39 - 0
edu-user/edu-student-server/src/main/java/com/keao/edu/config/ResourceServerConfig.java

@@ -0,0 +1,39 @@
+package com.keao.edu.config;
+
+import com.keao.edu.common.security.BaseAccessDeniedHandler;
+import com.keao.edu.common.security.BaseAuthenticationEntryPoint;
+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;
+
+@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.authorizeRequests()
+                .antMatchers("/task/*","/v2/api-docs", "/su/**", "/student/apply", "/examRegistration/ocr", "/examOrder/paymentResult",
+                        "/examOrder/notify","/examinationBasic/getInfo","/examOrder/executePayment","/examOrder/pageList","/studentExamResult/recordSync")
+                .permitAll()
+                .anyRequest().authenticated().and().csrf().disable().exceptionHandling().accessDeniedHandler(baseAccessDeniedHandler)
+                .authenticationEntryPoint(baseAuthenticationEntryPoint).and();
+    }
+
+    @Override
+    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
+        resources.authenticationEntryPoint(baseAuthenticationEntryPoint).accessDeniedHandler(baseAccessDeniedHandler);
+    }
+
+}

+ 55 - 0
edu-user/edu-student-server/src/main/java/com/keao/edu/config/WebMvcConfig.java

@@ -0,0 +1,55 @@
+package com.keao.edu.config;
+
+import com.keao.edu.common.config.EnumConverterFactory;
+import com.keao.edu.common.config.LocalFastJsonHttpMessageConverter;
+import com.keao.edu.common.tenant.TenantInterceptor;
+import com.keao.edu.datasource.interceptor.DataSourceInterceptor;
+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 java.util.ArrayList;
+import java.util.List;
+
+@Configuration
+public class WebMvcConfig implements WebMvcConfigurer {
+
+	/**
+	 * 枚举类的转换器 addConverterFactory
+	 */
+	@Override
+	public void addFormatters(FormatterRegistry registry) {
+		registry.addConverterFactory(new EnumConverterFactory());
+	}
+
+	@Override
+	public void addInterceptors(InterceptorRegistry registry) {
+
+		registry.addInterceptor(getDataSrouceInterceptor()).addPathPatterns("/**");
+		registry.addInterceptor(getTenantInterceptor()).addPathPatterns("/**");
+	}
+
+	@Bean
+	public DataSourceInterceptor getDataSrouceInterceptor() {
+		return new DataSourceInterceptor();
+	}
+
+	@Bean
+	public TenantInterceptor getTenantInterceptor() {
+		return new TenantInterceptor();
+	}
+	
+	@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);
+    }
+
+}

+ 14 - 0
edu-user/edu-student-server/src/main/java/com/keao/edu/config/WebSocketConfig.java

@@ -0,0 +1,14 @@
+package com.keao.edu.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+@Configuration
+public class WebSocketConfig {
+
+    @Bean
+    public ServerEndpointExporter serverEndpointExporter () {
+        return new ServerEndpointExporter();
+    }
+}

+ 36 - 0
edu-user/edu-student-server/src/main/java/com/keao/edu/controller/ExamCertificationController.java

@@ -0,0 +1,36 @@
+package com.keao.edu.controller;
+
+import com.keao.edu.common.controller.BaseController;
+import com.keao.edu.common.entity.HttpResponseResult;
+import com.keao.edu.user.dto.ExamCertificationDto;
+import com.keao.edu.user.dto.NeedCheckingDetailDto;
+import com.keao.edu.user.service.ExamCertificationService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+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.util.List;
+
+@RestController
+@RequestMapping("examCertification")
+@Api(tags = "准考证服务")
+public class ExamCertificationController extends BaseController {
+
+    @Autowired
+    private ExamCertificationService examCertificationService;
+
+    @ApiOperation("学生端获取学员准考证列表")
+    @GetMapping(value = "queryCertificationPage")
+    public HttpResponseResult<List<ExamCertificationDto>> queryCertification(Long examRegistrationId) {
+        return succeed(examCertificationService.queryCertificationPage(examRegistrationId));
+    }
+
+    @ApiOperation("学生端待考详情")
+    @GetMapping(value = "needCheckingDetail")
+    public HttpResponseResult<NeedCheckingDetailDto> needCheckingDetail(Long examRegistrationId) {
+        return succeed(examCertificationService.needCheckingDetail(examRegistrationId));
+    }
+}

+ 34 - 0
edu-user/edu-student-server/src/main/java/com/keao/edu/controller/ExamMusicTheoryController.java

@@ -0,0 +1,34 @@
+package com.keao.edu.controller;
+
+import com.keao.edu.common.controller.BaseController;
+import com.keao.edu.common.entity.HttpResponseResult;
+import com.keao.edu.user.entity.ExamMusicTheory;
+import com.keao.edu.user.service.ExamMusicTheoryService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+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.util.List;
+
+/**
+ * @Author Joburgess
+ * @Date 2020.07.01
+ */
+@RestController
+@RequestMapping("examMusicTheory")
+@Api(tags = "考级乐理")
+public class ExamMusicTheoryController extends BaseController {
+
+    @Autowired
+    private ExamMusicTheoryService examMusicTheoryService;
+
+    @ApiOperation("获取项目乐理级别列表")
+    @GetMapping(value = "/getTheoryLevelList")
+    public HttpResponseResult<List<ExamMusicTheory>> getTheoryLevelList(Integer examId) {
+        return succeed(examMusicTheoryService.getTheoryLevelList(examId));
+    }
+
+}

+ 171 - 0
edu-user/edu-student-server/src/main/java/com/keao/edu/controller/ExamOrderController.java

@@ -0,0 +1,171 @@
+package com.keao.edu.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.keao.edu.auth.api.client.SysUserFeignService;
+import com.keao.edu.auth.api.entity.SysUser;
+import com.keao.edu.common.controller.BaseController;
+import com.keao.edu.common.entity.HttpResponseResult;
+import com.keao.edu.thirdparty.adapay.ConfigInit;
+import com.keao.edu.thirdparty.adapay.Payment;
+import com.keao.edu.user.dto.ExamPaymentInfo;
+import com.keao.edu.user.entity.ExamRegistrationPayment;
+import com.keao.edu.user.service.ExamRegistrationPaymentService;
+import com.keao.edu.util.date.DateUtil;
+import com.keao.edu.util.http.HttpUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.DigestUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+
+@RestController
+@Api(tags = "报名订单服务")
+@RequestMapping(value = "examOrder")
+public class ExamOrderController extends BaseController {
+
+    @Autowired
+    private ExamRegistrationPaymentService examRegistrationPaymentService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @ApiOperation("获取用户项目未支付的订单")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "examinationBasicId", value = "项目id", required = true, dataType = "Integer")})
+    @GetMapping(value = "/getExamIngOrder")
+    public HttpResponseResult<ExamRegistrationPayment> getExamIngOrder(Long examinationBasicId) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        return succeed(examRegistrationPaymentService.getExamIngOrder(examinationBasicId, sysUser.getId()));
+    }
+
+    @ApiOperation(value = "台牌支付")
+    @PostMapping("/executePayment")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "amount", value = "支付金额", required = true, dataType = "BigDecimal"),
+            @ApiImplicitParam(name = "orderNo", value = "订单号", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "payChannel", value = "支付方式", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "returnUrl", value = "返回页面", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "orderSubject", value = "订单标题", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "orderBody", value = "订单内容", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "sign", value = "sign", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "code", value = "code", required = true, dataType = "String")
+    })
+    public Object executePayment(BigDecimal amount, String orderNo, String payChannel, String returnUrl,String notifyUrl, String orderSubject, String orderBody, String sign, String code, String platform) throws Exception {
+        Map<String, Object> signParams = new LinkedHashMap<>();
+        signParams.put("appId", ConfigInit.appId);
+        signParams.put("amount", amount);
+        signParams.put("orderNo", orderNo);
+        signParams.put("notifyUrl", notifyUrl);
+        signParams.put("returnUrl", returnUrl);
+        signParams.put("orderSubject", orderSubject);
+        signParams.put("orderBody", orderBody);
+        signParams.put("wxAppId", ConfigInit.wxAppId);
+
+        String originalStr = JSONObject.toJSONString(signParams);
+        String newSign = DigestUtils.md5DigestAsHex(originalStr.getBytes());
+        if(sign != newSign){
+            return failed("请勿非法请求");
+        }
+
+        String openId = "";
+        if (payChannel.equals("wx_pub")) {
+            if (code == null || code.isEmpty()) {
+                return failed("微信支付请先授权");
+            }
+            String wxMpOAuth2AccessTokenUrl = String.format(ConfigInit.wxMpOAuth2AccessTokenUrl, ConfigInit.wxAppId, ConfigInit.wxAppSecret, code);
+            Map<String, String> weChatRes = JSON.parseObject(HttpUtil.get(wxMpOAuth2AccessTokenUrl, new HashMap<>()), Map.class);
+            if (!weChatRes.containsKey("openid")) {
+                return failed("授权失败,请重新授权");
+            }
+            openId = weChatRes.get("openid");
+        }
+
+        ExamRegistrationPayment examRegistrationPayment = examRegistrationPaymentService.getByOrderNo(orderNo);
+
+        if (examRegistrationPayment == null) {
+            return failed("订单不存在,请勿非法请求");
+        }
+        String merNos = examRegistrationPayment.getMerNo();
+        Date createTime = examRegistrationPayment.getCreateTime();
+        Calendar beforeTime = Calendar.getInstance();
+        beforeTime.add(Calendar.MINUTE, -28);// 28 分钟之前的时间
+        Date beforeDate = beforeTime.getTime();
+        if (createTime.before(beforeDate)) {
+            return failed("订单已超时,请重新下单");
+        }
+        amount = examRegistrationPayment.getTransAmount().setScale(2,BigDecimal.ROUND_HALF_UP);
+
+        Date expireDate = DateUtil.addMinutes(createTime, 30);
+        String timeExpire = new SimpleDateFormat("yyyyMMddHHmmss").format(expireDate);
+
+        Map<String, Object> paymentParams = new HashMap<>();
+        paymentParams.put("app_id", ConfigInit.appId);
+        paymentParams.put("order_no", orderNo);
+        paymentParams.put("pay_channel", payChannel);
+        paymentParams.put("pay_amt", amount);
+        paymentParams.put("goods_title", orderSubject);
+        paymentParams.put("goods_desc", orderBody);
+        paymentParams.put("time_expire", timeExpire);
+
+        if (!merNos.equals(ConfigInit.merNo)) {
+            List<Map<String, Object>> divMembers = new ArrayList<>();
+            Map<String, Object> divMember = new HashMap<>();
+            divMember.put("member_id", merNos);//分佣账户
+            divMember.put("amount", amount);//分佣金额
+            divMember.put("fee_flag", "Y"); //承担手续费
+            divMembers.add(divMember);
+            paymentParams.put("div_members", JSON.toJSONString(divMembers));
+        }
+
+        Map<String, Object> expendParams = new HashMap<>(5);
+        expendParams.put("open_id", openId);
+        expendParams.put("is_raw", "1");
+        expendParams.put("callback_url", returnUrl);
+        expendParams.put("limit_pay", "1");
+        paymentParams.put("expend", expendParams);
+
+        Map<String, Object> payment = Payment.executePayment(paymentParams);
+
+        examRegistrationPayment.setTransNo((String) payment.get("id"));
+        examRegistrationPaymentService.update(examRegistrationPayment);
+        return succeed(payment);
+    }
+
+
+    @ApiOperation(value = "获取订单状态及订单信息")
+    @GetMapping(value = "/paymentResult")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "orderNo", value = "订单编号", required = true, dataType = "String")})
+    public HttpResponseResult<ExamPaymentInfo> getExamOrderInfo(String orderNo) {
+        return succeed(examRegistrationPaymentService.getExamOrderInfo(orderNo));
+    }
+
+    @PostMapping(value = "orderSuccess")
+    public HttpResponseResult orderSuccess(String orderNo){
+        Map<String, String> notifyMap = new HashMap<>();
+        notifyMap.put("channelType", "Alipay");
+        notifyMap.put("memo", "手动回调");
+        notifyMap.put("transStatus", "SUCCESS");
+        notifyMap.put("orderNo", orderNo);
+        notifyMap.put("transNo", UUID.randomUUID().toString());
+        examRegistrationPaymentService.updateOrder(notifyMap);
+        return succeed();
+    }
+
+    @ApiOperation(value = "关闭订单")
+    @PostMapping("/closeOrder")
+    public HttpResponseResult closeOrder(String orderNo){
+        return succeed(examRegistrationPaymentService.closeOrder(orderNo));
+    }
+
+}

+ 128 - 0
edu-user/edu-student-server/src/main/java/com/keao/edu/controller/ExamRegistrationController.java

@@ -0,0 +1,128 @@
+package com.keao.edu.controller;
+
+import com.keao.edu.auth.api.client.SysUserFeignService;
+import com.keao.edu.auth.api.entity.SysUser;
+import com.keao.edu.common.controller.BaseController;
+import com.keao.edu.common.entity.HttpResponseResult;
+import com.keao.edu.common.page.PageInfo;
+import com.keao.edu.common.page.QueryInfo;
+import com.keao.edu.thirdparty.ocr.Ocr;
+import com.keao.edu.user.dto.ExamRegistrationDto;
+import com.keao.edu.user.dto.ExamRegistrationStatisticsDto;
+import com.keao.edu.user.dto.StudentBaseExamsDto;
+import com.keao.edu.user.dto.StudentExamListDto;
+import com.keao.edu.user.entity.Employee;
+import com.keao.edu.user.entity.ExamRegistration;
+import com.keao.edu.user.page.ApplyListQueryInfo;
+import com.keao.edu.user.page.ExamRecordQueryInfo;
+import com.keao.edu.user.service.EmployeeService;
+import com.keao.edu.user.service.ExamRegistrationService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.Objects;
+
+/**
+ * @Author Joburgess
+ * @Date 2020.06.23
+ */
+@RestController
+@Api(tags = "学员报名服务")
+@RequestMapping(value = "examRegistration")
+public class ExamRegistrationController extends BaseController {
+
+    @Autowired
+    private ExamRegistrationService examRegistrationService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private EmployeeService employeeService;
+
+    @ApiOperation(value = "学生端学员报名记录查询")
+    @GetMapping(value = "applyList")
+    public HttpResponseResult<PageInfo<ExamRegistrationDto>> applyList(ApplyListQueryInfo queryInfo) {
+        return succeed(examRegistrationService.applyList(queryInfo));
+    }
+
+    @ApiOperation(value = "学生端考级曲库考试列表")
+    @GetMapping(value = "studentBaseExams")
+    public HttpResponseResult<PageInfo<StudentBaseExamsDto>> studentBaseExams(QueryInfo queryInfo) {
+        return succeed(examRegistrationService.studentBaseExams(queryInfo));
+    }
+
+    @ApiOperation(value = "学生端获取学员考试记录")
+    @GetMapping(value = "examList")
+    public HttpResponseResult<PageInfo<StudentExamListDto>> examList(ExamRecordQueryInfo queryInfo) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        queryInfo.setStudentId(sysUser.getId());
+        return succeed(examRegistrationService.examList(queryInfo));
+    }
+
+    @ApiOperation(value = "修改学员报名信息")
+    @PostMapping(value = "update")
+    public HttpResponseResult update(@RequestBody ExamRegistration examRegistration) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if(Objects.isNull(sysUser)){
+            return failed("用户信息异常");
+        }
+        examRegistration.setStudentId(sysUser.getId());
+        examRegistrationService.updateExamRegistration(examRegistration);
+        return succeed();
+    }
+
+
+    @ApiOperation(value = "报名")
+    @PostMapping(value = "add")
+    public HttpResponseResult add(@RequestBody ExamRegistration examRegistration) throws Exception {
+        SysUser student = sysUserFeignService.queryUserInfo();
+        examRegistration.setStudentId(student.getId());
+        return succeed(examRegistrationService.addRegistration(examRegistration));
+    }
+
+    @ApiOperation(value = "获取招生统计信息")
+    @GetMapping(value = "getExamRegistrationStaticsInfo")
+    @PreAuthorize("@pcs.hasPermissions('examRegistration/getExamRegistrationStaticsInfo')")
+    public HttpResponseResult<ExamRegistrationStatisticsDto> getExamRegistrationStaticsInfo(Integer examId) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        Integer organId=null;
+        if(!sysUser.getIsSuperAdmin()){
+            Employee employee = employeeService.get(sysUser.getId());
+            if(Objects.isNull(employee)){
+                return failed("用户信息异常");
+            }
+            organId=employee.getOrganId();
+        }
+        return succeed(examRegistrationService.getExamRegistrationStaticsInfo(organId, examId));
+    }
+
+
+    @ApiOperation(value = "ocr")
+    @PostMapping(value = "ocr")
+    @ApiImplicitParams({@ApiImplicitParam(name = "file", value = "身份证图片", required = true, dataType = "file"),
+            @ApiImplicitParam(name = "idCardSide", value = "身份证(front-人像面 back-国徽面)", required = true, dataType = "String")})
+    public HttpResponseResult ocr(@RequestParam("file") MultipartFile file, String idCardSide) throws IOException {
+        return succeed(Ocr.idcard(file, idCardSide));
+    }
+
+    @ApiOperation(value = "获取报名信息(报名)")
+    @GetMapping(value = "getExamRegistration")
+    @ApiImplicitParams({@ApiImplicitParam(name = "examRegistrationId", value = "报名id", required = true, dataType = "int")})
+    public HttpResponseResult<ExamRegistrationDto> getExamRegistration(Long examRegistrationId) {
+        return succeed(examRegistrationService.getExamRegistration(examRegistrationId));
+    }
+
+    @ApiOperation(value = "重新支付(报名用)")
+    @PostMapping(value = "repay")
+    public HttpResponseResult repay(@RequestParam String orderNo) throws Exception {
+        SysUser student = sysUserFeignService.queryUserInfo();
+        return succeed(examRegistrationService.repay(student.getId(), orderNo));
+    }
+
+}

+ 43 - 0
edu-user/edu-student-server/src/main/java/com/keao/edu/controller/ExamRoomStudentRelationController.java

@@ -0,0 +1,43 @@
+package com.keao.edu.controller;
+
+import com.keao.edu.common.controller.BaseController;
+import com.keao.edu.common.entity.HttpResponseResult;
+import com.keao.edu.user.dto.StuRecordDetailDto;
+import com.keao.edu.user.service.ExamRoomStudentRelationService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("examRoomStudentRelation")
+@Api(tags = "考场与学生关联服务")
+public class ExamRoomStudentRelationController extends BaseController {
+
+    @Autowired
+    private ExamRoomStudentRelationService examRoomStudentRelationService;
+
+    @ApiOperation("签到")
+    @PostMapping(value = "/signIn")
+    public HttpResponseResult signIn(Long examRegistrationId) {
+        examRoomStudentRelationService.signIn(examRegistrationId);
+        return succeed();
+    }
+
+    @ApiOperation("学生端录播详情页面")
+    @GetMapping(value = "/stuRecordDetail")
+    public HttpResponseResult<StuRecordDetailDto> stuRecordDetail(Long examRegistrationId) {
+        return succeed(examRoomStudentRelationService.stuRecordDetail(examRegistrationId));
+    }
+
+    @ApiOperation("学生端完成录播")
+    @PostMapping(value = "/stuEndRecord")
+    public HttpResponseResult stuEndRecord(Long examRegistrationId,String videoUrl) {
+        examRoomStudentRelationService.stuEndRecord(examRegistrationId,videoUrl);
+        return succeed();
+    }
+
+}

+ 34 - 0
edu-user/edu-student-server/src/main/java/com/keao/edu/controller/ExamSongController.java

@@ -0,0 +1,34 @@
+package com.keao.edu.controller;
+
+import com.keao.edu.common.controller.BaseController;
+import com.keao.edu.common.entity.HttpResponseResult;
+import com.keao.edu.common.page.PageInfo;
+import com.keao.edu.user.entity.ExamSong;
+import com.keao.edu.user.page.ExamSongQueryInfo;
+import com.keao.edu.user.service.ExamSongService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+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;
+
+/**
+ * @Author Joburgess
+ * @Date 2020.06.16
+ */
+@RestController
+@RequestMapping("examSong")
+@Api(tags = "曲库服务")
+public class ExamSongController extends BaseController {
+
+    @Autowired
+    private ExamSongService examSongService;
+
+    @ApiOperation("学生端分页查询考级曲库")
+    @GetMapping(value = "/queryPage")
+    public HttpResponseResult<PageInfo<ExamSong>> queryPage(ExamSongQueryInfo queryInfo) {
+        return succeed(examSongService.querySongPage(queryInfo));
+    }
+
+}

+ 32 - 0
edu-user/edu-student-server/src/main/java/com/keao/edu/controller/ExamSubjectController.java

@@ -0,0 +1,32 @@
+package com.keao.edu.controller;
+
+import com.keao.edu.common.controller.BaseController;
+import com.keao.edu.common.entity.HttpResponseResult;
+import com.keao.edu.user.dto.ExamSubjectDto;
+import com.keao.edu.user.service.ExamSubjectService;
+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.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("examSubject")
+@Api(tags = "考级内容服务")
+public class ExamSubjectController extends BaseController {
+
+    @Autowired
+    private ExamSubjectService examSubjectService;
+
+    @ApiOperation("获取考试项目专业")
+    @ApiImplicitParam(name = "ExamId", value = "考试项目id", required = true, dataType = "Integer")
+    @GetMapping(value = "/getExamSubjects")
+    public HttpResponseResult<List<ExamSubjectDto>> getExamSubjects(Integer examId) {
+        return succeed(examSubjectService.getExamSubjects(examId));
+    }
+
+}

+ 50 - 0
edu-user/edu-student-server/src/main/java/com/keao/edu/controller/ExamSubjectSongController.java

@@ -0,0 +1,50 @@
+package com.keao.edu.controller;
+
+import com.keao.edu.common.controller.BaseController;
+import com.keao.edu.common.entity.HttpResponseResult;
+import com.keao.edu.user.entity.ExamSong;
+import com.keao.edu.user.entity.ExamSubjectSong;
+import com.keao.edu.user.service.ExamSubjectSongService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+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.util.List;
+
+/**
+ * @Author Joburgess
+ * @Date 2020.06.18
+ */
+@RestController
+@RequestMapping("examSubjectSong")
+@Api(tags = "考级内容服务")
+public class ExamSubjectSongController extends BaseController {
+
+    @Autowired
+    private ExamSubjectSongService examSubjectSongService;
+
+    @ApiOperation("获取考级专业相应级别列表-报名")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "examinationBasicId", value = "项目id", required = true, dataType = "Integer"),
+            @ApiImplicitParam(name = "examSubjectId", value = "考试项目专业id", required = true, dataType = "Integer")})
+    @GetMapping(value = "/getExamSubjectLevel")
+    public HttpResponseResult<List<ExamSubjectSong>> getExamSubjectLevel(Integer examinationBasicId, Long examSubjectId) {
+        return succeed(examSubjectSongService.getExamSubjectLevels(examinationBasicId, examSubjectId));
+    }
+
+    @ApiOperation("获取考级专业相应级别的曲目-报名")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "examinationBasicId", value = "项目id", required = true, dataType = "Integer"),
+            @ApiImplicitParam(name = "examSubjectId", value = "考试项目专业id", required = true, dataType = "Integer"),
+            @ApiImplicitParam(name = "level", value = "级别", required = true, dataType = "Integer")})
+    @GetMapping(value = "/getExamSubjectSong")
+    public HttpResponseResult<List<ExamSong>> getExamSubjectSong(Integer examinationBasicId, Long examSubjectId, Integer level) {
+        return succeed(examSubjectSongService.getExamSubjectSong(examinationBasicId, examSubjectId, level));
+    }
+
+}

+ 31 - 0
edu-user/edu-student-server/src/main/java/com/keao/edu/controller/ExaminationBasicController.java

@@ -0,0 +1,31 @@
+package com.keao.edu.controller;
+
+import com.keao.edu.common.controller.BaseController;
+import com.keao.edu.common.entity.HttpResponseResult;
+import com.keao.edu.user.entity.ExaminationBasic;
+import com.keao.edu.user.service.ExaminationBasicService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @Author Joburgess
+ * @Date 2020.06.18
+ */
+@RestController
+@RequestMapping("examinationBasic")
+@Api(tags = "考级项目服务")
+public class ExaminationBasicController extends BaseController {
+
+    @Autowired
+    private ExaminationBasicService examinationBasicService;
+
+    @ApiOperation("获取考级项目信息")
+    @PostMapping(value = "/getInfo")
+    public HttpResponseResult<ExaminationBasic> getInfo(Integer examId){
+        return succeed(examinationBasicService.getInfo(examId));
+    }
+}

+ 46 - 0
edu-user/edu-student-server/src/main/java/com/keao/edu/controller/StudentController.java

@@ -0,0 +1,46 @@
+package com.keao.edu.controller;
+
+
+import com.keao.edu.auth.api.client.SysUserFeignService;
+import com.keao.edu.auth.api.entity.SysUser;
+import com.keao.edu.common.controller.BaseController;
+import com.keao.edu.common.entity.HttpResponseResult;
+import com.keao.edu.user.api.entity.Student;
+import com.keao.edu.user.service.StudentService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 系统配置控制层
+ */
+@RestController
+@Api(tags = "学员服务")
+@RequestMapping(value = "student")
+public class StudentController extends BaseController {
+
+    @Autowired
+    private StudentService studentService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @ApiOperation(value = "获取学生信息")
+    @GetMapping(value = "getStudent")
+    public HttpResponseResult<Student> getStudent() {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        return succeed(studentService.getStudent(user.getId()));
+    }
+
+    @ApiOperation(value = "更新学员基本信息")
+    @PostMapping(value = "updateInfo")
+    public HttpResponseResult<Student> updateInfo(Student student) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        student.setUserId(user.getId());
+        return succeed(studentService.updateInfo(student));
+    }
+
+}

+ 30 - 0
edu-user/edu-student-server/src/main/java/com/keao/edu/controller/SubjectController.java

@@ -0,0 +1,30 @@
+package com.keao.edu.controller;
+
+
+import com.keao.edu.common.controller.BaseController;
+import com.keao.edu.common.entity.HttpResponseResult;
+import com.keao.edu.common.page.PageInfo;
+import com.keao.edu.user.entity.Subject;
+import com.keao.edu.user.page.SubjectQueryInfo;
+import com.keao.edu.user.service.SubjectService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+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;
+
+@RequestMapping("subject")
+@Api(tags = "科目服务")
+@RestController
+public class SubjectController extends BaseController {
+
+    @Autowired
+    private SubjectService subjectService;
+
+    @ApiOperation(value = "学生端分页查询科目列表")
+    @GetMapping("/studentQueryPage")
+    public HttpResponseResult<PageInfo<Subject>> studentQueryPage(SubjectQueryInfo queryInfo){
+        return succeed(subjectService.queryPage(queryInfo));
+    }
+}

+ 30 - 0
edu-user/edu-student-server/src/main/java/com/keao/edu/controller/SysSuggestionController.java

@@ -0,0 +1,30 @@
+package com.keao.edu.controller;
+
+
+import com.keao.edu.common.controller.BaseController;
+import com.keao.edu.user.entity.SysSuggestion;
+import com.keao.edu.user.service.SysSuggestionService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RequestMapping("sysSuggestion")
+@Api(tags = "意见反馈")
+@RestController
+public class SysSuggestionController extends BaseController {
+
+    @Autowired
+    private SysSuggestionService sysSuggestionService;
+
+    @ApiOperation(value = "新增")
+    @RequestMapping("/add")
+    @PreAuthorize("@pcs.hasPermissions('sysSuggestion/add')")
+    public Object add(SysSuggestion sysSuggestion) {
+        sysSuggestionService.insert(sysSuggestion);
+        return succeed();
+    }
+
+}

+ 45 - 0
edu-user/edu-student-server/src/main/java/com/keao/edu/controller/UploadFileController.java

@@ -0,0 +1,45 @@
+package com.keao.edu.controller;
+
+import com.keao.edu.common.controller.BaseController;
+import com.keao.edu.common.entity.UploadReturnBean;
+import com.keao.edu.user.service.UploadFileService;
+import com.keao.edu.util.upload.UploadUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiParam;
+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.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * 上传控制层
+ */
+@RestController
+@Api(tags = "文件上传服务")
+public class UploadFileController extends BaseController {
+
+	private final static Logger LOGGER = LoggerFactory.getLogger(UploadFileController.class);
+
+	@Autowired
+	private UploadFileService uploadFileService;
+
+	@PostMapping(value = "uploadFile")
+	public Object uploadFile(@ApiParam(value = "上传的文件", required = true) @RequestParam("file") MultipartFile file) {
+		try {
+			if (file != null && StringUtils.isNotBlank(file.getOriginalFilename())) {
+				UploadReturnBean bean = uploadFileService.uploadFile(file.getInputStream(), UploadUtil.getExtension(file.getOriginalFilename()));
+				if (bean.isStatus()) {
+					return succeed(bean);
+				}
+				return failed(bean.getMessage());
+			}
+		} catch (Exception e) {
+			LOGGER.error("上传失败", e);
+		}
+		return failed("上传失败");
+	}
+}

+ 120 - 0
edu-user/edu-student-server/src/main/resources/application.yml

@@ -0,0 +1,120 @@
+server:
+  port: 8002
+  tomcat:
+    accesslog:
+      enabled: true
+      buffered: true
+      directory: /var/logs
+      file-date-format: -yyyy-MM-dd
+      pattern: common
+      prefix: tomcat-user
+      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
+
+spring:
+  application:
+    name: student-server
+
+  servlet:
+    multipart:
+      # 最大支持文件大小
+      max-file-size: 50MB
+      # 最大支持请求大小
+      max-request-size: 50MB
+    
+  datasource:
+    name: test
+#    url: jdbc:mysql://47.99.212.176:3306/edu_saas?useUnicode=true&characterEncoding=UTF8&serverTimezone=Asia/Shanghai
+#    username: edu_saas
+#    password: edu_saas
+    url: jdbc:mysql://47.114.176.40:3306/edu_saas?useUnicode=true&characterEncoding=UTF8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
+    username: edu_saas
+    password: dayaDataOnline@2019
+    # 使用druid数据源
+    type: com.alibaba.druid.pool.DruidDataSource
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    filters: stat
+    maxActive: 20
+    initialSize: 1
+    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.176.40
+    port: 6379
+    password: dyym
+    database: 1
+    #连接超时时间(毫秒)
+    timeout: 10000
+    jedis:
+      pool:
+        #连接池最大连接数(使用负值表示没有限制)
+        max-active: 10
+        #连接池最大阻塞等待时间(使用负值表示没有限制)
+        max-wait: -1
+        #连接池中的最大空闲连接
+        max-idle: 10
+        #连接池中的最小空闲连接
+        min-idle: 1
+
+mybatis:
+  mapperLocations: classpath*:config/mybatis/*.xml
+  typeAliasesPackage: com.keao.edu.*.entity
+  configuration:
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+
+swagger:
+  base-package: com.keao.edu.user.controller
+##认证 
+security:
+  oauth2:
+    client:
+      client-id: student
+      client-secret: student
+    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: 60000
+  ConnectTimeout: 60000
+
+message:
+  debugMode: true
+
+logging:
+  level:
+    com.keao.edu.user.api.client.EduUserFeignService: INFO
+    com.keao.edu.user.dao: DEBUG
+
+
+push:
+  jiguang:
+    reqURL: https://api.jpush.cn/v3/push
+    apns_production: false

+ 16 - 0
edu-user/edu-student-server/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.176.40:8848
+#\u9ed8\u8ba4\u4e3aPublic\u547d\u540d\u7a7a\u95f4,\u53ef\u4ee5\u7701\u7565\u4e0d\u5199
+spring.cloud.nacos.config.namespace=753368b1-d0a9-42bc-bb76-c4ab319f0203
+#\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=student
+#\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
edu-user/edu-student-server/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=121.40.129.226:8848
+#\u9ed8\u8ba4\u4e3aPublic\u547d\u540d\u7a7a\u95f4,\u53ef\u4ee5\u7701\u7565\u4e0d\u5199
+spring.cloud.nacos.config.namespace=a97db240-8024-45f2-bceb-bbccbb07ea1d
+#\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=user
+#\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

+ 38 - 0
edu-user/edu-student-server/src/main/resources/logback-spring.xml

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration scan="true" scanPeriod="10 seconds">
+
+	<property name="LOG_HOME" value="/mdata/logs/cms-%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>
+
+	<logger name="com.keao.edu" level="INFO" />
+
+	<!--开发环境:打印控制台 -->
+	<root level="INFO">
+		<appender-ref ref="stdout" />
+		<appender-ref ref="file" />
+	</root>
+
+</configuration>

+ 48 - 0
edu-user/edu-teacher-server/pom.xml

@@ -22,5 +22,53 @@
       <version>3.8.1</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.springframework.cloud</groupId>
+      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-websocket</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.springframework.cloud</groupId>
+      <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-web</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.cloud</groupId>
+      <artifactId>spring-cloud-openfeign-core</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.spring4all</groupId>
+      <artifactId>swagger-spring-boot-starter</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.keao.edu</groupId>
+      <artifactId>edu-user-biz</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>javax.servlet-api</artifactId>
+    </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>

+ 0 - 13
edu-user/edu-teacher-server/src/main/java/com/keao/edu/App.java

@@ -1,13 +0,0 @@
-package com.keao.edu;
-
-/**
- * Hello world!
- *
- */
-public class App 
-{
-    public static void main( String[] args )
-    {
-        System.out.println( "Hello World!" );
-    }
-}

+ 29 - 0
edu-user/edu-teacher-server/src/main/java/com/keao/edu/TeacherApplication.java

@@ -0,0 +1,29 @@
+package com.keao.edu;
+
+import com.spring4all.swagger.EnableSwagger2Doc;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableAsync;
+
+/**
+ * Hello world!
+ *
+ */
+@SpringBootApplication
+@EnableDiscoveryClient
+@EnableFeignClients({"com.keao.edu"})
+@MapperScan({"com.keao.edu.user.dao", "com.keao.edu.common.dao"})
+@Configuration
+@EnableSwagger2Doc
+@EnableAsync
+public class TeacherApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(TeacherApplication.class, args);
+    }
+
+}

+ 49 - 0
edu-user/edu-teacher-server/src/main/java/com/keao/edu/config/PermissionCheckService.java

@@ -0,0 +1,49 @@
+package com.keao.edu.config;
+
+import com.keao.edu.auth.api.client.SysUserFeignService;
+import com.keao.edu.auth.api.entity.SysUser;
+import com.keao.edu.auth.api.util.SecurityUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.stereotype.Component;
+
+import java.util.Collection;
+
+@Component("pcs")
+public class PermissionCheckService {
+
+	@Autowired
+	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);
+	}
+
+}

+ 39 - 0
edu-user/edu-teacher-server/src/main/java/com/keao/edu/config/ResourceServerConfig.java

@@ -0,0 +1,39 @@
+package com.keao.edu.config;
+
+import com.keao.edu.common.security.BaseAccessDeniedHandler;
+import com.keao.edu.common.security.BaseAuthenticationEntryPoint;
+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;
+
+@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.authorizeRequests()
+                .antMatchers("/task/*","/v2/api-docs", "/su/**", "/student/apply", "/examRegistration/ocr", "/examOrder/paymentResult",
+                        "/examOrder/notify","/examinationBasic/getInfo","/examOrder/executePayment","/examOrder/pageList","/studentExamResult/recordSync")
+                .permitAll()
+                .anyRequest().authenticated().and().csrf().disable().exceptionHandling().accessDeniedHandler(baseAccessDeniedHandler)
+                .authenticationEntryPoint(baseAuthenticationEntryPoint).and();
+    }
+
+    @Override
+    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
+        resources.authenticationEntryPoint(baseAuthenticationEntryPoint).accessDeniedHandler(baseAccessDeniedHandler);
+    }
+
+}

+ 55 - 0
edu-user/edu-teacher-server/src/main/java/com/keao/edu/config/WebMvcConfig.java

@@ -0,0 +1,55 @@
+package com.keao.edu.config;
+
+import com.keao.edu.common.config.EnumConverterFactory;
+import com.keao.edu.common.config.LocalFastJsonHttpMessageConverter;
+import com.keao.edu.common.tenant.TenantInterceptor;
+import com.keao.edu.datasource.interceptor.DataSourceInterceptor;
+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 java.util.ArrayList;
+import java.util.List;
+
+@Configuration
+public class WebMvcConfig implements WebMvcConfigurer {
+
+	/**
+	 * 枚举类的转换器 addConverterFactory
+	 */
+	@Override
+	public void addFormatters(FormatterRegistry registry) {
+		registry.addConverterFactory(new EnumConverterFactory());
+	}
+
+	@Override
+	public void addInterceptors(InterceptorRegistry registry) {
+
+		registry.addInterceptor(getDataSrouceInterceptor()).addPathPatterns("/**");
+		registry.addInterceptor(getTenantInterceptor()).addPathPatterns("/**");
+	}
+
+	@Bean
+	public DataSourceInterceptor getDataSrouceInterceptor() {
+		return new DataSourceInterceptor();
+	}
+
+	@Bean
+	public TenantInterceptor getTenantInterceptor() {
+		return new TenantInterceptor();
+	}
+	
+	@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);
+    }
+
+}

+ 14 - 0
edu-user/edu-teacher-server/src/main/java/com/keao/edu/config/WebSocketConfig.java

@@ -0,0 +1,14 @@
+package com.keao.edu.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+@Configuration
+public class WebSocketConfig {
+
+    @Bean
+    public ServerEndpointExporter serverEndpointExporter () {
+        return new ServerEndpointExporter();
+    }
+}

+ 32 - 0
edu-user/edu-teacher-server/src/main/java/com/keao/edu/controller/EmployeeController.java

@@ -0,0 +1,32 @@
+package com.keao.edu.controller;
+
+
+import com.keao.edu.auth.api.client.SysUserFeignService;
+import com.keao.edu.auth.api.entity.SysUser;
+import com.keao.edu.common.controller.BaseController;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+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;
+
+@RestController
+@RequestMapping("employee")
+@Api(tags = "员工服务")
+public class EmployeeController extends BaseController {
+
+	@Autowired
+	private SysUserFeignService sysUserFeignService;
+
+	@ApiOperation(value = "获取用户信息")
+	@GetMapping("/queryUserInfo")
+	public Object apiQueryUserInfo() {
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		if(sysUser != null && sysUser.getId() != null){
+			return succeed(sysUser);
+		}
+		return failed("获取用户信息失败");
+	}
+
+}

+ 27 - 0
edu-user/edu-teacher-server/src/main/java/com/keao/edu/controller/ExamCertificationController.java

@@ -0,0 +1,27 @@
+package com.keao.edu.controller;
+
+import com.keao.edu.common.controller.BaseController;
+import com.keao.edu.common.entity.HttpResponseResult;
+import com.keao.edu.user.dto.ExamCertificationDto;
+import com.keao.edu.user.service.ExamCertificationService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+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;
+
+@RestController
+@RequestMapping("examCertification")
+@Api(tags = "准考证服务")
+public class ExamCertificationController extends BaseController {
+
+    @Autowired
+    private ExamCertificationService examCertificationService;
+
+    @ApiOperation("后台获取学员准考证详情")
+    @GetMapping(value = "findDetailByStudentId")
+    public HttpResponseResult<ExamCertificationDto> findDetailByStudentId(Long examRegistrationId) {
+        return succeed(examCertificationService.findDetailByStudentId(examRegistrationId));
+    }
+}

+ 51 - 0
edu-user/edu-teacher-server/src/main/java/com/keao/edu/controller/ExamReviewController.java

@@ -0,0 +1,51 @@
+package com.keao.edu.controller;
+
+import com.keao.edu.auth.api.client.SysUserFeignService;
+import com.keao.edu.auth.api.entity.SysUser;
+import com.keao.edu.common.controller.BaseController;
+import com.keao.edu.common.entity.HttpResponseResult;
+import com.keao.edu.common.page.PageInfo;
+import com.keao.edu.user.dto.ExamReviewRecordDto;
+import com.keao.edu.user.entity.ExamReview;
+import com.keao.edu.user.page.ExamReviewRecordQueryInfo;
+import com.keao.edu.user.service.ExamReviewService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("examReview")
+@Api(tags = "评审服务")
+public class ExamReviewController extends BaseController {
+
+    @Autowired
+    private ExamReviewService examReviewService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @ApiOperation("监考页面分页查询评审结果")
+    @GetMapping(value = "/queryExamReviewRecordList")
+    public HttpResponseResult<PageInfo<ExamReviewRecordDto>> queryExamReviewRecordList(ExamReviewRecordQueryInfo queryInfo) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        queryInfo.setTeacherId(sysUser.getId());
+        return succeed(examReviewService.queryExamReviewRecordList(queryInfo));
+    }
+
+    @ApiOperation("修改评审结果")
+    @PostMapping(value = "/update")
+    public HttpResponseResult update(ExamReview examReview){
+        examReviewService.update(examReview);
+        return succeed();
+    }
+
+    @ApiOperation("老师评审")
+    @PostMapping(value = "/createExamReview")
+    public HttpResponseResult createExamReview(ExamReview examReview){
+        examReviewService.add(examReview);
+        return succeed();
+    }
+}

+ 66 - 0
edu-user/edu-teacher-server/src/main/java/com/keao/edu/controller/ExamRoomController.java

@@ -0,0 +1,66 @@
+package com.keao.edu.controller;
+
+import com.keao.edu.auth.api.client.SysUserFeignService;
+import com.keao.edu.auth.api.entity.SysUser;
+import com.keao.edu.common.controller.BaseController;
+import com.keao.edu.common.entity.HttpResponseResult;
+import com.keao.edu.common.page.PageInfo;
+import com.keao.edu.user.api.entity.ExamRoom;
+import com.keao.edu.user.dto.ExamRoomListDto;
+import com.keao.edu.user.entity.Teacher;
+import com.keao.edu.user.page.ExamRoomListQueryInfo;
+import com.keao.edu.user.service.EmployeeService;
+import com.keao.edu.user.service.ExamRoomService;
+import com.keao.edu.user.service.TeacherService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Objects;
+
+@RestController
+@RequestMapping("examRoom")
+@Api(tags = "考场服务")
+public class ExamRoomController extends BaseController {
+
+    @Autowired
+    private ExamRoomService examRoomService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private EmployeeService employeeService;
+    @Autowired
+    private TeacherService teacherService;
+
+    @ApiOperation("分页查询监考列表")
+    @GetMapping(value = "/list")
+    public HttpResponseResult<PageInfo<ExamRoomListDto>> getList(ExamRoomListQueryInfo queryInfo) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if(!sysUser.getIsSuperAdmin() && Objects.isNull(queryInfo.getOrganId())){
+            Teacher teacher = teacherService.get(sysUser.getId());
+            if(Objects.isNull(teacher)){
+                return failed("用户信息异常");
+            }
+            queryInfo.setOrganId(teacher.getOrganId());
+        }
+        return succeed(examRoomService.queryExamRoomPage(queryInfo));
+    }
+
+    @ApiOperation("教室状态变更(关闭教室,开启教室)")
+    @PostMapping(value = "/changeExamRoom")
+    public HttpResponseResult changeExamRoom(Long examRoomId,Integer openFlag){
+        examRoomService.changeExamRoom(examRoomId,openFlag);
+        return succeed();
+    }
+
+    @ApiOperation("获取教室")
+    @GetMapping(value = "/get")
+    public HttpResponseResult<ExamRoom> getExamRoom(Long id){
+        return succeed(examRoomService.get(id));
+    }
+
+}

+ 47 - 0
edu-user/edu-teacher-server/src/main/java/com/keao/edu/controller/ExamRoomStudentRelationController.java

@@ -0,0 +1,47 @@
+package com.keao.edu.controller;
+
+import com.keao.edu.common.controller.BaseController;
+import com.keao.edu.common.entity.HttpResponseResult;
+import com.keao.edu.user.service.ExamRoomStudentRelationService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("examRoomStudentRelation")
+@Api(tags = "考场与学生关联服务")
+public class ExamRoomStudentRelationController extends BaseController {
+
+    @Autowired
+    private ExamRoomStudentRelationService examRoomStudentRelationService;
+
+    @ApiOperation("下一位")
+    @PostMapping(value = "/nextBit")
+    public HttpResponseResult nextBit(Integer examStatus,Long roomId) {
+        examRoomStudentRelationService.nextBit(examStatus,roomId);
+        return succeed();
+    }
+
+    @ApiOperation("开始考试")
+    @PostMapping(value = "/actionExam")
+    public HttpResponseResult actionExam(Long roomId) {
+        examRoomStudentRelationService.actionExam(roomId);
+        return succeed();
+    }
+
+    @ApiOperation("监考端选择去录播")
+    @PostMapping(value = "/webRecorded")
+    public HttpResponseResult webRecorded(Long roomId) {
+        examRoomStudentRelationService.recorded(roomId);
+        return succeed();
+    }
+
+    @ApiOperation("获取后台考场待考队列")
+    @PostMapping(value = "/queryNeedCheckingList")
+    public HttpResponseResult queryNeedCheckingList(Long roomId) {
+        return succeed(examRoomStudentRelationService.queryNeedCheckingList(roomId));
+    }
+}

+ 50 - 0
edu-user/edu-teacher-server/src/main/java/com/keao/edu/controller/StudentExamResultController.java

@@ -0,0 +1,50 @@
+package com.keao.edu.controller;
+
+import com.keao.edu.auth.api.client.SysUserFeignService;
+import com.keao.edu.common.controller.BaseController;
+import com.keao.edu.common.entity.HttpResponseResult;
+import com.keao.edu.user.service.EmployeeService;
+import com.keao.edu.user.service.StudentExamResultService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @Author Joburgess
+ * @Date 2020.06.30
+ */
+@RestController
+@RequestMapping("studentExamResult")
+@Api(tags = "考试结果服务")
+public class StudentExamResultController extends BaseController {
+
+    @Autowired
+    private StudentExamResultService studentExamResultService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private EmployeeService employeeService;
+
+    @ApiOperation("确认考生")
+    @PostMapping(value = "/confirmStudent")
+    public HttpResponseResult confirmStudent(Long examRegistrationId) {
+        studentExamResultService.confirmStudent(examRegistrationId);
+        return succeed();
+    }
+
+    /**
+     * 屏蔽指定用户
+     * @param roomId
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value = "/shieldUserId", method = RequestMethod.POST)
+    public Object shieldUserId(Long roomId,Integer shieldFlag)throws Exception {
+        studentExamResultService.shieldUserId(roomId,shieldFlag);
+        return succeed();
+    }
+}

+ 36 - 0
edu-user/edu-teacher-server/src/main/java/com/keao/edu/controller/TenantInfoController.java

@@ -0,0 +1,36 @@
+package com.keao.edu.controller;
+
+
+import com.keao.edu.common.controller.BaseController;
+import com.keao.edu.common.entity.HttpResponseResult;
+import com.keao.edu.common.tenant.TenantContextHolder;
+import com.keao.edu.user.entity.TenantInfo;
+import com.keao.edu.user.service.TenantInfoService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+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;
+
+@RestController
+@RequestMapping("tenantInfo")
+@Api(tags = "机构服务")
+public class TenantInfoController extends BaseController {
+
+	@Autowired
+	private TenantInfoService tenantInfoService;
+
+	@ApiOperation("查询机构详情")
+	@GetMapping(value = "/query")
+	public HttpResponseResult<TenantInfo> query() {
+		String tenantId = TenantContextHolder.getTenantId();
+		if(StringUtils.isNotEmpty(tenantId)){
+			return succeed(tenantInfoService.get(Integer.parseInt(tenantId)));
+		}else {
+			return succeed(new TenantInfo());
+		}
+	}
+
+}

+ 120 - 0
edu-user/edu-teacher-server/src/main/resources/application.yml

@@ -0,0 +1,120 @@
+server:
+  port: 8003
+  tomcat:
+    accesslog:
+      enabled: true
+      buffered: true
+      directory: /var/logs
+      file-date-format: -yyyy-MM-dd
+      pattern: common
+      prefix: tomcat-user
+      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
+
+spring:
+  application:
+    name: student-server
+
+  servlet:
+    multipart:
+      # 最大支持文件大小
+      max-file-size: 50MB
+      # 最大支持请求大小
+      max-request-size: 50MB
+    
+  datasource:
+    name: test
+#    url: jdbc:mysql://47.99.212.176:3306/edu_saas?useUnicode=true&characterEncoding=UTF8&serverTimezone=Asia/Shanghai
+#    username: edu_saas
+#    password: edu_saas
+    url: jdbc:mysql://47.114.176.40:3306/edu_saas?useUnicode=true&characterEncoding=UTF8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
+    username: edu_saas
+    password: dayaDataOnline@2019
+    # 使用druid数据源
+    type: com.alibaba.druid.pool.DruidDataSource
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    filters: stat
+    maxActive: 20
+    initialSize: 1
+    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.176.40
+    port: 6379
+    password: dyym
+    database: 1
+    #连接超时时间(毫秒)
+    timeout: 10000
+    jedis:
+      pool:
+        #连接池最大连接数(使用负值表示没有限制)
+        max-active: 10
+        #连接池最大阻塞等待时间(使用负值表示没有限制)
+        max-wait: -1
+        #连接池中的最大空闲连接
+        max-idle: 10
+        #连接池中的最小空闲连接
+        min-idle: 1
+
+mybatis:
+  mapperLocations: classpath*:config/mybatis/*.xml
+  typeAliasesPackage: com.keao.edu.*.entity
+  configuration:
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+
+swagger:
+  base-package: com.keao.edu.user.controller
+##认证 
+security:
+  oauth2:
+    client:
+      client-id: student
+      client-secret: student
+    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: 60000
+  ConnectTimeout: 60000
+
+message:
+  debugMode: true
+
+logging:
+  level:
+    com.keao.edu.user.api.client.EduUserFeignService: INFO
+    com.keao.edu.user.dao: DEBUG
+
+
+push:
+  jiguang:
+    reqURL: https://api.jpush.cn/v3/push
+    apns_production: false

+ 16 - 0
edu-user/edu-teacher-server/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.176.40:8848
+#\u9ed8\u8ba4\u4e3aPublic\u547d\u540d\u7a7a\u95f4,\u53ef\u4ee5\u7701\u7565\u4e0d\u5199
+spring.cloud.nacos.config.namespace=753368b1-d0a9-42bc-bb76-c4ab319f0203
+#\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=teacher
+#\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
edu-user/edu-teacher-server/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=121.40.129.226:8848
+#\u9ed8\u8ba4\u4e3aPublic\u547d\u540d\u7a7a\u95f4,\u53ef\u4ee5\u7701\u7565\u4e0d\u5199
+spring.cloud.nacos.config.namespace=a97db240-8024-45f2-bceb-bbccbb07ea1d
+#\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=user
+#\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

+ 38 - 0
edu-user/edu-teacher-server/src/main/resources/logback-spring.xml

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration scan="true" scanPeriod="10 seconds">
+
+	<property name="LOG_HOME" value="/mdata/logs/cms-%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>
+
+	<logger name="com.keao.edu" level="INFO" />
+
+	<!--开发环境:打印控制台 -->
+	<root level="INFO">
+		<appender-ref ref="stdout" />
+		<appender-ref ref="file" />
+	</root>
+
+</configuration>

+ 18 - 0
edu-user/edu-user-biz/src/main/java/com/keao/edu/user/dao/StudentExamResultDao.java

@@ -96,4 +96,22 @@ public interface StudentExamResultDao extends BaseDAO<Long, StudentExamResult> {
      * @return int
      */
     int updateRegistAvgScore(@Param("results") List<StudentExamResult> results);
+
+    /**
+     * @describe 获取指定考场的学员考试结果
+     * @author Joburgess
+     * @date 2020.08.03
+     * @param examRoomId:
+     * @return java.util.List<com.keao.edu.user.entity.StudentExamResult>
+     */
+    List<StudentExamResult> getWithExamRoom(@Param("examRoomId") Long examRoomId);
+
+    /**
+     * @describe 统计考级项目下未确认结果的学生数量
+     * @author Joburgess
+     * @date 2020.08.03
+     * @param examId:
+     * @return int
+     */
+    int countExamNoResultStudentNum(@Param("examId") Long examId);
 }

+ 5 - 2
edu-user/edu-user-biz/src/main/java/com/keao/edu/user/service/impl/ExaminationBasicServiceImpl.java

@@ -60,6 +60,8 @@ public class ExaminationBasicServiceImpl extends BaseServiceImpl<Long, Examinati
     @Autowired
     private StudentExamResultService studentExamResultService;
     @Autowired
+    private StudentExamResultDao studentExamResultDao;
+    @Autowired
     private ExamRoomDao examRoomDao;
     @Autowired
     private TenantInfoDao tenantInfoDao;
@@ -217,8 +219,9 @@ public class ExaminationBasicServiceImpl extends BaseServiceImpl<Long, Examinati
         if(ExamStatusEnum.DELETE.equals(statusEnum)){
             examLifecycleLogDao.insert(new ExamLifecycleLog(existsExam.getId().intValue(), "删除考级项目", operatorId));
         }else if(ExamStatusEnum.RESULT_CONFIRM.equals(statusEnum)){
-            if(ExamStatusEnum.EXAM_END.equals(existsExam.getStatus())){
-                throw new BizException("考试未结束");
+            int noResultStudentNum = studentExamResultDao.countExamNoResultStudentNum(examId);
+            if(noResultStudentNum>0){
+                throw new BizException("尚有考生考试结果未确认");
             }
             examLifecycleLogDao.insert(new ExamLifecycleLog(existsExam.getId().intValue(), "确认考试结果", operatorId));
             studentExamResultService.examResultConfirmPush(examId);

+ 9 - 10
edu-user/edu-user-biz/src/main/java/com/keao/edu/user/service/impl/StudentExamResultServiceImpl.java

@@ -124,7 +124,7 @@ public class StudentExamResultServiceImpl extends BaseServiceImpl<Long, StudentE
 			throw new BizException("考试结果不存在");
 		}
 		if(Objects.isNull(oldStudentExamResult.getAvgScore())){
-			throw new BizException("考试结果暂不可编辑");
+			throw new BizException("考试未结束");
 		}
 		ExaminationBasic examinationBasic = examinationBasicDao.get(oldStudentExamResult.getExaminationBasicId().longValue());
 		if(Objects.isNull(examinationBasic)){
@@ -170,25 +170,24 @@ public class StudentExamResultServiceImpl extends BaseServiceImpl<Long, StudentE
 	@Override
 	@Transactional(rollbackFor = Exception.class)
 	public void calculateStudentExamAvgScore(Long examRoomId) {
-		List<ExamReview> examReviews = examReviewDao.getWithExamRoom(examRoomId);
-		if(CollectionUtils.isEmpty(examReviews)){
+		List<StudentExamResult> studentExamResults = studentExamResultDao.getWithExamRoom(examRoomId);
+		if(CollectionUtils.isEmpty(studentExamResults)){
 			return;
 		}
+		List<ExamReview> examReviews = examReviewDao.getWithExamRoom(examRoomId);
 		Map<Long, List<ExamReview>> registReviewMap = examReviews.stream().collect(Collectors.groupingBy(ExamReview::getExamRegistrationId));
-		List<StudentExamResult> needUpdateStudentExamResult = new ArrayList<>();
-		for (Map.Entry<Long, List<ExamReview>> registReviewEntry : registReviewMap.entrySet()) {
-			List<ExamReview> reviews = registReviewEntry.getValue().stream().filter(e->Objects.nonNull(e.getEvaluationResult())).collect(Collectors.toList());
+		for (StudentExamResult studentExamResult : studentExamResults) {
+			List<ExamReview> reviews = registReviewMap.get(studentExamResult.getExamRegistrationId());
 			if(CollectionUtils.isEmpty(reviews)){
+				studentExamResult.setAvgScore((float) 0);
 				continue;
 			}
-			StudentExamResult studentExamResult=new StudentExamResult();
-			studentExamResult.setExamRegistrationId(registReviewEntry.getKey());
+			reviews = reviews.stream().filter(e->Objects.nonNull(e.getEvaluationResult())).collect(Collectors.toList());
 			long totalScore = reviews.stream().mapToLong(ExamReview::getEvaluationResult).sum();
 			BigDecimal avgScore = new BigDecimal(totalScore).divide(new BigDecimal(reviews.size()), 2, BigDecimal.ROUND_CEILING);
 			studentExamResult.setAvgScore(avgScore.floatValue());
-			needUpdateStudentExamResult.add(studentExamResult);
 		}
-		studentExamResultDao.updateRegistAvgScore(needUpdateStudentExamResult);
+		studentExamResultDao.updateRegistAvgScore(studentExamResults);
 	}
 
 	@Override

+ 2 - 2
edu-user/edu-user-biz/src/main/resources/config/mybatis/ExamCertificationMapper.xml

@@ -144,9 +144,9 @@
 		LEFT JOIN exam_certification ec ON ec.exam_registration_id_ = ersr.exam_registration_id_
 		LEFT JOIN examination_basic eb ON eb.id_ = ersr.examination_basic_id_
 		LEFT JOIN student_exam_result ser ON ser.exam_registration_id_ = ersr.exam_registration_id_
-		WHERE eb.status_ NOT IN ('EXAM_END','RESULT_CONFIRM','CLOSE','DELETE') AND ersr.student_id_ = #{studentId}
+		WHERE eb.status_ NOT IN ('EXAM_END','RESULT_CONFIRM','CLOSE','DELETE') AND ersr.student_id_ = #{studentId} AND ser.is_finished_exam_ != 5
 		<if test="examRegistrationId != null">
-			AND ersr.exam_registration_id_ = #{examRegistrationId} AND ser.is_finished_exam_ != 5
+			AND ersr.exam_registration_id_ = #{examRegistrationId}
 		</if>
 		ORDER BY ec.exam_start_time_
 	</select>

+ 6 - 0
edu-user/edu-user-biz/src/main/resources/config/mybatis/StudentExamResultMapper.xml

@@ -286,4 +286,10 @@
     <select id="findByRoomIdAndUserId" resultMap="StudentExamResult">
 		SELECT * FROM student_exam_result WHERE exam_room_id_ = #{roomId} AND student_id_ = #{userId} LIMIT 1
 	</select>
+    <select id="getWithExamRoom" resultMap="StudentExamResult">
+		SELECT * FROM student_exam_result WHERE exam_room_id_=#{examRoomId}
+    </select>
+	<select id="countExamNoResultStudentNum" resultType="int">
+		SELECT COUNT(exam_registration_id_) FROM student_exam_result WHERE examination_basic_id_=#{examId} AND result_ IS NULL
+	</select>
 </mapper>

+ 7 - 2
edu-zuul/src/main/resources/application.yml

@@ -53,7 +53,12 @@ zuul:
       serviceId: user-server
       #url: http://localhost:8001/
       ##加上下面参数,可将header信息传递至下游
-      #sensitiveHeaders:
+    api-student:
+      path: /api-student/**
+      serviceId: student-server
+    api-teacher:
+      path: /api-teacher/**
+      serviceId: teacher-server
     api-task:
       ### 以 /api-auth/访问转发到会员服务
       path: /api-task/**
@@ -107,4 +112,4 @@ management:
         include: "*"
   endpoint:
     health:
-      show-details: ALWAYS
+      show-details: ALWAYS