Pārlūkot izejas kodu

Merge branch 'master' of http://git.dayaedu.com/yonge/edu-saas

yonge 5 gadi atpakaļ
vecāks
revīzija
6f6da897c6
32 mainītis faili ar 419 papildinājumiem un 198 dzēšanām
  1. 5 14
      edu-im/edu-im-api/src/main/java/com/keao/edu/im/api/client/ImFeignService.java
  2. 6 4
      edu-im/edu-im-api/src/main/java/com/keao/edu/im/api/client/callback/ImFeignServiceFallback.java
  3. 24 10
      edu-im/edu-im-api/src/main/java/com/keao/edu/im/api/entity/ReqUserData.java
  4. 1 0
      edu-im/edu-im-server/src/main/java/com/keao/edu/im/controller/RoomController.java
  5. 11 1
      edu-user/edu-user-client-api/src/main/java/com/keao/edu/user/api/entity/ExamRoom.java
  6. 13 0
      edu-user/edu-user-client-api/src/main/java/com/keao/edu/user/api/entity/ExamRoomStudentRelation.java
  7. 12 0
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/controller/ExamOrderController.java
  8. 1 1
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/controller/ExamRegistrationController.java
  9. 18 4
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/controller/ExamRoomController.java
  10. 8 1
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/controller/ExamRoomStudentRelationController.java
  11. 1 2
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/controller/ExamSongController.java
  12. 0 44
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/controller/WebSocketController.java
  13. 88 71
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/controller/WebSocketServer.java
  14. 8 0
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/dao/ExamOrganizationRelationDao.java
  15. 4 1
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/dao/ExamRegistrationDao.java
  16. 15 1
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/dao/ExamRoomStudentRelationDao.java
  17. 6 0
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/dao/StudentExamResultDao.java
  18. 1 1
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/entity/ExamRegistration.java
  19. 34 0
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/page/ExamSongQueryInfo.java
  20. 8 0
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/service/ExamRoomStudentRelationService.java
  21. 23 8
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/service/impl/ExamRegistrationPaymentServiceImpl.java
  22. 17 14
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/service/impl/ExamRegistrationServiceImpl.java
  23. 32 0
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/service/impl/ExamRoomStudentRelationServiceImpl.java
  24. 2 2
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/service/impl/ExaminationBasicServiceImpl.java
  25. 4 2
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/service/impl/OrganizationServiceImpl.java
  26. 7 4
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/service/impl/TenantInfoServiceImpl.java
  27. 6 0
      edu-user/edu-user-server/src/main/resources/config/mybatis/ExamOrganizationRelationMapper.xml
  28. 25 5
      edu-user/edu-user-server/src/main/resources/config/mybatis/ExamRegistrationMapper.xml
  29. 21 5
      edu-user/edu-user-server/src/main/resources/config/mybatis/ExamRoomStudentRelationMapper.xml
  30. 12 0
      edu-user/edu-user-server/src/main/resources/config/mybatis/ExamSongMapper.xml
  31. 1 1
      edu-user/edu-user-server/src/main/resources/config/mybatis/OrganizationMapper.xml
  32. 5 2
      edu-user/edu-user-server/src/main/resources/config/mybatis/StudentExamResultMapper.xml

+ 5 - 14
edu-im/edu-im-api/src/main/java/com/keao/edu/im/api/client/ImFeignService.java

@@ -2,6 +2,7 @@ package com.keao.edu.im.api.client;
 
 import java.util.List;
 
+import com.keao.edu.im.api.entity.*;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.http.MediaType;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -9,10 +10,6 @@ import org.springframework.web.bind.annotation.RequestBody;
 
 import com.keao.edu.common.config.FeignConfiguration;
 import com.keao.edu.im.api.client.callback.ImFeignServiceFallback;
-import com.keao.edu.im.api.entity.ImGroupModel;
-import com.keao.edu.im.api.entity.ImPrivateMessage;
-import com.keao.edu.im.api.entity.ImResult;
-import com.keao.edu.im.api.entity.ImUserModel;
 
 @FeignClient(name = "im-server", configuration = FeignConfiguration.class, fallback = ImFeignServiceFallback.class)
 public interface ImFeignService {
@@ -95,19 +92,13 @@ public interface ImFeignService {
 	 * @return
 	 */
 	@PostMapping(value = "private/send")
-	//body模板
-	//{"senderId":"325","targetId":[1094986],"objectName":"RC:TxtMsg",
-	// "content":{"content":"www.baidu.com"}}
 	Object privateSend(@RequestBody ImPrivateMessage privateMessage);
 
 	/**
-	 * 发送群组自定义消息
-	 * @param groupMessage
+	 * 发送私聊消息
+	 * @param reqUserData
 	 * @return
 	 */
-//	@PostMapping(value = "private/sendCustom")
-	//body模板
-	//{"senderId":"325","targetId":[1094986],"objectName":"RC:TxtMsg",
-	// "content":{"content":"www.baidu.com"}}
-//	Object privateSendCustom(@RequestBody ImGroupMessage groupMessage);
+	@PostMapping(value = "room/leave")
+	void leaveRoom(@RequestBody ReqUserData reqUserData);
 }

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

@@ -2,13 +2,10 @@ package com.keao.edu.im.api.client.callback;
 
 import java.util.List;
 
+import com.keao.edu.im.api.entity.*;
 import org.springframework.stereotype.Component;
 
 import com.keao.edu.im.api.client.ImFeignService;
-import com.keao.edu.im.api.entity.ImGroupModel;
-import com.keao.edu.im.api.entity.ImPrivateMessage;
-import com.keao.edu.im.api.entity.ImResult;
-import com.keao.edu.im.api.entity.ImUserModel;
 
 @Component
 public class ImFeignServiceFallback implements ImFeignService {
@@ -62,6 +59,11 @@ public class ImFeignServiceFallback implements ImFeignService {
     public Object privateSend(ImPrivateMessage privateMessage) {
         return null;
     }
+
+    @Override
+    public void leaveRoom(ReqUserData reqUserData) {
+
+    }
 /*
     @Override
     public Object privateSendCustom(ImGroupMessage groupMessage) {

+ 24 - 10
edu-im/edu-im-server/src/main/java/com/keao/edu/im/pojo/ReqUserData.java → edu-im/edu-im-api/src/main/java/com/keao/edu/im/api/entity/ReqUserData.java

@@ -1,11 +1,6 @@
-package com.keao.edu.im.pojo;
+package com.keao.edu.im.api.entity;
 
-import lombok.Data;
 
-/**
- * Created by weiqinxiao on 2019/3/1.
- */
-@Data
 public class ReqUserData {
 	private String userName;
 	private String roomId;
@@ -13,41 +8,60 @@ public class ReqUserData {
 	private boolean audience;
 	private boolean disableCamera;
 	private boolean musicMode;
-	public boolean isMusicMode() {
-		return musicMode;
+
+	public ReqUserData(String roomId, String userId) {
+		this.roomId = roomId;
+		this.userId = userId;
 	}
-	public void setMusicMode(boolean musicMode) {
-		this.musicMode = musicMode;
+
+	public ReqUserData() {
 	}
+
 	public String getUserName() {
 		return userName;
 	}
+
 	public void setUserName(String userName) {
 		this.userName = userName;
 	}
+
 	public String getRoomId() {
 		return roomId;
 	}
+
 	public void setRoomId(String roomId) {
 		this.roomId = roomId;
 	}
+
 	public String getUserId() {
 		return userId;
 	}
+
 	public void setUserId(String userId) {
 		this.userId = userId;
 	}
+
 	public boolean isAudience() {
 		return audience;
 	}
+
 	public void setAudience(boolean audience) {
 		this.audience = audience;
 	}
+
 	public boolean isDisableCamera() {
 		return disableCamera;
 	}
+
 	public void setDisableCamera(boolean disableCamera) {
 		this.disableCamera = disableCamera;
 	}
 
+	public boolean isMusicMode() {
+		return musicMode;
+	}
+
+	public void setMusicMode(boolean musicMode) {
+		this.musicMode = musicMode;
+	}
 }

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

@@ -2,6 +2,7 @@ package com.keao.edu.im.controller;
 
 import com.alibaba.fastjson.JSONObject;
 import com.keao.edu.auth.api.client.SysUserFeignService;
+import com.keao.edu.im.api.entity.ReqUserData;
 import com.keao.edu.im.common.ApiException;
 import com.keao.edu.im.common.BaseResponse;
 import com.keao.edu.im.common.ErrorEnum;

+ 11 - 1
edu-user/edu-user-client-api/src/main/java/com/keao/edu/user/api/entity/ExamRoom.java

@@ -52,6 +52,8 @@ public class ExamRoom {
 
 	private Integer organId;
 
+	private Integer openFlag;
+
 	private YesOrNoEnum examPlanPushFlag;
 
 	private Integer examRoomStudentNum;
@@ -66,7 +68,15 @@ public class ExamRoom {
 	
 	/**  */
 	private String tenantId;
-	
+
+	public Integer getOpenFlag() {
+		return openFlag;
+	}
+
+	public void setOpenFlag(Integer openFlag) {
+		this.openFlag = openFlag;
+	}
+
 	public void setId(Long id){
 		this.id = id;
 	}

+ 13 - 0
edu-user/edu-user-client-api/src/main/java/com/keao/edu/user/api/entity/ExamRoomStudentRelation.java

@@ -4,6 +4,8 @@ import com.keao.edu.common.enums.YesOrNoEnum;
 import io.swagger.annotations.ApiModelProperty;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 
+import java.util.Date;
+
 /**
  * 对应数据库表(exam_room_student_relation):
  */
@@ -23,6 +25,9 @@ public class ExamRoomStudentRelation {
 	@ApiModelProperty(value = "学员编号")
 	private Integer studentId;
 
+	@ApiModelProperty(value = "签到时间")
+	private java.util.Date signInTime;
+
 	private java.util.Date createTime;
 
 	private java.util.Date updateTime;
@@ -32,6 +37,14 @@ public class ExamRoomStudentRelation {
 	@ApiModelProperty(value = "房间是否开启")
 	private YesOrNoEnum classroomSwitch;
 
+	public Date getSignInTime() {
+		return signInTime;
+	}
+
+	public void setSignInTime(Date signInTime) {
+		this.signInTime = signInTime;
+	}
+
 	public YesOrNoEnum getClassroomSwitch() {
 		return classroomSwitch;
 	}

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

@@ -189,6 +189,18 @@ public class ExamOrderController extends BaseController {
         return msg;
     }
 
+    @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){

+ 1 - 1
edu-user/edu-user-server/src/main/java/com/keao/edu/user/controller/ExamRegistrationController.java

@@ -55,7 +55,7 @@ public class ExamRegistrationController extends BaseController {
                 return failed("用户信息异常");
             }
             queryInfo.setOrganId(employee.getOrganId());
-        }else{
+        }else if(sysUser.getIsSuperAdmin()){
             queryInfo.setOrganId(null);
         }
         return succeed(examRegistrationService.queryExamRegistrationStudents(queryInfo));

+ 18 - 4
edu-user/edu-user-server/src/main/java/com/keao/edu/user/controller/ExamRoomController.java

@@ -9,9 +9,11 @@ import com.keao.edu.user.api.entity.ExamRoom;
 import com.keao.edu.user.dto.ExamRoomDto;
 import com.keao.edu.user.dto.ExamRoomStatisticsDto;
 import com.keao.edu.user.entity.Employee;
+import com.keao.edu.user.entity.Teacher;
 import com.keao.edu.user.page.ExamRoomQueryInfo;
 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;
@@ -31,17 +33,19 @@ public class ExamRoomController extends BaseController {
     private SysUserFeignService sysUserFeignService;
     @Autowired
     private EmployeeService employeeService;
+    @Autowired
+    private TeacherService teacherService;
 
     @ApiOperation("分页查询监考列表")
     @GetMapping(value = "/list")
     public HttpResponseResult<PageInfo<ExamRoomDto>> getList(ExamRoomQueryInfo queryInfo) {
         SysUser sysUser = sysUserFeignService.queryUserInfo();
-        if(!sysUser.getIsSuperAdmin()&&Objects.isNull(queryInfo.getOrganId())){
-            Employee employee = employeeService.get(sysUser.getId());
-            if(Objects.isNull(employee)){
+        if(!sysUser.getIsSuperAdmin() && Objects.isNull(queryInfo.getOrganId())){
+            Teacher teacher = teacherService.get(sysUser.getId());
+            if(Objects.isNull(teacher)){
                 return failed("用户信息异常");
             }
-            queryInfo.setOrganId(employee.getOrganId());
+            queryInfo.setOrganId(teacher.getOrganId());
         }
         return succeed(examRoomService.queryExamRoomPage(queryInfo));
     }
@@ -110,6 +114,16 @@ public class ExamRoomController extends BaseController {
         return succeed(examRoomService.updateExamRoom(examRoom));
     }
 
+    @ApiOperation("教室状态变更")
+    @PostMapping(value = "/openExamRoom")
+    public HttpResponseResult<ExamRoom> openExamRoom(Long examRoomId,Integer openFlag){
+        ExamRoom examRoom = new ExamRoom();
+        examRoom.setId(examRoomId);
+        examRoom.setOpenFlag(openFlag);
+        examRoomService.update(examRoom);
+        return succeed();
+    }
+
     @ApiOperation("删除教室")
     @PostMapping(value = "/deleteExamRooms")
     public HttpResponseResult deleteExamRooms(String examRoomIds){

+ 8 - 1
edu-user/edu-user-server/src/main/java/com/keao/edu/user/controller/ExamRoomStudentRelationController.java

@@ -33,11 +33,18 @@ public class ExamRoomStudentRelationController extends BaseController {
     @Autowired
     private EmployeeService employeeService;
 
-    @ApiOperation("开启/关闭教室")
+    /*@ApiOperation("开启/关闭教室")
     @GetMapping(value = "/switchClassRoom")
     public HttpResponseResult switchClassRoom(Integer openFlag,Integer examinationBasicId,Integer studentId) {
         examRoomStudentRelationService.switchClassRoom(openFlag,examinationBasicId,studentId);
         return succeed();
+    }*/
+
+    @ApiOperation("下一位")
+    @PostMapping(value = "/nextBit")
+    public HttpResponseResult nextBit(Long nextExamRoomStudentRelationId,Long examRoomStudentRelationId,Integer examStatus) {
+        examRoomStudentRelationService.nextBit(nextExamRoomStudentRelationId,examRoomStudentRelationId,examStatus);
+        return succeed();
     }
 
     @ApiOperation("获取教室学员关联")

+ 1 - 2
edu-user/edu-user-server/src/main/java/com/keao/edu/user/controller/ExamSongController.java

@@ -3,7 +3,6 @@ package com.keao.edu.user.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.common.page.QueryInfo;
 import com.keao.edu.common.tenant.TenantContextHolder;
 import com.keao.edu.user.entity.ExamSong;
 import com.keao.edu.user.page.ExamSongQueryInfo;
@@ -31,7 +30,7 @@ public class ExamSongController extends BaseController {
 
     @ApiOperation("分页查询")
     @GetMapping(value = "/list")
-    public HttpResponseResult<PageInfo<ExamSong>> getList(QueryInfo queryInfo) {
+    public HttpResponseResult<PageInfo<ExamSong>> getList(ExamSongQueryInfo queryInfo) {
         return succeed(examSongService.queryPage(queryInfo));
     }
 

+ 0 - 44
edu-user/edu-user-server/src/main/java/com/keao/edu/user/controller/WebSocketController.java

@@ -1,44 +0,0 @@
-package com.keao.edu.user.controller;
-
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.io.IOException;
-
-@RestController
-@RequestMapping("/api/ws")
-public class WebSocketController {
-
-    /**
-     * 群发消息内容
-     * @param message
-     * @return
-     */
-    @RequestMapping(value="/sendAll", method= RequestMethod.GET)
-    public String sendAllMessage(@RequestParam(required=true) String message){
-        try {
-            WebSocketServer.BroadCastInfo(message);
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return "ok";
-    }
-
-    /**
-     * 指定会话ID发消息
-     * @param message 消息内容
-     * @param id 连接会话ID
-     * @return
-     */
-    @RequestMapping(value="/sendOne", method=RequestMethod.GET)
-    public String sendOneMessage(@RequestParam(required=true) String message,@RequestParam(required=true) String id){
-        try {
-            WebSocketServer.SendMessage(message,id);
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return "ok";
-    }
-}

+ 88 - 71
edu-user/edu-user-server/src/main/java/com/keao/edu/user/controller/WebSocketServer.java

@@ -1,122 +1,139 @@
 package com.keao.edu.user.controller;
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
 
-import javax.annotation.PostConstruct;
 import javax.websocket.*;
+import javax.websocket.server.PathParam;
 import javax.websocket.server.ServerEndpoint;
 import java.io.IOException;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.ConcurrentHashMap;
 
-@ServerEndpoint(value = "/ws/asset")
+@ServerEndpoint(value = "/ws/{userId}")
 @Component
 public class WebSocketServer {
 
-    @PostConstruct
-    public void init() {
-        System.out.println("websocket 加载");
-    }
     private static Logger log = LoggerFactory.getLogger(WebSocketServer.class);
-    private static final AtomicInteger OnlineCount = new AtomicInteger(0);
-    // concurrent包的线程安全Set,用来存放每个客户端对应的Session对象。
-    private static CopyOnWriteArraySet<Session> SessionSet = new CopyOnWriteArraySet<Session>();
-
+    /**静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。*/
+    private static int onlineCount = 0;
+    /**concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。*/
+    private static ConcurrentHashMap<String,WebSocketServer> webSocketMap = new ConcurrentHashMap<>();
+    /**与某个客户端的连接会话,需要通过它来给客户端发送数据*/
+    private Session session;
+    /**接收userId*/
+    private String userId="";
 
     /**
-     * 连接建立成功调用的方法
-     */
+     * 连接建立成功调用的方法*/
     @OnOpen
-    public void onOpen(Session session) {
-        SessionSet.add(session);
-        int cnt = OnlineCount.incrementAndGet(); // 在线数加1
-        log.info("有连接加入,当前连接数为:{}", cnt);
-        SendMessage(session, "连接成功");
+    public void onOpen(Session session,@PathParam("userId") String userId) {
+        this.session = session;
+        this.userId=userId;
+        if(webSocketMap.containsKey(userId)){
+            webSocketMap.remove(userId);
+            webSocketMap.put(userId,this);
+            //加入set中
+        }else{
+            webSocketMap.put(userId,this);
+            //加入set中
+            addOnlineCount();
+            //在线数加1
+        }
+
+        log.info("用户连接:"+userId+",当前在线人数为:" + getOnlineCount());
+
+        try {
+            sendMessage("连接成功");
+        } catch (IOException e) {
+            log.error("用户:"+userId+",网络异常!!!!!!");
+        }
     }
 
     /**
      * 连接关闭调用的方法
      */
     @OnClose
-    public void onClose(Session session) {
-        SessionSet.remove(session);
-        int cnt = OnlineCount.decrementAndGet();
-        log.info("有连接关闭,当前连接数为:{}", cnt);
+    public void onClose() {
+        if(webSocketMap.containsKey(userId)){
+            webSocketMap.remove(userId);
+            //从set中删除
+            subOnlineCount();
+        }
+        log.info("用户退出:"+userId+",当前在线人数为:" + getOnlineCount());
     }
 
     /**
      * 收到客户端消息后调用的方法
      *
-     * @param message
-     *            客户端发送过来的消息
-     */
+     * @param message 客户端发送过来的消息*/
     @OnMessage
     public void onMessage(String message, Session session) {
-        log.info("来自客户端的消息:{}",message);
-        SendMessage(session, "收到消息,消息内容:"+message);
-
+        log.info("用户消息:"+userId+",报文:"+message);
+        //可以群发消息
+        //消息保存到数据库、redis
+        if(StringUtils.isNotBlank(message)){
+            try {
+                //解析发送的报文
+                JSONObject jsonObject = JSON.parseObject(message);
+                //追加发送人(防止串改)
+                jsonObject.put("fromUserId",this.userId);
+                String toUserId=jsonObject.getString("toUserId");
+                //传送给对应toUserId用户的websocket
+                if(StringUtils.isNotBlank(toUserId)&&webSocketMap.containsKey(toUserId)){
+                    webSocketMap.get(toUserId).sendMessage(jsonObject.toJSONString());
+                }else{
+                    log.error("请求的userId:"+toUserId+"不在该服务器上");
+                    //否则不在这个服务器上,发送到mysql或者redis
+                }
+            }catch (Exception e){
+                e.printStackTrace();
+            }
+        }
     }
 
     /**
-     * 出现错误
+     *
      * @param session
      * @param error
      */
     @OnError
     public void onError(Session session, Throwable error) {
-        log.error("发生错误:{},Session ID: {}",error.getMessage(),session.getId());
+        log.error("用户错误:"+this.userId+",原因:"+error.getMessage());
         error.printStackTrace();
     }
-
     /**
-     * 发送消息,实践表明,每次浏览器刷新,session会发生变化。
-     * @param session
-     * @param message
+     * 实现服务器主动推送
      */
-    public static void SendMessage(Session session, String message) {
-        try {
-            session.getBasicRemote().sendText(String.format("%s (From Server,Session ID=%s)",message,session.getId()));
-        } catch (IOException e) {
-            log.error("发送消息出错:{}", e.getMessage());
-            e.printStackTrace();
-        }
+    public void sendMessage(String message) throws IOException {
+        this.session.getBasicRemote().sendText(message);
     }
 
+
     /**
-     * 群发消息
-     * @param message
-     * @throws IOException
-     */
-    public static void BroadCastInfo(String message) throws IOException {
-        for (Session session : SessionSet) {
-            if(session.isOpen()){
-                SendMessage(session, message);
-            }
+     * 发送自定义消息
+     * */
+    public static void sendInfo(String message,@PathParam("userId") String userId) throws IOException {
+        log.info("发送消息到:"+userId+",报文:"+message);
+        if(StringUtils.isNotBlank(userId)&&webSocketMap.containsKey(userId)){
+            webSocketMap.get(userId).sendMessage(message);
+        }else{
+            log.error("用户"+userId+",不在线!");
         }
     }
 
-    /**
-     * 指定Session发送消息
-     * @param sessionId
-     * @param message
-     * @throws IOException
-     */
-    public static void SendMessage(String message,String sessionId) throws IOException {
-        Session session = null;
-        for (Session s : SessionSet) {
-            if(s.getId().equals(sessionId)){
-                session = s;
-                break;
-            }
-        }
-        if(session!=null){
-            SendMessage(session, message);
-        }
-        else{
-            log.warn("没有找到你指定ID的会话:{}",sessionId);
-        }
+    public static synchronized int getOnlineCount() {
+        return onlineCount;
+    }
+
+    public static synchronized void addOnlineCount() {
+        WebSocketServer.onlineCount++;
     }
 
+    public static synchronized void subOnlineCount() {
+        WebSocketServer.onlineCount--;
+    }
 }

+ 8 - 0
edu-user/edu-user-server/src/main/java/com/keao/edu/user/dao/ExamOrganizationRelationDao.java

@@ -106,4 +106,12 @@ public interface ExamOrganizationRelationDao extends BaseDAO<Long, ExamOrganizat
      */
     ExamOrganizationRelation getExamOrganizationRelation(@Param("examId") Long examId, @Param("OrganId") Integer OrganId);
 
+    /**
+     * 获取考级项目关联合作单位信息
+     * @param examId
+     * @param organIds
+     * @return
+     */
+    List<ExamOrganizationRelation> getExamOrganizationRelations(@Param("examId") Long examId, @Param("organIds") List<Integer> organIds);
+
 }

+ 4 - 1
edu-user/edu-user-server/src/main/java/com/keao/edu/user/dao/ExamRegistrationDao.java

@@ -7,6 +7,7 @@ import com.keao.edu.user.dto.ExamRegistrationDto;
 import com.keao.edu.user.dto.ExamRegistrationRoomDto;
 import com.keao.edu.user.dto.ExamRegistrationStatisticsDto;
 import com.keao.edu.user.entity.ExamRegistration;
+import com.keao.edu.user.enums.StudentRegistrationStatusEnum;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
@@ -137,6 +138,8 @@ public interface ExamRegistrationDao extends BaseDAO<Long, ExamRegistration> {
      * @param level
      * @return
      */
-    ExamRegistration getRegistration(@Param("examId") Long examId, @Param("studentId") Integer studentId, @Param("subjectId") Integer subjectId, @Param("level") Integer level);
+    ExamRegistration getRegistration(@Param("examId") Long examId, @Param("studentId") Integer studentId,
+                                     @Param("subjectId") Integer subjectId, @Param("level") Integer level,
+                                     @Param("statusEnumList") List<StudentRegistrationStatusEnum> statusEnumList);
 
 }

+ 15 - 1
edu-user/edu-user-server/src/main/java/com/keao/edu/user/dao/ExamRoomStudentRelationDao.java

@@ -1,8 +1,8 @@
 package com.keao.edu.user.dao;
 
 import com.keao.edu.common.dal.BaseDAO;
-import com.keao.edu.user.dto.ExamRoomStudentRelationDto;
 import com.keao.edu.user.api.entity.ExamRoomStudentRelation;
+import com.keao.edu.user.dto.ExamRoomStudentRelationDto;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
@@ -78,4 +78,18 @@ public interface ExamRoomStudentRelationDao extends BaseDAO<Long, ExamRoomStuden
      * @return com.keao.edu.user.api.entity.ExamRoomStudentRelation
      */
     ExamRoomStudentRelation getStudentExamRoom(@Param("registId") Long registId);
+
+    /**
+     * 获取教室
+     * @param roomId
+     * @param currentUserId
+     * @return
+     */
+    ExamRoomStudentRelation findByStudentIdAndRoomId(@Param("roomId") Long roomId, @Param("currentUserId") Integer currentUserId);
+
+    /**
+     * 清除签到时间
+     * @param examRegistrationId
+     */
+    void cleanSignInTime(Long examRegistrationId);
 }

+ 6 - 0
edu-user/edu-user-server/src/main/java/com/keao/edu/user/dao/StudentExamResultDao.java

@@ -40,4 +40,10 @@ public interface StudentExamResultDao extends BaseDAO<Long, StudentExamResult> {
      * @return
      */
     List<Map<Integer, Integer>> countExamNum(@Param("studentIds") List<Integer> studentIds, @Param("tenantId") String tenantId);
+
+    /**
+     * 更改考试状态
+     * @param examRegistrationId
+     */
+    void endExam(Long examRegistrationId);
 }

+ 1 - 1
edu-user/edu-user-server/src/main/java/com/keao/edu/user/entity/ExamRegistration.java

@@ -91,7 +91,7 @@ public class ExamRegistration {
 	private java.util.Date updateTime;
 
 	private String tenantId;
-	
+
 	public void setId(Integer id){
 		this.id = id;
 	}

+ 34 - 0
edu-user/edu-user-server/src/main/java/com/keao/edu/user/page/ExamSongQueryInfo.java

@@ -1,6 +1,7 @@
 package com.keao.edu.user.page;
 
 import com.keao.edu.common.page.QueryInfo;
+import com.keao.edu.user.enums.SongTypeEnum;
 import io.swagger.annotations.ApiModelProperty;
 
 public class ExamSongQueryInfo extends QueryInfo {
@@ -11,6 +12,15 @@ public class ExamSongQueryInfo extends QueryInfo {
     @ApiModelProperty(value = "级别")
     private Integer level;
 
+    @ApiModelProperty(value = "曲目名")
+    private String songName;
+
+    @ApiModelProperty(value = "作者名")
+    private String songAuthor;
+
+    @ApiModelProperty(value = "曲目类别")
+    private SongTypeEnum type;
+
     public Integer getLevel() {
         return level;
     }
@@ -26,4 +36,28 @@ public class ExamSongQueryInfo extends QueryInfo {
     public void setSubjectList(Integer subjectList) {
         this.subjectList = subjectList;
     }
+
+    public String getSongName() {
+        return songName;
+    }
+
+    public void setSongName(String songName) {
+        this.songName = songName;
+    }
+
+    public String getSongAuthor() {
+        return songAuthor;
+    }
+
+    public void setSongAuthor(String songAuthor) {
+        this.songAuthor = songAuthor;
+    }
+
+    public SongTypeEnum getType() {
+        return type;
+    }
+
+    public void setType(SongTypeEnum type) {
+        this.type = type;
+    }
 }

+ 8 - 0
edu-user/edu-user-server/src/main/java/com/keao/edu/user/service/ExamRoomStudentRelationService.java

@@ -63,4 +63,12 @@ public interface ExamRoomStudentRelationService extends BaseService<Long, ExamRo
      * @return
      */
     ExamRoomStudentRelation getExamRoomStudentRelation(Integer basicId, String roomId, Integer studentId);
+
+    /**
+     * 下一位
+     * @param nextExamRoomStudentRelationId 下一位学员
+     * @param examRoomStudentRelationId 学员考场关联
+     * @param examStatus 是否完成考试1是0否
+     */
+    void nextBit(Long nextExamRoomStudentRelationId, Long examRoomStudentRelationId, Integer examStatus);
 }

+ 23 - 8
edu-user/edu-user-server/src/main/java/com/keao/edu/user/service/impl/ExamRegistrationPaymentServiceImpl.java

@@ -15,21 +15,20 @@ import com.keao.edu.user.dao.ExamRegistrationPaymentDao;
 import com.keao.edu.user.dto.ExamPaymentInfo;
 import com.keao.edu.user.dto.ExamRegistrationDto;
 import com.keao.edu.user.dto.ExamRegistrationPaymentDto;
-import com.keao.edu.user.dto.StudentExamPaymentDto;
 import com.keao.edu.user.entity.ExamOrganizationRelation;
 import com.keao.edu.user.entity.ExamRegistration;
 import com.keao.edu.user.entity.ExamRegistrationPayment;
+import com.keao.edu.user.entity.Organization;
 import com.keao.edu.user.enums.StudentRegistrationStatusEnum;
 import com.keao.edu.user.enums.TransStatusEnum;
 import com.keao.edu.user.page.ExamRegistrationPaymentQueryInfo;
-import com.keao.edu.user.page.ExamRegistrationQueryInfo;
-import com.keao.edu.user.service.ExamOrganizationRelationService;
 import com.keao.edu.user.service.ExamRegistrationPaymentService;
 import com.keao.edu.user.service.ExamRegistrationService;
 import com.keao.edu.user.service.OrganizationService;
 import com.keao.edu.util.collection.MapUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Isolation;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
@@ -76,7 +75,7 @@ public class ExamRegistrationPaymentServiceImpl extends BaseServiceImpl<Long, Ex
     }
 
     @Override
-    @Transactional(rollbackFor = Exception.class)
+    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
     public ExamRegistrationPayment updateOrder(Map<String, String> rpMap) {
         ExamRegistrationPayment order = examRegistrationPaymentDao.getByOrderNo(rpMap.get("orderNo"));
         if (order == null || !order.getTransStatus().equals(TransStatusEnum.ING)) {
@@ -111,12 +110,27 @@ public class ExamRegistrationPaymentServiceImpl extends BaseServiceImpl<Long, Ex
         }
         //更新报名人数,和报名金额
         ExamOrganizationRelation examOrganizationRelation = examOrganizationRelationDao.getExamOrganizationRelation(examRegistration.getExaminationBasicId(), examRegistration.getOrganId());
-        examOrganizationRelation.setTotalRegistrationStudentNum(examOrganizationRelation.getTotalRegistrationStudentNum() + 1);
-        BigDecimal amount = examOrganizationRelation.getTotalPaymentAmount().add(examRegistration.getLevelFee()).add(examRegistration.getTheoryLevelFee());
-        examOrganizationRelation.setTotalPaymentAmount(amount);
+        examOrganizationRelation.setSelfRegistrationStudentNum(examOrganizationRelation.getSelfRegistrationStudentNum() + 1);
+        BigDecimal amount = examOrganizationRelation.getSelfPaymentAmount().add(examRegistration.getLevelFee()).add(examRegistration.getTheoryLevelFee());
+        examOrganizationRelation.setSelfPaymentAmount(amount);
         if (examOrganizationRelationDao.update(examOrganizationRelation) <= 0) {
             throw new BizException("报名人数报名金额更新失败");
         }
+        Organization organization = organizationService.get(examRegistration.getOrganId());
+
+        List<Integer> parentOrganIds = Arrays.stream(organization.getParentOrganIdTag().split(","))
+                .map(e -> Integer.valueOf(e)).collect(Collectors.toList());
+        List<ExamOrganizationRelation> examOrgans = examOrganizationRelationDao.getExamOrganizationRelations(examRegistration.getExaminationBasicId(), parentOrganIds);
+        for (ExamOrganizationRelation examOrgan : examOrgans) {
+            examOrgan.setTotalRegistrationStudentNum(examOrgan.getTotalRegistrationStudentNum() + 1);
+            BigDecimal totalAmount = examOrgan.getTotalPaymentAmount().add(examRegistration.getLevelFee()).add(examRegistration.getTheoryLevelFee());
+            examOrgan.setTotalPaymentAmount(totalAmount);
+        }
+        int updateNum = examOrganizationRelationDao.batchUpdate(examOrgans);
+        if(updateNum!=examOrgans.size()){
+            throw new BizException("总报名人数报名金额更新失败");
+        }
+
         return order;
     }
 
@@ -151,9 +165,10 @@ public class ExamRegistrationPaymentServiceImpl extends BaseServiceImpl<Long, Ex
     public Boolean closeOrder(String orderNo) {
         ExamRegistrationPayment order = examRegistrationPaymentDao.getByOrderNo(orderNo);
         if (!order.getTransStatus().equals(TransStatusEnum.ING)) {
-            throw new BizException("订单不是待支付状态,请重新报名");
+            throw new BizException("订单不是待支付状态,不能关闭");
         }
         Date nowDate = new Date();
+        order.setMemo("用户主动放弃支付");
         order.setTransStatus(TransStatusEnum.CLOSE);
         order.setUpdateTime(nowDate);
         if (examRegistrationPaymentDao.update(order) <= 0) {

+ 17 - 14
edu-user/edu-user-server/src/main/java/com/keao/edu/user/service/impl/ExamRegistrationServiceImpl.java

@@ -36,8 +36,6 @@ public class ExamRegistrationServiceImpl extends BaseServiceImpl<Long, ExamRegis
     @Autowired
     private ExamRegistrationDao examRegistrationDao;
     @Autowired
-    private StudentDao studentDao;
-    @Autowired
     private ExaminationBasicDao examinationBasicDao;
     @Autowired
     private OrganizationService organizationService;
@@ -83,8 +81,15 @@ public class ExamRegistrationServiceImpl extends BaseServiceImpl<Long, ExamRegis
             throw new BizException("机构不存在");
         }
 
-        ExamRegistration registration = examRegistrationDao.getRegistration(examinationBasic.getId(), examRegistration.getStudentId(), examRegistration.getSubjectId(), examSubjectSong.getLevel());
-        if(registration != null && !registration.getStatus().equals(StudentRegistrationStatusEnum.PAY_WAIT)){
+        List<StudentRegistrationStatusEnum> statusEnumList = new ArrayList<>();
+        statusEnumList.add(StudentRegistrationStatusEnum.AUDIT_WAIT);
+        statusEnumList.add(StudentRegistrationStatusEnum.AUDIT_REJECT);
+        statusEnumList.add(StudentRegistrationStatusEnum.AUDIT_PASS);
+
+        ExamRegistration registration = examRegistrationDao.getRegistration(examinationBasic.getId(),
+                examRegistration.getStudentId(), examRegistration.getSubjectId(), examSubjectSong.getLevel(),
+                statusEnumList);
+        if (registration != null) {
             throw new BizException("该考级相同专业及等级您已报名,请勿重复报名");
         }
 
@@ -112,15 +117,13 @@ public class ExamRegistrationServiceImpl extends BaseServiceImpl<Long, ExamRegis
         examRegistration.setCreateTime(nowDate);
         examRegistration.setUpdateTime(nowDate);
 
-        ExamRegistrationPayment examIngOrder = examRegistrationPaymentService.getExamIngOrder(examinationBasic.getId(), examRegistration.getStudentId());
-        if (examIngOrder != null) {
-            examIngOrder.setTransStatus(TransStatusEnum.CLOSE);
-            examIngOrder.setMemo("用户主动放弃支付");
-            if (examRegistrationPaymentService.update(examIngOrder) <= 0) {
-                throw new BizException("未支付订单关闭失败");
-            }
-            ExamRegistration examReg = examRegistrationDao.get(examIngOrder.getExamRegistrationId());
-            examRegistration.setId(examReg.getId());
+        statusEnumList.clear();
+        statusEnumList.add(StudentRegistrationStatusEnum.AUDIT_WAIT);
+        registration = examRegistrationDao.getRegistration(examinationBasic.getId(),
+                examRegistration.getStudentId(), null, null,
+                statusEnumList);
+        if (registration != null) {
+            examRegistration.setId(registration.getId());
             examRegistrationDao.update(examRegistration);
         } else {
             examRegistrationDao.insert(examRegistration);
@@ -163,7 +166,7 @@ public class ExamRegistrationServiceImpl extends BaseServiceImpl<Long, ExamRegis
         Map<String, Object> params = new HashMap<String, Object>();
         MapUtil.populateMap(params, queryInfo);
 
-        if(Objects.nonNull(queryInfo.getExamId())){
+        if (Objects.nonNull(queryInfo.getExamId())) {
             List<Integer> nextLevelOrganIds = organizationService.getChildOrganIds(queryInfo.getOrganId(), true);
             params.put("organIds", nextLevelOrganIds);
             params.put("organId", null);

+ 32 - 0
edu-user/edu-user-server/src/main/java/com/keao/edu/user/service/impl/ExamRoomStudentRelationServiceImpl.java

@@ -8,6 +8,8 @@ import com.keao.edu.common.page.PageInfo;
 import com.keao.edu.common.service.IdGeneratorService;
 import com.keao.edu.common.service.impl.BaseServiceImpl;
 import com.keao.edu.common.tenant.TenantContextHolder;
+import com.keao.edu.im.api.client.ImFeignService;
+import com.keao.edu.im.api.entity.ReqUserData;
 import com.keao.edu.user.api.entity.ExamRoom;
 import com.keao.edu.user.api.entity.ExamRoomStudentRelation;
 import com.keao.edu.user.api.enums.ExamModeEnum;
@@ -50,6 +52,8 @@ public class ExamRoomStudentRelationServiceImpl extends BaseServiceImpl<Long, Ex
 	private ExamRegistrationDao examRegistrationDao;
 	@Autowired
 	private ExamTeacherSalaryService examTeacherSalaryService;
+	@Autowired
+	private ImFeignService imFeignService;
 
 	@Override
 	public BaseDAO<Long, ExamRoomStudentRelation> getDAO() {
@@ -244,4 +248,32 @@ public class ExamRoomStudentRelationServiceImpl extends BaseServiceImpl<Long, Ex
 	public ExamRoomStudentRelation getExamRoomStudentRelation(Integer basicId, String roomId, Integer studentId) {
 		return examRoomStudentRelationDao.getExamRoomStudentRelation(basicId,roomId,studentId);
 	}
+
+	@Override
+	public void nextBit(Long nextExamRoomStudentRelationId, Long currentExamRoomStudentRelationId, Integer examStatus) {
+		if(currentExamRoomStudentRelationId != null){
+			ExamRoomStudentRelation examRoomStudentRelation = examRoomStudentRelationDao.get(currentExamRoomStudentRelationId);
+			Long roomId = examRoomStudentRelation.getExamRoomId();
+			//将当前学员退出教室并添加参考状态,如果考试未完成,清除签到时间,重新签到
+			imFeignService.leaveRoom(new ReqUserData(roomId.toString(),examRoomStudentRelation.getStudentId().toString()));
+			if(examStatus == 0){
+				//未完成
+				examRoomStudentRelationDao.cleanSignInTime(examRoomStudentRelation.getExamRegistrationId());
+			}else {
+				//结束考试
+				studentExamResultDao.endExam(examRoomStudentRelation.getExamRegistrationId());
+			}
+			//关闭学员房间入口
+			examRoomStudentRelation.setClassroomSwitch(YesOrNoEnum.NO);
+			examRoomStudentRelationDao.update(examRoomStudentRelation);
+		}
+		if(nextExamRoomStudentRelationId != null){
+			ExamRoomStudentRelation examRoomStudentRelation = examRoomStudentRelationDao.get(nextExamRoomStudentRelationId);
+			//开启学员房间入口
+			examRoomStudentRelation.setClassroomSwitch(YesOrNoEnum.YES);
+			examRoomStudentRelationDao.update(examRoomStudentRelation);
+			//推送消息
+
+		}
+	}
 }

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

@@ -162,14 +162,14 @@ public class ExaminationBasicServiceImpl extends BaseServiceImpl<Long, Examinati
             List<Long> examIds = dataList.stream().map(ExaminationBasicDto::getId).collect(Collectors.toList());
             List<ExamOrganizationRelation> examOrgans = new ArrayList<>();
             if (!CollectionUtils.isEmpty(examIds)) {
-                examOrganizationRelationDao.getWithExams(examIds);
+                examOrgans = examOrganizationRelationDao.getWithExams(examIds);
             }
             Map<Integer, List<ExamOrganizationRelation>> examOrgansMap = new HashMap<>();
             if (!CollectionUtils.isEmpty(examOrgans)) {
                 examOrgansMap = examOrgans.stream().collect(Collectors.groupingBy(ExamOrganizationRelation::getExaminationBasicId));
             }
             for (ExaminationBasicDto examinationBasicDto : dataList) {
-                List<ExamOrganizationRelation> examOrganizationRelations = examOrgansMap.get(examinationBasicDto.getId());
+                List<ExamOrganizationRelation> examOrganizationRelations = examOrgansMap.get(examinationBasicDto.getId().intValue());
                 if (CollectionUtils.isEmpty(examOrganizationRelations)) {
                     continue;
                 }

+ 4 - 2
edu-user/edu-user-server/src/main/java/com/keao/edu/user/service/impl/OrganizationServiceImpl.java

@@ -79,12 +79,13 @@ public class OrganizationServiceImpl extends BaseServiceImpl<Integer, Organizati
 			}
 			Organization organization = organDao.get(user.getId());
 			if(organization == null){
-				organ.setParentOrganIdTag(currentOrganization.getParentOrganIdTag() + "," + user.getId());
 				if(StringUtils.isEmpty(user.getPassword())){
 					sysUser.setPassword(new BCryptPasswordEncoder().encode("123456"));
 				}
 				organ.setUserId(user.getId());
 				organDao.insert(organ);
+				organ.setParentOrganIdTag(currentOrganization.getParentOrganIdTag() + "," + organ.getId());
+				organDao.update(organ);
 				//新增用户角色
 				if(sysUser.getRoles() != null){
 					sysUserDao.batchAddEmployeeRole(user.getId(),sysUser.getRoles());
@@ -125,9 +126,10 @@ public class OrganizationServiceImpl extends BaseServiceImpl<Integer, Organizati
 		sysUser.setPhone(organ.getContactPhone());
 		sysUserDao.insert(sysUser);
 
-		organ.setParentOrganIdTag(currentOrganization.getParentOrganIdTag() + "," + sysUser.getId());
 		organ.setUserId(sysUser.getId());
 		organDao.insert(organ);
+		organ.setParentOrganIdTag(currentOrganization.getParentOrganIdTag() + "," + organ.getId());
+		organDao.update(organ);
 		//新增用户角色
 		sysUserDao.delEmployeeRole(sysUser.getId());
 		if(sysUser.getRoles() != null){

+ 7 - 4
edu-user/edu-user-server/src/main/java/com/keao/edu/user/service/impl/TenantInfoServiceImpl.java

@@ -104,12 +104,11 @@ public class TenantInfoServiceImpl extends BaseServiceImpl<Integer, TenantInfo>
 			throw new BizException("机构不存在");
 		}
 		SysUser sysUser = sysUserDao.queryByPhone(existTenantInfo.getContactPhone());
-		if(Objects.isNull(sysUser)){
-			throw new BizException("机构账户不存在");
+		if(Objects.nonNull(sysUser) && !newTenantInfo.getContactPhone().equals(sysUser.getPhone())){
+			throw new BizException("手机号已被占用");
 		}
+		Organization organization = organizationDao.findByUserId(sysUser.getId());
 		if(newTenantInfo.getRoleIds() != null){
-
-//			Set<Integer> roleIds = Arrays.stream(newTenantInfo.getRoleIds().split(",")).map(e -> Integer.valueOf(e)).collect(Collectors.toSet());
 			//删除当前用户角色
 			sysUserDao.delEmployeeRole(sysUser.getId());
 			//新增用户角色
@@ -117,10 +116,14 @@ public class TenantInfoServiceImpl extends BaseServiceImpl<Integer, TenantInfo>
 		}
 		if(StringUtils.isNotBlank(newTenantInfo.getContactName())){
 			sysUser.setRealName(newTenantInfo.getContactName());
+			organization.setContactName(newTenantInfo.getContactName());
+			organization.setName(newTenantInfo.getName());
 		}
 		if(StringUtils.isNotBlank(newTenantInfo.getContactPhone())){
 			sysUser.setPhone(newTenantInfo.getContactPhone());
+			organization.setContactPhone(newTenantInfo.getContactPhone());
 		}
+		organizationDao.update(organization);
 		sysUserDao.update(sysUser);
 		imFeignService.update(new ImUserModel(sysUser.getId().toString(),sysUser.getRealName(),sysUser.getAvatar()));
 		tenantInfoDao.update(newTenantInfo);

+ 6 - 0
edu-user/edu-user-server/src/main/resources/config/mybatis/ExamOrganizationRelationMapper.xml

@@ -322,5 +322,11 @@
     <select id="getExamOrganizationRelation" resultMap="ExamOrganizationRelation">
 		SELECT * FROM exam_organization_relation WHERE examination_basic_id_=#{examId} AND organ_id_=#{OrganId} FOR UPDATE
 	</select>
+	<select id="getExamOrganizationRelations" resultMap="ExamOrganizationRelation">
+		SELECT * FROM exam_organization_relation WHERE examination_basic_id_=#{examId} AND organ_id_ IN
+		<foreach collection="organIds" item="organId" separator="," open="(" close=")">
+			#{organId}
+		</foreach>
+	</select>
 
 </mapper>

+ 25 - 5
edu-user/edu-user-server/src/main/resources/config/mybatis/ExamRegistrationMapper.xml

@@ -138,7 +138,6 @@
 
 	<sql id="queryCondition">
 		<where>
-			er.status_ != 'PAY_WAIT' AND er.status_ != 'AUDIT_WAIT'
 			<if test="organIds!=null">
 				AND er.organ_id_ IN
 				<foreach collection="organIds" item="organId" separator="," open="(" close=")">
@@ -313,7 +312,7 @@
 
     <select id="getExamRegistrationStaticsInfo" resultMap="ExamRegistrationStatisticsDto">
 		SELECT
-			SUM( CASE WHEN er.organ_id_ = #{selfOrganId} THEN 1 ELSE 0 END ) totalRegistrationStudentNum,
+			COUNT( er.student_id_ ) totalRegistrationStudentNum,
 			SUM( CASE WHEN er.organ_id_ != #{selfOrganId} THEN 1 ELSE 0 END ) childOrganRegistrationStudentNum,
 			SUM( CASE WHEN er.status_ = 'AUDIT_WAIT' THEN 1 ELSE 0 END ) waitAuditStudentNum,
 			SUM( CASE WHEN er.status_ = 'REFUNDED' THEN 1 ELSE 0 END ) refundedStudentNum
@@ -432,7 +431,28 @@
 		WHERE er.id_ = #{id}
 	</select>
 
-	<select id="getRegistration" resultMap="ExamRegistration">
-		SELECT * FROM exam_registration WHERE examination_basic_id_ = #{examId}  AND student_id_ =#{studentId} AND subject_id_=#{subjectId} AND level_ = #{level} LIMIT 1
-	</select>
+    <select id="getRegistration" resultMap="ExamRegistration">
+        SELECT * FROM exam_registration
+        <where>
+            <if test="examId != null">
+                AND examination_basic_id_ = #{examId}
+            </if>
+            <if test="studentId != null">
+                AND student_id_ =#{studentId}
+            </if>
+            <if test="subjectId != null">
+                AND subject_id_=#{subjectId}
+            </if>
+            <if test="level != null">
+                AND level_ = #{level}
+            </if>
+            <if test="statusEnumList != null">
+                AND status_ IN
+                <foreach collection="statusEnumList" item="status" open="(" close=")" separator=",">
+                    #{status,typeHandler=com.keao.edu.common.dal.CustomEnumTypeHandler}
+                </foreach>
+            </if>
+        </where>
+        LIMIT 1
+    </select>
 </mapper>

+ 21 - 5
edu-user/edu-user-server/src/main/resources/config/mybatis/ExamRoomStudentRelationMapper.xml

@@ -13,6 +13,7 @@
 		<result column="exam_room_id_" property="examRoomId" />
 		<result column="student_id_" property="studentId" />
 		<result column="classroom_switch_" property="classroomSwitch" typeHandler="com.keao.edu.common.dal.CustomEnumTypeHandler"/>
+		<result column="sign_in_time_" property="signInTime" />
 		<result column="create_time_" property="createTime" />
 		<result column="update_time_" property="updateTime" />
 		<result column="tenant_id_" property="tenantId" />
@@ -36,15 +37,19 @@
 	
 	<!-- 向数据库增加一条记录 -->
 	<insert id="insert" parameterType="com.keao.edu.user.api.entity.ExamRoomStudentRelation" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
-		INSERT INTO exam_room_student_relation (id_,examination_basic_id_,exam_registration_id_,exam_room_id_,student_id_,create_time_,update_time_,tenant_id_)
-		VALUES(#{id},#{examinationBasicId},#{examRegistrationId},#{examRoomId},#{studentId},NOW(),NOW(),#{tenantId})
+		INSERT INTO exam_room_student_relation (id_,examination_basic_id_,exam_registration_id_,
+		exam_room_id_,student_id_,create_time_,update_time_,tenant_id_,sign_in_time_)
+		VALUES(#{id},#{examinationBasicId},#{examRegistrationId},#{examRoomId},
+		#{studentId},NOW(),NOW(),#{tenantId},#{signInTime})
 	</insert>
 
 	<insert id="batchInsert" parameterType="com.keao.edu.user.api.entity.ExamRoomStudentRelation" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
-		INSERT INTO exam_room_student_relation (examination_basic_id_,exam_registration_id_,exam_room_id_,student_id_,create_time_,update_time_,tenant_id_)
+		INSERT INTO exam_room_student_relation (examination_basic_id_,exam_registration_id_,
+		exam_room_id_,student_id_,create_time_,update_time_,tenant_id_,sign_in_time_)
 		VALUES
 		<foreach collection="roomStudents" item="roomStudent" separator=",">
-			(#{roomStudent.examinationBasicId},#{roomStudent.examRegistrationId},#{roomStudent.examRoomId},#{roomStudent.studentId},NOW(),NOW(),#{roomStudent.tenantId})
+			(#{roomStudent.examinationBasicId},#{roomStudent.examRegistrationId},
+			#{roomStudent.examRoomId},#{roomStudent.studentId},NOW(),NOW(),#{roomStudent.tenantId},#{roomStudent.signInTime})
 		</foreach>
 	</insert>
 	
@@ -55,6 +60,9 @@
 			<if test="examinationBasicId != null">
 				examination_basic_id_ = #{examinationBasicId},
 			</if>
+			<if test="signInTime != null">
+				sign_in_time_ = #{signInTime},
+			</if>
 			<if test="examRegistrationId != null">
 				exam_registration_id_ = #{examRegistrationId},
 			</if>
@@ -77,8 +85,12 @@
 		UPDATE exam_room_student_relation SET classroom_switch_ = #{openFlag},update_time_ = NOW()
 		WHERE examination_basic_id_ = #{examinationBasicId} AND student_id_ = #{studentId}
 	</update>
+	<update id="cleanSignInTime">
+		UPDATE exam_room_student_relation SET sign_in_time_ = NULL,update_time_ = NOW()
+		WHERE exam_registration_id_ = #{examRegistrationId}
+	</update>
 
-    <!-- 根据主键删除一条记录 -->
+	<!-- 根据主键删除一条记录 -->
 	<delete id="delete" >
 		DELETE FROM exam_room_student_relation WHERE id_ = #{id} 
 	</delete>
@@ -174,4 +186,8 @@
     <select id="getStudentExamRoom" resultMap="ExamRoomStudentRelation">
 		SELECT * FROM exam_room_student_relation WHERE exam_registration_id_=#{registId}
     </select>
+	<select id="findByStudentIdAndRoomId" resultMap="ExamRoomStudentRelation">
+		SELECT ersr.* FROM exam_room_student_relation ersr
+		WHERE ersr.exam_room_id_ = #{roomId} AND ersr.student_id_ = #{currentUserId} LIMIT 1
+	</select>
 </mapper>

+ 12 - 0
edu-user/edu-user-server/src/main/resources/config/mybatis/ExamSongMapper.xml

@@ -82,6 +82,18 @@
 			<if test="subjectList!=null">
 				AND FIND_IN_SET(#{subjectList}, es.subject_list_)
 			</if>
+			<if test="songAuthor!=null">
+				AND es.song_author_ LIKE CONCAT(#{songAuthor}, '%')
+			</if>
+			<if test="level!=null">
+				AND FIND_IN_SET(#{level},level_list_)
+			</if>
+			<if test="type!=null">
+				AND type_=#{type, typeHandler=com.keao.edu.common.dal.CustomEnumTypeHandler}
+			</if>
+			<if test="songName!=null">
+				AND es.song_name_ LIKE CONCAT(#{songName}, '%')
+			</if>
 			<if test="search!=null">
 				AND (es.id_=#{search} OR es.song_name_ LIKE CONCAT('%', #{search}, '%'))
 			</if>

+ 1 - 1
edu-user/edu-user-server/src/main/resources/config/mybatis/OrganizationMapper.xml

@@ -110,7 +110,7 @@
 				AND tenant_id_ = #{tenantId}
 			</if>
 			<if test="organId != null">
-				AND id_ != #{organId}
+				AND parent_organ_id_ = #{organId}
 			</if>
 			<if test="organIds != null">
 				AND id_ IN

+ 5 - 2
edu-user/edu-user-server/src/main/resources/config/mybatis/StudentExamResultMapper.xml

@@ -92,8 +92,11 @@
 				update_time_ = NOW()
 		</set> WHERE id_ = #{id}
 	</update>
-	
-	<!-- 根据主键删除一条记录 -->
+    <update id="endExam">
+		UPDATE student_exam_result SET is_finished_exam_ = 1 AND update_time_ = NOW() WHERE exam_registration_id_ = #{examRegistrationId}
+	</update>
+
+    <!-- 根据主键删除一条记录 -->
 	<delete id="delete" >
 		DELETE FROM student_exam_result WHERE id_ = #{id} 
 	</delete>