zouxuan 5 年之前
父節點
當前提交
fe781c9c48
共有 43 個文件被更改,包括 2145 次插入172 次删除
  1. 0 5
      edu-auth/edu-auth-server/pom.xml
  2. 2 2
      edu-auth/edu-auth-server/src/main/resources/application.yml
  3. 5 1
      edu-im/edu-im-server/pom.xml
  4. 13 31
      edu-im/edu-im-server/src/main/java/com/keao/edu/im/controller/RoomController.java
  5. 10 0
      edu-im/edu-im-server/src/main/java/com/keao/edu/im/dao/StudentAttendanceDao.java
  6. 11 0
      edu-im/edu-im-server/src/main/java/com/keao/edu/im/dao/TeacherAttendanceDao.java
  7. 0 57
      edu-im/edu-im-server/src/main/java/com/keao/edu/im/pojo/CustomMessage.java
  8. 3 4
      edu-im/edu-im-server/src/main/java/com/keao/edu/im/pojo/RoleEnum.java
  9. 2 0
      edu-im/edu-im-server/src/main/java/com/keao/edu/im/pojo/RoomMember.java
  10. 5 5
      edu-im/edu-im-server/src/main/java/com/keao/edu/im/pojo/RoomResult.java
  11. 119 0
      edu-im/edu-im-server/src/main/java/com/keao/edu/im/pojo/StudentAttendance.java
  12. 152 0
      edu-im/edu-im-server/src/main/java/com/keao/edu/im/pojo/TeacherAttendance.java
  13. 146 41
      edu-im/edu-im-server/src/main/java/com/keao/edu/im/service/Impl/RoomServiceImpl.java
  14. 15 0
      edu-im/edu-im-server/src/main/java/com/keao/edu/im/service/Impl/StudentAttendanceServiceImpl.java
  15. 17 0
      edu-im/edu-im-server/src/main/java/com/keao/edu/im/service/Impl/TeacherAttendanceServiceImpl.java
  16. 4 4
      edu-im/edu-im-server/src/main/java/com/keao/edu/im/service/RoomService.java
  17. 6 0
      edu-im/edu-im-server/src/main/java/com/keao/edu/im/service/StudentAttendanceService.java
  18. 6 0
      edu-im/edu-im-server/src/main/java/com/keao/edu/im/service/TeacherAttendanceService.java
  19. 2 2
      edu-im/edu-im-server/src/main/resources/application.yml
  20. 15 1
      edu-user/edu-user-client-api/pom.xml
  21. 16 0
      edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/client/EduUserFeignService.java
  22. 16 0
      edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/client/fallback/EduUserFeignServiceFallback.java
  23. 136 0
      edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/entity/ExamRoom.java
  24. 43 0
      edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/entity/LoginEntity.java
  25. 205 0
      edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/entity/SysMenu.java
  26. 146 0
      edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/entity/SysOauthClientDetails.java
  27. 131 0
      edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/entity/SysRole.java
  28. 51 0
      edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/entity/SysRoleDept.java
  29. 58 0
      edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/entity/SysRoleMenu.java
  30. 307 0
      edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/entity/SysUser.java
  31. 100 0
      edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/entity/SysUserLogin.java
  32. 74 0
      edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/entity/SysUserLoginLog.java
  33. 52 0
      edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/entity/SysUserRole.java
  34. 36 0
      edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/enums/SysUserType.java
  35. 42 0
      edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/enums/UserLockFlag.java
  36. 12 0
      edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/util/SecurityConstants.java
  37. 55 0
      edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/util/SecurityUtils.java
  38. 10 0
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/dao/ExamRoomDao.java
  39. 9 0
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/service/ExamRoomService.java
  40. 23 0
      edu-user/edu-user-server/src/main/java/com/keao/edu/user/service/impl/ExamRoomServiceImpl.java
  41. 2 2
      edu-user/edu-user-server/src/main/resources/application.yml
  42. 88 0
      edu-user/edu-user-server/src/main/resources/config/mybatis/ExamRoomMapper.xml
  43. 0 17
      pom.xml

+ 0 - 5
edu-auth/edu-auth-server/pom.xml

@@ -47,11 +47,6 @@
 		</dependency>
 
 		<dependency>
-			<groupId>org.springframework.cloud</groupId>
-			<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
-		</dependency>
-
-		<dependency>
 			<groupId>com.github.penggle</groupId>
 			<artifactId>kaptcha</artifactId>
 			<version>2.3.2</version>

+ 2 - 2
edu-auth/edu-auth-server/src/main/resources/application.yml

@@ -47,9 +47,9 @@ spring:
     maxOpenPreparedStatements: 20
 
   redis:
-    host: 127.0.0.1
+    host: 47.99.212.176
     port: 6379
-    password: 
+    password: dyym
     database: 1
     #连接超时时间(毫秒)
     timeout: 10000

+ 5 - 1
edu-im/edu-im-server/pom.xml

@@ -93,5 +93,9 @@
 			<groupId>org.springframework.cloud</groupId>
 			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
 		</dependency>
-	</dependencies>
+        <dependency>
+            <groupId>com.keao.edu</groupId>
+            <artifactId>edu-user-client-api</artifactId>
+        </dependency>
+    </dependencies>
 </project>

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

@@ -1,36 +1,18 @@
 package com.keao.edu.im.controller;
 
-import java.util.List;
-
-import lombok.extern.slf4j.Slf4j;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.RequestBody;
-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 com.alibaba.fastjson.JSONObject;
 import com.keao.edu.auth.api.client.SysUserFeignService;
 import com.keao.edu.im.common.ApiException;
 import com.keao.edu.im.common.BaseResponse;
 import com.keao.edu.im.common.ErrorEnum;
-import com.keao.edu.im.pojo.ChannelStateNotify;
-import com.keao.edu.im.pojo.DeviceTypeEnum;
-import com.keao.edu.im.pojo.PlayMidiMessageData;
-import com.keao.edu.im.pojo.ReqChangeRole;
-import com.keao.edu.im.pojo.ReqChangeUserRoleData;
-import com.keao.edu.im.pojo.ReqDeviceControlData;
-import com.keao.edu.im.pojo.ReqDisplayData;
-import com.keao.edu.im.pojo.ReqMemberOnlineStatus;
-import com.keao.edu.im.pojo.ReqSpeechData;
-import com.keao.edu.im.pojo.ReqUpgradeRoleData;
-import com.keao.edu.im.pojo.ReqUserData;
-import com.keao.edu.im.pojo.ReqWhiteboardData;
-import com.keao.edu.im.pojo.RoomResult;
+import com.keao.edu.im.pojo.*;
 import com.keao.edu.im.service.MessageService;
 import com.keao.edu.im.service.RoomService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
 
 /**
  * Created by weiqinxiao on 2019/2/25.
@@ -49,7 +31,7 @@ public class RoomController{
     @RequestMapping(value = "/join", method = RequestMethod.POST)
     public Object joinRoom(@RequestBody ReqUserData data)
             throws ApiException, Exception {
-        RoomResult roomResult = roomService.joinRoom(data.getUserName(), data.getRoomId(), data.isAudience(), data.isDisableCamera(),data.isMusicMode());
+        RoomResult roomResult = roomService.joinRoom(data.getRoomId(), data.isAudience(), data.isDisableCamera(),data.isMusicMode());
         return new BaseResponse<>(roomResult);
     }
 
@@ -66,11 +48,11 @@ public class RoomController{
         return new BaseResponse<>(result);
     }
 
-    @RequestMapping(value = "/sendImPlayMidiMessage", method = RequestMethod.POST)
+    /*@RequestMapping(value = "/sendImPlayMidiMessage", method = RequestMethod.POST)
     public Object sendImPlayMidiMessage(@RequestBody PlayMidiMessageData playMidiMessageData) throws Exception {
         roomService.sendImPlayMidiMessage(playMidiMessageData);
         return new BaseResponse<>();
-    }
+    }*/
 
     @RequestMapping(value = "/statusSync")
     public Object statusSync(@RequestBody String body) throws Exception {
@@ -107,7 +89,7 @@ public class RoomController{
     }
 
     //only teacher
-    @RequestMapping(value = "/display", method = RequestMethod.POST)
+    /*@RequestMapping(value = "/display", method = RequestMethod.POST)
     public Object display(@RequestBody ReqDisplayData data)
             throws ApiException, Exception {
         boolean result = roomService.display(data.getRoomId(), data.getType(), data.getUri());
@@ -134,7 +116,7 @@ public class RoomController{
             throws ApiException, Exception {
         List<RoomResult.WhiteboardResult> whiteboards = roomService.getWhiteboard(roomId);
         return new BaseResponse<>(whiteboards);
-    }
+    }*/
 
     @RequestMapping(value = "/device/approve", method = RequestMethod.POST)
     public Object approveControlDevice(@RequestBody ReqDeviceControlData data)
@@ -205,12 +187,12 @@ public class RoomController{
         return new BaseResponse<>(whiteboards);
     }
 
-    @RequestMapping(value = "/speech/apply", method = RequestMethod.POST)
+    /*@RequestMapping(value = "/speech/apply", method = RequestMethod.POST)
     public Object apply(@RequestBody ReqSpeechData data)
             throws ApiException, Exception {
         Boolean result = roomService.applySpeech(data.getRoomId());
         return new BaseResponse<>(result);
-    }
+    }*/
 
     @RequestMapping(value = "/speech/approve", method = RequestMethod.POST)
     public Object approval(@RequestBody ReqSpeechData data)

+ 10 - 0
edu-im/edu-im-server/src/main/java/com/keao/edu/im/dao/StudentAttendanceDao.java

@@ -0,0 +1,10 @@
+package com.keao.edu.im.dao;
+
+import com.keao.edu.im.pojo.StudentAttendance;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface StudentAttendanceDao extends JpaRepository<StudentAttendance, Long> {
+
+}

+ 11 - 0
edu-im/edu-im-server/src/main/java/com/keao/edu/im/dao/TeacherAttendanceDao.java

@@ -0,0 +1,11 @@
+package com.keao.edu.im.dao;
+
+
+import com.keao.edu.im.pojo.TeacherAttendance;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface TeacherAttendanceDao extends JpaRepository<TeacherAttendance, Long> {
+
+}

+ 0 - 57
edu-im/edu-im-server/src/main/java/com/keao/edu/im/pojo/CustomMessage.java

@@ -1,57 +0,0 @@
-package com.keao.edu.im.pojo;
-
-import io.rong.messages.BaseMessage;
-import org.apache.commons.lang3.StringUtils;
-
-public class CustomMessage extends BaseMessage {
-    private Boolean enable;
-    private int customType;
-    private int rate;
-    private String userId;
-
-    public Boolean getEnable() {
-        return enable;
-    }
-
-    public void setEnable(Boolean enable) {
-        this.enable = enable;
-    }
-
-    public int getCustomType() {
-        return customType;
-    }
-
-    public void setCustomType(int customType) {
-        this.customType = customType;
-    }
-
-    public int getRate() {
-        return rate;
-    }
-
-    public void setRate(int rate) {
-        this.rate = rate;
-    }
-
-    public String getUserId() {
-        return userId;
-    }
-
-    public void setUserId(String userId) {
-        this.userId = userId;
-    }
-
-    @Override
-    public String getType() {
-        return "DY:PlayMidiMessage";
-    }
-
-    @Override
-    public String toString() {
-        return "{\"enable\":" + enable +
-                ", \"customType\":" + customType +
-                ", \"rate\":" + rate +
-                ", \"userId\":" + (StringUtils.isEmpty(userId)?"\"\"":"\"" + userId + "\"") +
-                '}';
-    }
-}

+ 3 - 4
edu-im/edu-im-server/src/main/java/com/keao/edu/im/pojo/RoleEnum.java

@@ -10,10 +10,9 @@ import lombok.Setter;
  * Created by weiqinxiao on 2019/2/28.
  */
 public enum RoleEnum {
-    RoleAssistant("RoleAssistant", 1),
-    RoleTeacher("RoleTeacher", 2),
-    RoleStudent("RoleStudent", 3),
-    RoleAudience("RoleAudience", 4);
+    MainTeacher("MainTeacher", 1),
+    AssistantTeacher("AssistantTeacher", 2),
+    Student("Student", 3);
 
     private @Getter
     @Setter(AccessLevel.PRIVATE) String msg;

+ 2 - 0
edu-im/edu-im-server/src/main/java/com/keao/edu/im/pojo/RoomMember.java

@@ -18,12 +18,14 @@ public class RoomMember {
 
     private @Getter @Setter String uid;
     private @Getter @Setter String rid;
+    private @Getter @Setter String headUrl;
     private @Getter @Setter int role;
     private @Getter @Setter Date joinDt;
     private @Getter @Setter String name;
     private @Getter @Setter boolean camera = true;
     private @Getter @Setter boolean musicMode = true;
     private @Getter @Setter boolean mic = true;
+    private @Getter @Setter boolean hand = false;
 
     public RoomMember() {
     }

+ 5 - 5
edu-im/edu-im-server/src/main/java/com/keao/edu/im/pojo/RoomResult.java

@@ -1,6 +1,5 @@
 package com.keao.edu.im.pojo;
 
-import com.alibaba.fastjson.JSONObject;
 import lombok.Data;
 import lombok.Getter;
 import lombok.Setter;
@@ -8,7 +7,6 @@ import lombok.Setter;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
-import java.util.Map;
 
 /**
  * Created by weiqinxiao on 2019/2/28.
@@ -28,11 +26,12 @@ public class RoomResult {
     public static class MemberResult {
         String userId;
         String userName;
+        String headUrl;
         int role;
         Date joinTime;
         boolean camera;
         boolean microphone;
-        CustomMessage playMidiJson;
+        boolean handUp;
     }
 
     @Data
@@ -42,7 +41,7 @@ public class RoomResult {
         int curPg;
     }
 
-    public void setMembers(List<RoomMember> roomMemberList, Map<Integer,String> midiMap) {
+    public void setMembers(List<RoomMember> roomMemberList) {
         for (RoomMember member : roomMemberList) {
             MemberResult result = new MemberResult();
             result.setUserId(member.getUid());
@@ -51,7 +50,8 @@ public class RoomResult {
             result.setMicrophone(member.isMic());
             result.setCamera(member.isCamera());
             result.setUserName(member.getName());
-            result.setPlayMidiJson(JSONObject.parseObject(midiMap.get(Integer.parseInt(member.getUid())),CustomMessage.class));
+            result.setHandUp(member.isHand());
+            result.setHeadUrl(member.getHeadUrl());
             members.add(result);
         }
     }

+ 119 - 0
edu-im/edu-im-server/src/main/java/com/keao/edu/im/pojo/StudentAttendance.java

@@ -0,0 +1,119 @@
+package com.keao.edu.im.pojo;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+import javax.persistence.*;
+
+/**
+ * 对应数据库表(student_attendance):
+ */
+@Entity
+@Table(name = "student_attendance")
+public class StudentAttendance {
+
+	@Id
+	@GeneratedValue(strategy = GenerationType.IDENTITY)
+	private Long id;
+	
+	/** 课程计划 */
+	private Long examRoomId;
+	
+	/**  */
+	private Integer userId;
+	
+	/** 签到状态(0正常1异常) */
+	private String signInStatus;
+	
+	/** 签退状态(0正常1异常) */
+	private String signOutStatus;
+	
+	/**  */
+	private java.util.Date createTime;
+	
+	/** 备注 */
+	private String remark;
+	
+	/**  */
+	private java.util.Date signInTime;
+	
+	/**  */
+	private java.util.Date signOutTime;
+	
+	public void setId(Long id){
+		this.id = id;
+	}
+	
+	public Long getId(){
+		return this.id;
+	}
+			
+	public void setExamRoomId(Long examRoomId){
+		this.examRoomId = examRoomId;
+	}
+	
+	public Long getExamRoomId(){
+		return this.examRoomId;
+	}
+			
+	public void setUserId(Integer userId){
+		this.userId = userId;
+	}
+	
+	public Integer getUserId(){
+		return this.userId;
+	}
+			
+	public void setSignInStatus(String signInStatus){
+		this.signInStatus = signInStatus;
+	}
+	
+	public String getSignInStatus(){
+		return this.signInStatus;
+	}
+			
+	public void setSignOutStatus(String signOutStatus){
+		this.signOutStatus = signOutStatus;
+	}
+	
+	public String getSignOutStatus(){
+		return this.signOutStatus;
+	}
+			
+	public void setCreateTime(java.util.Date createTime){
+		this.createTime = createTime;
+	}
+	
+	public java.util.Date getCreateTime(){
+		return this.createTime;
+	}
+			
+	public void setRemark(String remark){
+		this.remark = remark;
+	}
+	
+	public String getRemark(){
+		return this.remark;
+	}
+			
+	public void setSignInTime(java.util.Date signInTime){
+		this.signInTime = signInTime;
+	}
+	
+	public java.util.Date getSignInTime(){
+		return this.signInTime;
+	}
+			
+	public void setSignOutTime(java.util.Date signOutTime){
+		this.signOutTime = signOutTime;
+	}
+	
+	public java.util.Date getSignOutTime(){
+		return this.signOutTime;
+	}
+			
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 152 - 0
edu-im/edu-im-server/src/main/java/com/keao/edu/im/pojo/TeacherAttendance.java

@@ -0,0 +1,152 @@
+package com.keao.edu.im.pojo;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+import javax.persistence.*;
+
+/**
+ * 对应数据库表(teacher_attendance):
+ */
+@Entity
+@Table(name = "teacher_attendance")
+public class TeacherAttendance {
+
+	@Id
+	@GeneratedValue(strategy = GenerationType.IDENTITY)
+	private Long id;
+	
+	/**  */
+	private Integer teacherId;
+	
+	/** 考场 */
+	private Long examRoomId;
+	
+	/** 签到时间 */
+	private java.util.Date signInTime;
+	
+	/** 签到状态(0正常1异常) */
+	private String signInStatus;
+	
+	/** 备注 */
+	private String remark;
+	
+	/**  */
+	private java.util.Date createTime;
+	
+	/** 签退时间 */
+	private java.util.Date signOutTime;
+	
+	/** 签退状态(0正常1异常) */
+	private String signOutStatus;
+	
+	/** 经度 */
+	private String signInLongitudeLatitude;
+	
+	/** 纬度 */
+	private String signOutLongitudeLatitude;
+	
+	/** 机构编号 */
+	private String tenantId;
+	
+	public void setId(Long id){
+		this.id = id;
+	}
+	
+	public Long getId(){
+		return this.id;
+	}
+			
+	public void setTeacherId(Integer teacherId){
+		this.teacherId = teacherId;
+	}
+	
+	public Integer getTeacherId(){
+		return this.teacherId;
+	}
+			
+	public void setExamRoomId(Long examRoomId){
+		this.examRoomId = examRoomId;
+	}
+	
+	public Long getExamRoomId(){
+		return this.examRoomId;
+	}
+			
+	public void setSignInTime(java.util.Date signInTime){
+		this.signInTime = signInTime;
+	}
+	
+	public java.util.Date getSignInTime(){
+		return this.signInTime;
+	}
+			
+	public void setSignInStatus(String signInStatus){
+		this.signInStatus = signInStatus;
+	}
+	
+	public String getSignInStatus(){
+		return this.signInStatus;
+	}
+			
+	public void setRemark(String remark){
+		this.remark = remark;
+	}
+	
+	public String getRemark(){
+		return this.remark;
+	}
+			
+	public void setCreateTime(java.util.Date createTime){
+		this.createTime = createTime;
+	}
+	
+	public java.util.Date getCreateTime(){
+		return this.createTime;
+	}
+			
+	public void setSignOutTime(java.util.Date signOutTime){
+		this.signOutTime = signOutTime;
+	}
+	
+	public java.util.Date getSignOutTime(){
+		return this.signOutTime;
+	}
+			
+	public void setSignOutStatus(String signOutStatus){
+		this.signOutStatus = signOutStatus;
+	}
+	
+	public String getSignOutStatus(){
+		return this.signOutStatus;
+	}
+			
+	public void setSignInLongitudeLatitude(String signInLongitudeLatitude){
+		this.signInLongitudeLatitude = signInLongitudeLatitude;
+	}
+	
+	public String getSignInLongitudeLatitude(){
+		return this.signInLongitudeLatitude;
+	}
+			
+	public void setSignOutLongitudeLatitude(String signOutLongitudeLatitude){
+		this.signOutLongitudeLatitude = signOutLongitudeLatitude;
+	}
+	
+	public String getSignOutLongitudeLatitude(){
+		return this.signOutLongitudeLatitude;
+	}
+			
+	public void setTenantId(String tenantId){
+		this.tenantId = tenantId;
+	}
+	
+	public String getTenantId(){
+		return this.tenantId;
+	}
+			
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

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

@@ -1,7 +1,9 @@
 package com.keao.edu.im.service.Impl;
 
 import com.alibaba.fastjson.JSONObject;
+import com.keao.edu.auth.api.client.EduUserFeignService;
 import com.keao.edu.auth.api.client.SysUserFeignService;
+import com.keao.edu.auth.api.entity.ExamRoom;
 import com.keao.edu.auth.api.entity.SysUser;
 import com.keao.edu.common.exception.BizException;
 import com.keao.edu.im.common.ApiException;
@@ -32,10 +34,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Isolation;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -77,11 +76,116 @@ public class RoomServiceImpl implements RoomService {
     @Autowired
     private SysUserFeignService sysUserFeignService;
 
+    @Autowired
+    private EduUserFeignService eduUserFeignService;
+
     @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
     @Override
-    public RoomResult joinRoom(String userName, String roomId, boolean isAudience, boolean isDisableCamera,boolean isMusicMode) throws ApiException, Exception {
-    
-    	return null;
+    public RoomResult joinRoom(String roomId, boolean isAudience, boolean isDisableCamera,boolean isMusicMode) throws ApiException, Exception {
+        CheckUtils.checkArgument(roomId != null, "roomId must't be null");
+
+        log.info("joinRoom: roomId={}, isAudience={}, isDisableCamera={},isMusicMode={}", roomId, isAudience, isDisableCamera,isMusicMode);
+
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        String userId = sysUser.getId().toString();
+        String realName = sysUser.getRealName();
+        ExamRoom examRoom = eduUserFeignService.getExamRoom(Integer.parseInt(roomId));
+        boolean isAssistant = false;
+        if (StringUtils.isNotEmpty(examRoom.getAssistantTeacherUserIdList())){
+            List<String> list = Arrays.asList(examRoom.getAssistantTeacherUserIdList().split(","));
+            if(list.contains(userId)){
+                isAssistant = true;
+            }
+        }
+        String display = "";
+        Date curTime = DateTimeUtils.currentUTC();
+        List<Room> roomList = roomDao.findByRid(roomId);
+        if (roomList.isEmpty()) {
+            saveRoom(roomId, roomId, curTime, display);
+            IMApiResultInfo resultInfo = imHelper.createGroup(new String[]{userId}, roomId, roomId);
+            if (!resultInfo.isSuccess()) {
+                log.error("joinRoom IM error: roomId={}, {}", roomId, resultInfo.getErrorMessage());
+                throw new ApiException(ErrorEnum.ERR_CREATE_ROOM_ERROR, resultInfo.getErrorMessage());
+            }
+//            else {
+//                scheduleManager.addExpiredTask(this, roomId);
+//            }
+        } else {
+            display = roomList.get(0).getDisplay();
+        }
+        RoleEnum roleEnum;
+        RoomResult roomResult = new RoomResult();
+        RoomResult.MemberResult userResult = new RoomResult.MemberResult();
+        List<RoomMember> memberList = roomMemberDao.findByRidAndUid(roomId, userId);
+        if (memberList.isEmpty()) {
+            if(userId.equals(examRoom.getMainTeacherUserId())){
+                roleEnum = RoleEnum.MainTeacher;
+            }else if(isAssistant){
+                roleEnum = RoleEnum.AssistantTeacher;
+            }else {
+                roleEnum = RoleEnum.Student;
+            }
+            saveRoomMember(userId,sysUser.getAvatar(), realName, roomId, roleEnum.getValue(), !isDisableCamera,!isMusicMode, curTime);
+            IMApiResultInfo resultInfo = imHelper.joinGroup(new String[]{userId}, roomId, roomId);
+            if (!resultInfo.isSuccess()) {
+                throw new ApiException(ErrorEnum.ERR_CREATE_ROOM_ERROR, resultInfo.getErrorMessage());
+            }
+            userResult.setMicrophone(true);
+            userResult.setCamera(!isDisableCamera);
+            userResult.setHandUp(false);
+            userResult.setJoinTime(curTime);
+            log.info("user join the room: roomId={} , userId={}, roleEnum={}", roomId, userId, roleEnum);
+        } else {
+            RoomMember roomMember = memberList.get(0);
+            roleEnum = RoleEnum.getEnumByValue(roomMember.getRole());
+//            roomMemberDao.updateCameraByRidAndUid(roomId, userId, !isDisableCamera);
+            userResult.setCamera(roomMember.isCamera());
+            userResult.setHandUp(roomMember.isHand());
+            userResult.setJoinTime(roomMember.getJoinDt());
+            log.info("user exist in the room: roomId={} , userId={}, use the last role={}", roomId, userId, roleEnum);
+        }
+
+        MemberChangedMessage msg = new MemberChangedMessage(MemberChangedMessage.Action_Join, userId, roleEnum.getValue());
+        msg.setTimestamp(curTime);
+        msg.setUserName(realName);
+        msg.setCamera(!isDisableCamera);
+        imHelper.publishMessage(userId, roomId, msg);
+        if (roleEnum == RoleEnum.MainTeacher) {
+            display = "display://type=0?userId=" + userId + "?uri=";
+            updateDisplay(roomId, userId, display, 0);
+            log.info("joinRoom, display changed: roomId={}, {}, userId={}", roomId, display, userId);
+        } else if (roleEnum == RoleEnum.AssistantTeacher && display.isEmpty()) {
+            display = "display://type=1?userId=" + userId + "?uri=";
+            updateDisplay(roomId, userId, display, 0);
+            log.info("joinRoom, display changed: roomId={}, {}, userId={}", roomId, display, userId);
+        }
+
+        List<UserInfo> userInfoList = userDao.findByUid(userId);
+        if (userInfoList.isEmpty()) {
+            UserInfo userInfo = new UserInfo();
+            userInfo.setUid(userId);
+            userInfo.setName(realName);
+            userInfo.setCreateDt(curTime);
+            userInfo.setUpdateDt(curTime);
+            userDao.save(userInfo);
+        } else {
+            UserInfo user = userInfoList.get(0);
+            user.setUpdateDt(curTime);
+            userDao.save(user);
+        }
+
+        userResult.setUserName(realName);
+        userResult.setUserId(userId);
+        userResult.setRole(roleEnum.getValue());
+        roomResult.setUserInfo(userResult);
+        roomResult.setDisplay(display);
+        roomResult.setRoomId(roomId);
+
+        roomResult.setMembers(roomMemberDao.findByRid(roomId));
+        List<Whiteboard> whiteboardList = whiteboardDao.findByRid(roomId);
+        roomResult.setWhiteboards(whiteboardList);
+        log.info("join success: roomId = {}, userId = {}, userName={}, role = {}", roomId, userId, roleEnum);
+        return roomResult;
     }
 
     @Override
@@ -104,7 +208,7 @@ public class RoomServiceImpl implements RoomService {
         }
     }
 
-    private void saveRoomMember(String userId, String userName, String roomId, int role, boolean cameraOn,boolean musicModeOn, Date joinTime) {
+    private void saveRoomMember(String userId, String headUrl, String userName, String roomId, int role, boolean cameraOn,boolean musicModeOn, Date joinTime) {
         RoomMember roomMember = new RoomMember();
         roomMember.setUid(userId);
         roomMember.setName(userName);
@@ -113,6 +217,7 @@ public class RoomServiceImpl implements RoomService {
         roomMember.setCamera(cameraOn);
         roomMember.setJoinDt(joinTime);
         roomMember.setMusicMode(musicModeOn);
+        roomMember.setHeadUrl(headUrl);
         roomMemberDao.save(roomMember);
     }
 
@@ -143,7 +248,7 @@ public class RoomServiceImpl implements RoomService {
         int userRole = roomMemberList.get(0).getRole();
         log.info("leaveRoom: roomId={}, role={}", roomId, RoleEnum.getEnumByValue(userRole));
 
-        if (userRole == RoleEnum.RoleTeacher.getValue() || userRole == RoleEnum.RoleAssistant.getValue()) {
+        if (userRole == RoleEnum.MainTeacher.getValue() || userRole == RoleEnum.AssistantTeacher.getValue()) {
             if (isUserDisplay(roomList.get(0), userId)) {
                 updateDisplay(roomId, userId, "", 0);
                 log.info("clear display cause speaker leave: roomId={}", roomId);
@@ -249,7 +354,7 @@ public class RoomServiceImpl implements RoomService {
             } else {
                 List<RoomMember> oldUsers = roomMemberDao.findByRidAndUid(roomId, changedUserId);
                 if (oldUsers.size() > 0) {
-                    if (changedRole.equals(RoleEnum.RoleAudience)) {
+                    /*if (changedRole.equals(RoleEnum.RoleAudience)) {
                         int r = roomMemberDao.updateRoleByRidAndUid(roomId, changedUserId, changedRole.getValue());
                         RoleChangedMessage.ChangedUser u = new RoleChangedMessage.ChangedUser(changedUserId, changedRole.getValue());
                         List<UserInfo> userInfoList = userDao.findByUid(changedUserId);
@@ -259,8 +364,8 @@ public class RoomServiceImpl implements RoomService {
                         changedUsers.add(u);
                         log.info("change the role: {}, {}, {}, result: {}", roomId, userId, changedRole, r);
                         result = true;
-                    }
-                    if (oldUsers.get(0).getRole() == RoleEnum.RoleTeacher.getValue() && isUserDisplay(roomList.get(0), oldUsers.get(0).getUid())) {
+                    }*/
+                    if (oldUsers.get(0).getRole() != RoleEnum.Student.getValue() && isUserDisplay(roomList.get(0), oldUsers.get(0).getUid())) {
                         updateDisplay(roomId, userId, "", 1);
                     } else {
                         log.info("don't update display: room={}, userRole={}", roomList.get(0), RoleEnum.getEnumByValue(oldUsers.get(0).getRole()));
@@ -303,7 +408,7 @@ public class RoomServiceImpl implements RoomService {
             Thread.sleep(50);
             log.info("published msg: msg={}", msg);
             List<Room> roomList = roomDao.findByRid(roomId);
-            if (kickedUsers.get(0).getRole() == RoleEnum.RoleTeacher.getValue() && isUserDisplay(roomList.get(0), userId)) {
+            if (kickedUsers.get(0).getRole() != RoleEnum.Student.getValue() && isUserDisplay(roomList.get(0), userId)) {
                 updateDisplay(roomId, userId, "", 1);
             } else {
                 log.info("don't update display: room={}, userRole={}", roomId, RoleEnum.getEnumByValue(kickedUsers.get(0).getRole()));
@@ -317,7 +422,7 @@ public class RoomServiceImpl implements RoomService {
         return true;
     }
 
-    @Override
+    /*@Override
     public Boolean display(String roomId, int type, String uri) throws ApiException, Exception {
         SysUser authUser = sysUserFeignService.queryUserInfo();
         String userId = authUser.getId().toString();
@@ -377,7 +482,7 @@ public class RoomServiceImpl implements RoomService {
         }
         log.info("result display in room: {}, type = {}, uri = {}", roomId, type, uri);
         return true;
-    }
+    }*/
 
     @Override
     public String createWhiteBoard(String roomId) throws ApiException, Exception {
@@ -550,7 +655,7 @@ public class RoomServiceImpl implements RoomService {
                 roomMembers.add(new RoomMember(split[i]));
             }
         }else {
-            roomMembers = roomMemberDao.findByRidAndRole(data.getRoomId(),RoleEnum.RoleStudent.getValue());
+            roomMembers = roomMemberDao.findByRidAndRole(data.getRoomId(),RoleEnum.Student.getValue());
         }
         if(roomMembers.size() == 0){
             return false;
@@ -653,7 +758,7 @@ public class RoomServiceImpl implements RoomService {
         return null;
     }
 
-    @Override
+    /*@Override
     public Boolean applySpeech(String roomId) throws ApiException, Exception {
         CheckUtils.checkArgument(roomId != null, "roomId must't be null");
         CheckUtils.checkArgument(roomDao.existsByRid(roomId), "room not exist");
@@ -685,7 +790,7 @@ public class RoomServiceImpl implements RoomService {
         } else {
             throw new ApiException(ErrorEnum.ERR_MESSAGE_ERROR, resultInfo.getErrorMessage());
         }
-    }
+    }*/
 
     @Override
     public Boolean approveSpeech(String roomId, String ticket) throws ApiException, Exception {
@@ -694,15 +799,15 @@ public class RoomServiceImpl implements RoomService {
         SysUser authUser = sysUserFeignService.queryUserInfo();
         String userId = authUser.getId().toString();
 
-        int count = roomMemberDao.countByRidAndExcludeRole(roomId, RoleEnum.RoleAudience.getValue());
+        /*int count = roomMemberDao.countByRidAndExcludeRole(roomId, RoleEnum.RoleAudience.getValue());
         if (count == roomProperties.getMaxCount()) {
             log.error("approveSpeech error: roomId = {}, ticket={}", roomId, ticket);
             throw new ApiException(ErrorEnum.ERR_OVER_MAX_COUNT);
-        }
+        }*/
 
         ScheduledTaskInfo taskInfo = scheduleManager.executeTask(ticket);
         log.info("approveSpeech: task = {}", taskInfo);
-        roomMemberDao.updateRoleByRidAndUid(roomId, taskInfo.getApplyUserId(), RoleEnum.RoleStudent.getValue());
+        roomMemberDao.updateRoleByRidAndUid(roomId, taskInfo.getApplyUserId(), RoleEnum.Student.getValue());
 
         SpeechResultMessage msg = new SpeechResultMessage(SpeechResultMessage.Action_Approve);
         List<UserInfo> userInfoList = userDao.findByUid(taskInfo.getApplyUserId());
@@ -712,7 +817,7 @@ public class RoomServiceImpl implements RoomService {
         if (!userInfoList.isEmpty()) {
             msg.setReqUserName(userInfoList.get(0).getName());
         }
-        msg.setRole(RoleEnum.RoleStudent.getValue());
+        msg.setRole(RoleEnum.Student.getValue());
         IMApiResultInfo resultInfo = imHelper.publishMessage(userId, taskInfo.getApplyUserId(), roomId, msg);
         if (!resultInfo.isSuccess()) {
             throw new ApiException(ErrorEnum.ERR_MESSAGE_ERROR, resultInfo.getErrorMessage());
@@ -720,7 +825,7 @@ public class RoomServiceImpl implements RoomService {
 
         RoleChangedMessage rcMsg = new RoleChangedMessage(userId);
         List<RoleChangedMessage.ChangedUser> changedUserList = new ArrayList<>();
-        RoleChangedMessage.ChangedUser user = new RoleChangedMessage.ChangedUser(taskInfo.getApplyUserId(), RoleEnum.RoleStudent.getValue());
+        RoleChangedMessage.ChangedUser user = new RoleChangedMessage.ChangedUser(taskInfo.getApplyUserId(), RoleEnum.Student.getValue());
         if (!userInfoList.isEmpty()) {
             user.setUserName(userInfoList.get(0).getName());
         }
@@ -743,7 +848,7 @@ public class RoomServiceImpl implements RoomService {
         SpeechResultMessage msg = new SpeechResultMessage(SpeechResultMessage.Action_Reject);
         msg.setOpUserId(userId);
         msg.setOpUserName(authUser.getUsername());
-        msg.setRole(RoleEnum.RoleStudent.getValue());
+        msg.setRole(RoleEnum.Student.getValue());
         IMApiResultInfo resultInfo = imHelper.publishMessage(userId, taskInfo.getApplyUserId(), roomId, msg);
         if (resultInfo.isSuccess()) {
             return true;
@@ -752,7 +857,7 @@ public class RoomServiceImpl implements RoomService {
         }
     }
 
-    private void checkOverMax(String roomId, RoomMember targetUser, int targetRole) {
+    /*private void checkOverMax(String roomId, RoomMember targetUser, int targetRole) {
         if (RoleEnum.getEnumByValue(targetUser.getRole()).equals(RoleEnum.RoleAudience)) {
             int count = roomMemberDao.countByRidAndExcludeRole(roomId, RoleEnum.RoleAudience.getValue());
             if (count == roomProperties.getMaxCount()) {
@@ -762,7 +867,7 @@ public class RoomServiceImpl implements RoomService {
         } else if (targetRole > targetUser.getRole()) {
             throw new ApiException(ErrorEnum.ERR_DOWNGRADE_ROLE);
         }
-    }
+    }*/
 
     @Override
     public Boolean transfer(String roomId, String userId) throws ApiException, Exception {
@@ -789,8 +894,8 @@ public class RoomServiceImpl implements RoomService {
             log.info("don't update display: room={}", roomList.get(0));
         }
 
-        roomMemberDao.updateRoleByRidAndUid(roomId, userId, RoleEnum.RoleStudent.getValue());
-        roomMemberDao.updateRoleByRidAndUid(roomId, userId, RoleEnum.RoleAssistant.getValue());
+        roomMemberDao.updateRoleByRidAndUid(roomId, userId, RoleEnum.Student.getValue());
+//        roomMemberDao.updateRoleByRidAndUid(roomId, userId, RoleEnum.RoleAssistant.getValue());
 
         AssistantTransferMessage msg = new AssistantTransferMessage();
         msg.setOpUserId(userId);
@@ -817,7 +922,7 @@ public class RoomServiceImpl implements RoomService {
             throw new ApiException(ErrorEnum.ERR_USER_NOT_EXIST_IN_ROOM);
         }
 
-        checkOverMax(roomId, targetUser.get(0), targetRole);
+//        checkOverMax(roomId, targetUser.get(0), targetRole);
 
         String ticket = IdentifierUtils.uuid();
 
@@ -860,7 +965,7 @@ public class RoomServiceImpl implements RoomService {
             throw new ApiException(ErrorEnum.ERR_APPLY_TICKET_INVALID);
         }
 
-        checkOverMax(roomId, targetUser.get(0), taskInfo.getRole().getValue());
+//        checkOverMax(roomId, targetUser.get(0), taskInfo.getRole().getValue());
         roomMemberDao.updateRoleByRidAndUid(roomId, userId, taskInfo.getRole().getValue());
 
         UpgradeRoleMessage msg = new UpgradeRoleMessage(ActionEnum.Approve.ordinal());
@@ -910,7 +1015,7 @@ public class RoomServiceImpl implements RoomService {
         CheckUtils.checkArgument(roomId != null, "roomId must't be null");
         CheckUtils.checkArgument(targetUserId != null, "userId must't be null");
         CheckUtils.checkArgument(roomDao.existsByRid(roomId), "room not exist");
-        CheckUtils.checkArgument(RoleEnum.getEnumByValue(targetRole).equals(RoleEnum.RoleTeacher), "only set to teacher");
+//        CheckUtils.checkArgument(RoleEnum.getEnumByValue(targetRole).equals(RoleEnum.RoleTeacher), "only set to teacher");
         CheckUtils.checkArgument(roomMemberDao.existsByRidAndUid(roomId, targetUserId), "room member not exist");
         SysUser authUser = sysUserFeignService.queryUserInfo();
         String userId = authUser.getId().toString();
@@ -919,7 +1024,7 @@ public class RoomServiceImpl implements RoomService {
         if (targetUser.isEmpty()) {
             throw new ApiException(ErrorEnum.ERR_USER_NOT_EXIST_IN_ROOM);
         } else {
-            if (!RoleEnum.getEnumByValue(targetUser.get(0).getRole()).equals(RoleEnum.RoleStudent)) {
+            if (!RoleEnum.getEnumByValue(targetUser.get(0).getRole()).equals(RoleEnum.Student)) {
                 log.error("change role error: targetUserId={}, targetRole = {}", targetUser, RoleEnum.getEnumByValue(targetRole));
                 throw new ApiException(ErrorEnum.ERR_CHANGE_ROLE);
             }
@@ -929,10 +1034,10 @@ public class RoomServiceImpl implements RoomService {
         List<RoleChangedMessage.ChangedUser> changedUserList = new ArrayList<>();
         RoleChangedMessage msg = new RoleChangedMessage(userId);
 
-        List<RoomMember> teachers = roomMemberDao.findByRidAndRole(roomId, RoleEnum.RoleTeacher.getValue());
+        List<RoomMember> teachers = roomMemberDao.findByRidAndRole(roomId, RoleEnum.MainTeacher.getValue());
         if (!teachers.isEmpty()) {
-            roomMemberDao.updateRoleByRidAndUid(roomId, teachers.get(0).getUid(), RoleEnum.RoleStudent.getValue());
-            RoleChangedMessage.ChangedUser user = new RoleChangedMessage.ChangedUser(teachers.get(0).getUid(), RoleEnum.RoleStudent.getValue());
+            roomMemberDao.updateRoleByRidAndUid(roomId, teachers.get(0).getUid(), RoleEnum.Student.getValue());
+            RoleChangedMessage.ChangedUser user = new RoleChangedMessage.ChangedUser(teachers.get(0).getUid(), RoleEnum.Student.getValue());
             List<UserInfo> userInfoList = userDao.findByUid(teachers.get(0).getUid());
             if (!userInfoList.isEmpty()) {
                 user.setUserName(userInfoList.get(0).getName());
@@ -996,7 +1101,7 @@ public class RoomServiceImpl implements RoomService {
             int userRole = member.getRole();
             log.info("userIMOfflineKick: roomId={}, {}, role={}", member.getRid(), userId, RoleEnum.getEnumByValue(userRole));
             try {
-                if (userRole == RoleEnum.RoleTeacher.getValue() || userRole == RoleEnum.RoleAssistant.getValue()) {
+                if (userRole == RoleEnum.MainTeacher.getValue() || userRole == RoleEnum.AssistantTeacher.getValue()) {
                     List<Room> rooms = roomDao.findByRid(member.getRid());
                     if (rooms.isEmpty()) {
                         break;
@@ -1061,7 +1166,7 @@ public class RoomServiceImpl implements RoomService {
             int userRole = roomMemberList.get(0).getRole();
             log.info("statusSync: roomId={}, role={}", roomId, RoleEnum.getEnumByValue(userRole));
 
-            if (userRole == RoleEnum.RoleTeacher.getValue() || userRole == RoleEnum.RoleAssistant.getValue()) {
+            if (userRole == RoleEnum.MainTeacher.getValue() || userRole == RoleEnum.AssistantTeacher.getValue()) {
                 if (isUserDisplay(roomList.get(0), userId)) {
                     try {
                         updateDisplay(roomId, userId, "", 0);
@@ -1117,7 +1222,7 @@ public class RoomServiceImpl implements RoomService {
         return true;
     }
 
-    @Override
+    /*@Override
     public void sendImPlayMidiMessage(PlayMidiMessageData playMidiMessageData) throws Exception {
         SysUser sysUser = sysUserFeignService.queryUserInfo();
         if(sysUser == null){
@@ -1136,7 +1241,7 @@ public class RoomServiceImpl implements RoomService {
         //记录节拍器消息
         String userId = playMidiMessageData.getUserId();
 //        long courseId = Long.parseLong(roomId.substring(1));
-        /*if(StringUtils.isEmpty(userId)){
+        *//*if(StringUtils.isEmpty(userId)){
             //批量操作节拍器状态
             courseScheduleStudentPaymentDao.openPlayMidi(courseId,userId,content);
             roomMemberDao.updatePlayMidiJsonByRidAndRole(roomId,RoleEnum.RoleStudent.getValue(), content);
@@ -1146,8 +1251,8 @@ public class RoomServiceImpl implements RoomService {
                 roomMemberDao.updatePlayMidiJsonByRidAndRole(playMidiMessageData.getRoomId(),RoleEnum.RoleTeacher.getValue(), null);
             }
             roomMemberDao.updatePlayMidiJsonByRidAndUid(playMidiMessageData.getRoomId(),userId,content);
-        }*/
-    }
+        }*//*
+    }*/
 
     /*@Override
     public void sendImPlayMidiMessage(PlayMidiMessageData playMidiMessageData) {

+ 15 - 0
edu-im/edu-im-server/src/main/java/com/keao/edu/im/service/Impl/StudentAttendanceServiceImpl.java

@@ -0,0 +1,15 @@
+package com.keao.edu.im.service.Impl;
+
+
+import com.keao.edu.im.dao.StudentAttendanceDao;
+import com.keao.edu.im.service.StudentAttendanceService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class StudentAttendanceServiceImpl implements StudentAttendanceService {
+	
+	@Autowired
+	private StudentAttendanceDao studentAttendanceDao;
+	
+}

+ 17 - 0
edu-im/edu-im-server/src/main/java/com/keao/edu/im/service/Impl/TeacherAttendanceServiceImpl.java

@@ -0,0 +1,17 @@
+package com.keao.edu.im.service.Impl;
+
+
+import com.keao.edu.im.dao.TeacherAttendanceDao;
+import com.keao.edu.im.service.TeacherAttendanceService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+public class TeacherAttendanceServiceImpl implements TeacherAttendanceService {
+	
+	@Autowired
+	private TeacherAttendanceDao teacherAttendanceDao;
+	
+}

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

@@ -15,7 +15,7 @@ import com.keao.edu.im.pojo.RoomResult;
  */
 public interface RoomService {
     //everyone
-    public RoomResult joinRoom(String userName, String roomId, boolean isAudience, boolean isDisableCamera, boolean isMusicMode) throws ApiException, Exception;
+    public RoomResult joinRoom(String roomId, boolean isAudience, boolean isDisableCamera, boolean isMusicMode) throws ApiException, Exception;
 
     void signIn(Long roomId);
 
@@ -28,7 +28,7 @@ public interface RoomService {
 
 
     //only teacher
-    public Boolean display(String roomId, int type, String uri) throws ApiException, Exception;
+//    public Boolean display(String roomId, int type, String uri) throws ApiException, Exception;
 
     public String createWhiteBoard(String roomId) throws ApiException, Exception;
 
@@ -49,7 +49,7 @@ public interface RoomService {
 
     public List<RoomResult.MemberResult> getMembers(String roomId) throws  ApiException, Exception;
 
-    public Boolean applySpeech(String roomId) throws  ApiException, Exception;
+//    public Boolean applySpeech(String roomId) throws  ApiException, Exception;
 
     public Boolean approveSpeech(String roomId, String requestId) throws  ApiException, Exception;
 
@@ -76,7 +76,7 @@ public interface RoomService {
      * 发送节拍器消息
      * @param playMidiMessageData
      */
-    void sendImPlayMidiMessage(PlayMidiMessageData playMidiMessageData) throws Exception;
+//    void sendImPlayMidiMessage(PlayMidiMessageData playMidiMessageData) throws Exception;
 
     /**
      * 发送节拍器自定义消息

+ 6 - 0
edu-im/edu-im-server/src/main/java/com/keao/edu/im/service/StudentAttendanceService.java

@@ -0,0 +1,6 @@
+package com.keao.edu.im.service;
+
+
+public interface StudentAttendanceService{
+
+}

+ 6 - 0
edu-im/edu-im-server/src/main/java/com/keao/edu/im/service/TeacherAttendanceService.java

@@ -0,0 +1,6 @@
+package com.keao.edu.im.service;
+
+
+public interface TeacherAttendanceService {
+
+}

+ 2 - 2
edu-im/edu-im-server/src/main/resources/application.yml

@@ -32,7 +32,7 @@ spring:
     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
+    password: dayaDataOnline@2019
     # 使用druid数据源
     type: com.alibaba.druid.pool.DruidDataSource
     driver-class-name: com.mysql.cj.jdbc.Driver
@@ -53,7 +53,7 @@ spring:
   redis:
     host: 47.99.212.176
     port: 6379
-    password:
+    password: dyym
     database: 1
     #连接超时时间(毫秒)
     timeout: 10000

+ 15 - 1
edu-user/edu-user-client-api/pom.xml

@@ -17,5 +17,19 @@
 	</properties>
 
 	<dependencies>
-	</dependencies>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-openfeign-core</artifactId>
+            <version>2.1.2.RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
+		<dependency>
+			<groupId>com.keao.edu</groupId>
+			<artifactId>edu-common</artifactId>
+		</dependency>
+        <dependency>
+            <groupId>com.keao.edu</groupId>
+            <artifactId>edu-auth-api</artifactId>
+        </dependency>
+    </dependencies>
 </project>

+ 16 - 0
edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/client/EduUserFeignService.java

@@ -0,0 +1,16 @@
+package com.keao.edu.auth.api.client;
+
+
+import com.keao.edu.auth.api.client.fallback.EduUserFeignServiceFallback;
+import com.keao.edu.auth.api.entity.ExamRoom;
+import com.keao.edu.common.config.FeignConfiguration;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@FeignClient(contextId = "eduUserFeignService", name = "user-server", configuration = { FeignConfiguration.class }, fallback = EduUserFeignServiceFallback.class)
+public interface EduUserFeignService {
+
+	@GetMapping(value = "examRoom/get")
+	ExamRoom getExamRoom(@RequestParam("id") Integer id);
+}

+ 16 - 0
edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/client/fallback/EduUserFeignServiceFallback.java

@@ -0,0 +1,16 @@
+package com.keao.edu.auth.api.client.fallback;
+
+import com.keao.edu.auth.api.client.EduUserFeignService;
+import com.keao.edu.auth.api.entity.ExamRoom;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@Component
+public class EduUserFeignServiceFallback implements EduUserFeignService {
+
+	@Override
+	public ExamRoom getExamRoom(@RequestParam("id") Integer id){
+		return null;
+	}
+
+}

+ 136 - 0
edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/entity/ExamRoom.java

@@ -0,0 +1,136 @@
+package com.keao.edu.auth.api.entity;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+/**
+ * 对应数据库表(exam_room):
+ */
+public class ExamRoom {
+
+	/**  */
+	private Long id;
+	
+	/** 考试模式(线上/线下) */
+	private String examMode;
+	
+	/** 考点 */
+	private Integer examLocationId;
+	
+	/** 考试专业(多选,逗号分隔) */
+	private String subjectIdList;
+	
+	/** 主考老师 */
+	private Integer mainTeacherUserId;
+	
+	/** 助考老师(多个用逗号分隔) */
+	private String assistantTeacherUserIdList;
+	
+	/** 考试时间(json格式) */
+	private String examTimeJson;
+	
+	/**  */
+	private boolean delFlag;
+	
+	/**  */
+	private java.util.Date createTime;
+	
+	/**  */
+	private java.util.Date updateTime;
+	
+	/**  */
+	private String tenantId;
+	
+	public void setId(Long id){
+		this.id = id;
+	}
+	
+	public Long getId(){
+		return this.id;
+	}
+			
+	public void setExamMode(String examMode){
+		this.examMode = examMode;
+	}
+	
+	public String getExamMode(){
+		return this.examMode;
+	}
+			
+	public void setExamLocationId(Integer examLocationId){
+		this.examLocationId = examLocationId;
+	}
+	
+	public Integer getExamLocationId(){
+		return this.examLocationId;
+	}
+			
+	public void setSubjectIdList(String subjectIdList){
+		this.subjectIdList = subjectIdList;
+	}
+	
+	public String getSubjectIdList(){
+		return this.subjectIdList;
+	}
+			
+	public void setMainTeacherUserId(Integer mainTeacherUserId){
+		this.mainTeacherUserId = mainTeacherUserId;
+	}
+	
+	public Integer getMainTeacherUserId(){
+		return this.mainTeacherUserId;
+	}
+			
+	public void setAssistantTeacherUserIdList(String assistantTeacherUserIdList){
+		this.assistantTeacherUserIdList = assistantTeacherUserIdList;
+	}
+	
+	public String getAssistantTeacherUserIdList(){
+		return this.assistantTeacherUserIdList;
+	}
+			
+	public void setExamTimeJson(String examTimeJson){
+		this.examTimeJson = examTimeJson;
+	}
+	
+	public String getExamTimeJson(){
+		return this.examTimeJson;
+	}
+			
+	public void setDelFlag(boolean delFlag){
+		this.delFlag = delFlag;
+	}
+	
+	public boolean isDelFlag(){
+		return this.delFlag;
+	}
+			
+	public void setCreateTime(java.util.Date createTime){
+		this.createTime = createTime;
+	}
+	
+	public java.util.Date getCreateTime(){
+		return this.createTime;
+	}
+			
+	public void setUpdateTime(java.util.Date updateTime){
+		this.updateTime = updateTime;
+	}
+	
+	public java.util.Date getUpdateTime(){
+		return this.updateTime;
+	}
+			
+	public void setTenantId(String tenantId){
+		this.tenantId = tenantId;
+	}
+	
+	public String getTenantId(){
+		return this.tenantId;
+	}
+			
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 43 - 0
edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/entity/LoginEntity.java

@@ -0,0 +1,43 @@
+package com.keao.edu.auth.api.entity;
+
+public class LoginEntity {
+    private String smsCode;
+
+    private String clientId;
+
+    private String clientSecret;
+
+    private String phone;
+
+    public String getSmsCode() {
+        return smsCode;
+    }
+
+    public void setSmsCode(String smsCode) {
+        this.smsCode = smsCode;
+    }
+
+    public String getClientId() {
+        return clientId;
+    }
+
+    public void setClientId(String clientId) {
+        this.clientId = clientId;
+    }
+
+    public String getClientSecret() {
+        return clientSecret;
+    }
+
+    public void setClientSecret(String clientSecret) {
+        this.clientSecret = clientSecret;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+}

+ 205 - 0
edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/entity/SysMenu.java

@@ -0,0 +1,205 @@
+package com.keao.edu.auth.api.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+import java.util.List;
+
+/**
+ * 对应数据库表(sys_menu):
+ */
+public class SysMenu {
+
+	/** 菜单ID */
+	@ApiModelProperty(value = "菜单ID",required = false)
+	private Integer id;
+
+	/** 菜单名称 */
+	@ApiModelProperty(value = "菜单名称",required = false)
+	private String name;
+
+	/** 菜单权限标识 */
+	@ApiModelProperty(value = "菜单权限标识",required = false)
+	private String permission;
+
+	/** 菜单权限标识 */
+	@ApiModelProperty(value = "顶级菜单权限标识",required = false)
+	private String parentPermission;
+
+	/** 接口路径 */
+	@ApiModelProperty(value = "接口路径",required = false)
+	private String path;
+
+	/** 父菜单ID */
+	@ApiModelProperty(value = "父菜单ID",required = false)
+	private Integer parentId;
+
+	/** 图标 */
+	@ApiModelProperty(value = "图标 */",required = false)
+	private String icon;
+
+	/** 前端页面地址 */
+	@ApiModelProperty(value = "前端页面地址",required = false)
+	private String component;
+
+	/** 排序值 */
+	@ApiModelProperty(value = "排序值",required = false)
+	private Integer sort;
+
+	/** 0-开启,1- 关闭 */
+	@ApiModelProperty(value = "0-开启,1- 关闭",required = false)
+	private String keepAlive;
+
+	/** 菜单类型 (0菜单 1按钮) */
+	@ApiModelProperty(value = "菜单类型 (0菜单 1按钮)",required = false)
+	private String type;
+
+	/** 创建时间 */
+	private java.util.Date createTime;
+
+	/** 更新时间 */
+	private java.util.Date updateTime;
+
+	/** 逻辑删除标记(0--正常 1--删除) */
+	@ApiModelProperty(value = "逻辑删除标记(0--正常 1--删除)",required = false)
+	private String delFlag;
+
+	private Integer hid;
+
+	@ApiModelProperty(value = "子节点列表",required = false)
+	private List<SysMenu> sysMenus;
+
+	public String getParentPermission() {
+		return parentPermission;
+	}
+
+	public void setParentPermission(String parentPermission) {
+		this.parentPermission = parentPermission;
+	}
+
+	public Integer getHid() {
+		return hid;
+	}
+
+	public void setHid(Integer hid) {
+		this.hid = hid;
+	}
+
+	public List<SysMenu> getSysMenus() {
+		return sysMenus;
+	}
+
+	public void setSysMenus(List<SysMenu> sysMenus) {
+		this.sysMenus = sysMenus;
+	}
+
+	public Integer getId() {
+		return id;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getName() {
+		return this.name;
+	}
+
+	public void setPermission(String permission) {
+		this.permission = permission;
+	}
+
+	public String getPermission() {
+		return this.permission;
+	}
+
+	public void setPath(String path) {
+		this.path = path;
+	}
+
+	public String getPath() {
+		return this.path;
+	}
+
+	public void setParentId(Integer parentId) {
+		this.parentId = parentId;
+	}
+
+	public Integer getParentId() {
+		return this.parentId;
+	}
+
+	public void setIcon(String icon) {
+		this.icon = icon;
+	}
+
+	public String getIcon() {
+		return this.icon;
+	}
+
+	public String getComponent() {
+		return component;
+	}
+
+	public void setComponent(String component) {
+		this.component = component;
+	}
+
+	public void setSort(Integer sort) {
+		this.sort = sort;
+	}
+
+	public Integer getSort() {
+		return this.sort;
+	}
+
+	public void setKeepAlive(String keepAlive) {
+		this.keepAlive = keepAlive;
+	}
+
+	public String getKeepAlive() {
+		return this.keepAlive;
+	}
+
+	public void setType(String type) {
+		this.type = type;
+	}
+
+	public String getType() {
+		return this.type;
+	}
+
+	public void setCreateTime(java.util.Date createTime) {
+		this.createTime = createTime;
+	}
+
+	public java.util.Date getCreateTime() {
+		return this.createTime;
+	}
+
+	public void setUpdateTime(java.util.Date updateTime) {
+		this.updateTime = updateTime;
+	}
+
+	public java.util.Date getUpdateTime() {
+		return this.updateTime;
+	}
+
+	public void setDelFlag(String delFlag) {
+		this.delFlag = delFlag;
+	}
+
+	public String getDelFlag() {
+		return this.delFlag;
+	}
+
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 146 - 0
edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/entity/SysOauthClientDetails.java

@@ -0,0 +1,146 @@
+package com.keao.edu.auth.api.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+/**
+ * 对应数据库表(sys_oauth_client_details):
+ */
+public class SysOauthClientDetails {
+
+	/** 客户端ID */
+	@ApiModelProperty(value = "客户端ID",required = false)
+	private String id;
+	
+	/** 资源ID */
+	@ApiModelProperty(value = "资源ID",required = false)
+	private String resourceIds;
+	
+	/** 客户端密钥 */
+	@ApiModelProperty(value = "客户端密钥",required = false)
+	private String clientSecret;
+	
+	/** 作用域 */
+	@ApiModelProperty(value = "作用域",required = false)
+	private String scope;
+	
+	/** 授权方式 */
+	@ApiModelProperty(value = "授权方式",required = false)
+	private String authorizedGrantTypes;
+	
+	/**  */
+	private String webServerRedirectUri;
+	
+	/**  */
+	private String authorities;
+	
+	/** 请求令牌有效时间 */
+	@ApiModelProperty(value = "请求令牌有效时间",required = false)
+	private Integer accessTokenValidity;
+	
+	/** 刷新令牌有效时间 */
+	@ApiModelProperty(value = "刷新令牌有效时间",required = false)
+	private Integer refreshTokenValidity;
+	
+	/** 扩展信息 */
+	@ApiModelProperty(value = "扩展信息",required = false)
+	private String additionalInformation;
+	
+	/** 是否自动放行 */
+	@ApiModelProperty(value = "是否自动放行",required = false)
+	private String autoapprove;
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public void setResourceIds(String resourceIds){
+		this.resourceIds = resourceIds;
+	}
+	
+	public String getResourceIds(){
+		return this.resourceIds;
+	}
+			
+	public void setClientSecret(String clientSecret){
+		this.clientSecret = clientSecret;
+	}
+	
+	public String getClientSecret(){
+		return this.clientSecret;
+	}
+			
+	public void setScope(String scope){
+		this.scope = scope;
+	}
+	
+	public String getScope(){
+		return this.scope;
+	}
+			
+	public void setAuthorizedGrantTypes(String authorizedGrantTypes){
+		this.authorizedGrantTypes = authorizedGrantTypes;
+	}
+	
+	public String getAuthorizedGrantTypes(){
+		return this.authorizedGrantTypes;
+	}
+			
+	public void setWebServerRedirectUri(String webServerRedirectUri){
+		this.webServerRedirectUri = webServerRedirectUri;
+	}
+	
+	public String getWebServerRedirectUri(){
+		return this.webServerRedirectUri;
+	}
+			
+	public void setAuthorities(String authorities){
+		this.authorities = authorities;
+	}
+	
+	public String getAuthorities(){
+		return this.authorities;
+	}
+			
+	public void setAccessTokenValidity(Integer accessTokenValidity){
+		this.accessTokenValidity = accessTokenValidity;
+	}
+	
+	public Integer getAccessTokenValidity(){
+		return this.accessTokenValidity;
+	}
+			
+	public void setRefreshTokenValidity(Integer refreshTokenValidity){
+		this.refreshTokenValidity = refreshTokenValidity;
+	}
+	
+	public Integer getRefreshTokenValidity(){
+		return this.refreshTokenValidity;
+	}
+			
+	public void setAdditionalInformation(String additionalInformation){
+		this.additionalInformation = additionalInformation;
+	}
+	
+	public String getAdditionalInformation(){
+		return this.additionalInformation;
+	}
+			
+	public void setAutoapprove(String autoapprove){
+		this.autoapprove = autoapprove;
+	}
+	
+	public String getAutoapprove(){
+		return this.autoapprove;
+	}
+			
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 131 - 0
edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/entity/SysRole.java

@@ -0,0 +1,131 @@
+package com.keao.edu.auth.api.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.List;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+/**
+ * 对应数据库表(sys_role):
+ */
+public class SysRole {
+
+	/**  */
+	private Integer id;
+	
+	/**  */
+	@ApiModelProperty(value = "角色名称",required = false)
+	private String roleName;
+	
+	/**  */
+	@ApiModelProperty(value = "角色编码",required = false)
+	private String roleCode;
+	
+	/**  */
+	@ApiModelProperty(value = "角色描述",required = false)
+	private String roleDesc;
+	
+	/**  */
+	private java.util.Date createTime;
+	
+	/**  */
+	private java.util.Date updateTime;
+
+	private String tenantId;
+	
+	/** 删除标识(0-正常,1-删除) */
+	@ApiModelProperty(value = "删除标识(0-正常,1-删除)",required = false)
+	private String delFlag;
+	
+	private Integer organId;
+
+	@ApiModelProperty(value = "菜单列表",required = false)
+	private List<Integer> menuIds;
+
+	public String getTenantId() {
+		return tenantId;
+	}
+
+	public void setTenantId(String tenantId) {
+		this.tenantId = tenantId;
+	}
+
+	public List<Integer> getMenuIds() {
+		return menuIds;
+	}
+
+	public void setMenuIds(List<Integer> menuIds) {
+		this.menuIds = menuIds;
+	}
+
+	public Integer getId() {
+		return id;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	public void setRoleName(String roleName){
+		this.roleName = roleName;
+	}
+	
+	public String getRoleName(){
+		return this.roleName;
+	}
+			
+	public void setRoleCode(String roleCode){
+		this.roleCode = roleCode;
+	}
+	
+	public String getRoleCode(){
+		return this.roleCode;
+	}
+			
+	public void setRoleDesc(String roleDesc){
+		this.roleDesc = roleDesc;
+	}
+	
+	public String getRoleDesc(){
+		return this.roleDesc;
+	}
+			
+	public void setCreateTime(java.util.Date createTime){
+		this.createTime = createTime;
+	}
+	
+	public java.util.Date getCreateTime(){
+		return this.createTime;
+	}
+			
+	public void setUpdateTime(java.util.Date updateTime){
+		this.updateTime = updateTime;
+	}
+	
+	public java.util.Date getUpdateTime(){
+		return this.updateTime;
+	}
+			
+	public void setDelFlag(String delFlag){
+		this.delFlag = delFlag;
+	}
+	
+	public String getDelFlag(){
+		return this.delFlag;
+	}
+			
+	public Integer getOrganId() {
+		return organId;
+	}
+
+	public void setOrganId(Integer organId) {
+		this.organId = organId;
+	}
+
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 51 - 0
edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/entity/SysRoleDept.java

@@ -0,0 +1,51 @@
+package com.keao.edu.auth.api.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+/**
+ * 对应数据库表(sys_role_dept):
+ */
+public class SysRoleDept {
+
+	/**  */
+	private Integer id;
+	
+	/** 角色ID */
+	@ApiModelProperty(value = "角色ID",required = false)
+	private Integer roleId;
+	
+	/** 部门ID */
+	@ApiModelProperty(value = "部门ID",required = false)
+	private Integer deptId;
+	
+	public void setId(Integer id){
+		this.id = id;
+	}
+	
+	public Integer getId(){
+		return this.id;
+	}
+			
+	public void setRoleId(Integer roleId){
+		this.roleId = roleId;
+	}
+	
+	public Integer getRoleId(){
+		return this.roleId;
+	}
+			
+	public void setDeptId(Integer deptId){
+		this.deptId = deptId;
+	}
+	
+	public Integer getDeptId(){
+		return this.deptId;
+	}
+			
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 58 - 0
edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/entity/SysRoleMenu.java

@@ -0,0 +1,58 @@
+package com.keao.edu.auth.api.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+/**
+ * 对应数据库表(sys_role_menu):
+ */
+public class SysRoleMenu {
+
+	/** 角色ID */
+	@ApiModelProperty(value = "角色ID",required = false)
+	private Integer roleId;
+	
+	/** 菜单ID */
+	@ApiModelProperty(value = "菜单ID",required = false)
+	private Integer menuId;
+
+	private String tenantId;
+
+	public SysRoleMenu(Integer roleId, Integer menuId) {
+		this.roleId = roleId;
+		this.menuId = menuId;
+	}
+
+	public String getTenantId() {
+		return tenantId;
+	}
+
+	public void setTenantId(String tenantId) {
+		this.tenantId = tenantId;
+	}
+
+	public SysRoleMenu() {
+	}
+
+	public void setRoleId(Integer roleId){
+		this.roleId = roleId;
+	}
+	
+	public Integer getRoleId(){
+		return this.roleId;
+	}
+			
+	public void setMenuId(Integer menuId){
+		this.menuId = menuId;
+	}
+	
+	public Integer getMenuId(){
+		return this.menuId;
+	}
+			
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 307 - 0
edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/entity/SysUser.java

@@ -0,0 +1,307 @@
+package com.keao.edu.auth.api.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+/**
+ * 对应数据库表(sys_user):
+ */
+public class SysUser implements Serializable{
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -1374403507360017093L;
+
+	/** 主键ID */
+	private Integer id;
+
+	/** 用户名 */
+	@ApiModelProperty(value = "用户名",required = false)
+	private String username;
+
+	/**  */
+	@ApiModelProperty(value = "密码",required = false)
+	private String password;
+
+	/** 随机盐 */
+	@ApiModelProperty(value = "随机盐",required = false)
+	private String salt;
+
+	@ApiModelProperty(value = "手机号",required = false)
+	private String phone;
+
+	/** 头像 */
+	@ApiModelProperty(value = "头像",required = false)
+	private String avatar;
+
+	/** 创建时间 */
+	private java.util.Date createTime;
+
+	/** 修改时间 */
+	private java.util.Date updateTime;
+
+	/** 0-正常,9-锁定 */
+	@ApiModelProperty(value = "0-正常,9-锁定",required = false)
+	private Integer lockFlag;
+
+	/** 0-正常,1-删除 */
+	@ApiModelProperty(value = "0-正常,1-删除",required = false)
+	private Integer delFlag;
+
+	/** 微信openid */
+	@ApiModelProperty(value = "微信openid",required = false)
+	private String wxOpenid;
+
+	/** QQ openid */
+	@ApiModelProperty(value = "QQ openid",required = false)
+	private String qqOpenid;
+
+	/** 用户类型 */
+//	@ApiModelProperty(value = "用户类型",required = false)
+	//STUDENT("学生"), EDU_TEACHER("教务老师"), TEACHER("指导老师"), SYSTEM("系统內置"), ADMIN("管理员")
+	private String userType;
+
+	@ApiModelProperty(value = "性别0女1男",required = false)
+	private Integer gender;
+
+	@ApiModelProperty(value = "民族",required = false)
+	private String nation;
+
+	@ApiModelProperty(value = "生日",required = false)
+	private Date birthdate;
+
+	@ApiModelProperty(value = "邮箱",required = false)
+	private String email;
+
+	@ApiModelProperty(value = "融云token",required = false)
+	private String imToken;
+
+	@ApiModelProperty(value = "身份证号",required = false)
+	private String idCardNo;
+
+	@ApiModelProperty(value = "真实姓名",required = false)
+	private String realName;
+
+	@ApiModelProperty(value = "微信号",required = false)
+	private String wechatId;
+	
+	@ApiModelProperty(value = "是否是超管",required = false)
+	private Boolean isSuperAdmin = false;
+
+	@ApiModelProperty(value = "用户角色",required = false)
+	private List<Integer> roles;
+
+	private String tenantId;
+
+	public String getTenantId() {
+		return tenantId;
+	}
+
+	public void setTenantId(String tenantId) {
+		this.tenantId = tenantId;
+	}
+
+	public String getRealName() {
+		return realName;
+	}
+
+	public void setRealName(String realName) {
+		this.realName = realName;
+	}
+
+	public String getImToken() {
+		return imToken;
+	}
+
+	public void setImToken(String imToken) {
+		this.imToken = imToken;
+	}
+
+	public Integer getId() {
+		return id;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	public void setUsername(String username) {
+		this.username = username;
+	}
+
+	public String getUsername() {
+		return this.username;
+	}
+
+	public void setPassword(String password) {
+		this.password = password;
+	}
+
+	public String getPassword() {
+		return this.password;
+	}
+
+	public void setSalt(String salt) {
+		this.salt = salt;
+	}
+
+	public String getSalt() {
+		return this.salt;
+	}
+
+	public void setPhone(String phone) {
+		this.phone = phone;
+	}
+
+	public String getPhone() {
+		return this.phone;
+	}
+
+	public void setAvatar(String avatar) {
+		this.avatar = avatar;
+	}
+
+	public String getAvatar() {
+		return this.avatar;
+	}
+
+	public void setCreateTime(java.util.Date createTime) {
+		this.createTime = createTime;
+	}
+
+	public java.util.Date getCreateTime() {
+		return this.createTime;
+	}
+
+	public void setUpdateTime(java.util.Date updateTime) {
+		this.updateTime = updateTime;
+	}
+
+	public java.util.Date getUpdateTime() {
+		return this.updateTime;
+	}
+
+	public Integer getLockFlag() {
+		return lockFlag;
+	}
+
+	public void setLockFlag(Integer lockFlag) {
+		this.lockFlag = lockFlag;
+	}
+
+	public Boolean getSuperAdmin() {
+		return isSuperAdmin;
+	}
+
+	public void setSuperAdmin(Boolean superAdmin) {
+		isSuperAdmin = superAdmin;
+	}
+
+	public Integer getDelFlag() {
+		return delFlag;
+	}
+
+	public void setDelFlag(Integer delFlag) {
+		this.delFlag = delFlag;
+	}
+
+	public void setWxOpenid(String wxOpenid) {
+		this.wxOpenid = wxOpenid;
+	}
+
+	public String getWxOpenid() {
+		return this.wxOpenid;
+	}
+
+	public void setQqOpenid(String qqOpenid) {
+		this.qqOpenid = qqOpenid;
+	}
+
+	public String getQqOpenid() {
+		return this.qqOpenid;
+	}
+
+	public String getUserType() {
+		return userType;
+	}
+
+	public void setUserType(String userType) {
+		this.userType = userType;
+	}
+
+	public Integer getGender() {
+		return gender;
+	}
+
+	public void setGender(Integer gender) {
+		this.gender = gender;
+	}
+
+	public String getNation() {
+		return nation;
+	}
+
+	public void setNation(String nation) {
+		this.nation = nation;
+	}
+
+	public Date getBirthdate() {
+		return birthdate;
+	}
+
+	public void setBirthdate(Date birthdate) {
+		this.birthdate = birthdate;
+	}
+
+	public String getEmail() {
+		return email;
+	}
+
+	public void setEmail(String email) {
+		this.email = email;
+	}
+
+	public String getIdCardNo() {
+		return idCardNo;
+	}
+
+	public void setIdCardNo(String idCardNo) {
+		this.idCardNo = idCardNo;
+	}
+
+	public String getWechatId() {
+		return wechatId;
+	}
+
+	public void setWechatId(String wechatId) {
+		this.wechatId = wechatId;
+	}
+
+	public Boolean getIsSuperAdmin() {
+		return isSuperAdmin;
+	}
+
+	public void setIsSuperAdmin(Boolean isSuperAdmin) {
+		this.isSuperAdmin = isSuperAdmin;
+	}
+
+	public List<Integer> getRoles() {
+		return roles;
+	}
+
+	public void setRoles(List<Integer> roles) {
+		this.roles = roles;
+	}
+
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 100 - 0
edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/entity/SysUserLogin.java

@@ -0,0 +1,100 @@
+package com.keao.edu.auth.api.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+/**
+ * 对应数据库表(sys_user_login):
+ */
+public class SysUserLogin {
+
+	/**  */
+	@ApiModelProperty(value = "用户编号",required = false)
+	private Integer userId;
+	
+	/** 用户登录总次数 */
+	@ApiModelProperty(value = "用户登录总次数",required = false)
+	private Integer loginCount;
+	
+	/** 最后登录时间 */
+	@ApiModelProperty(value = "最后登录时间",required = false)
+	private java.util.Date lastLoginTime;
+	
+	/** 最后登录IP */
+	@ApiModelProperty(value = "最后登录IP",required = false)
+	private String lastLoginIp;
+	
+	/** 连续登陆失败的次数 */
+	@ApiModelProperty(value = "连续登陆失败的次数",required = false)
+	private Integer failCount;
+	
+	/** 锁定时间 单位:分钟(超过锁定时间自动解锁) */
+	@ApiModelProperty(value = "锁定时间 单位:分钟",required = false)
+	private Integer lockTime;
+	
+	/** 锁定日期 */
+	@ApiModelProperty(value = "锁定日期",required = false)
+	private java.util.Date lockDate;
+
+	public Integer getUserId() {
+		return userId;
+	}
+
+	public void setUserId(Integer userId) {
+		this.userId = userId;
+	}
+
+	public void setLoginCount(Integer loginCount){
+		this.loginCount = loginCount;
+	}
+	
+	public Integer getLoginCount(){
+		return this.loginCount;
+	}
+			
+	public void setLastLoginTime(java.util.Date lastLoginTime){
+		this.lastLoginTime = lastLoginTime;
+	}
+	
+	public java.util.Date getLastLoginTime(){
+		return this.lastLoginTime;
+	}
+			
+	public void setLastLoginIp(String lastLoginIp){
+		this.lastLoginIp = lastLoginIp;
+	}
+	
+	public String getLastLoginIp(){
+		return this.lastLoginIp;
+	}
+			
+	public void setFailCount(Integer failCount){
+		this.failCount = failCount;
+	}
+	
+	public Integer getFailCount(){
+		return this.failCount;
+	}
+			
+	public void setLockTime(Integer lockTime){
+		this.lockTime = lockTime;
+	}
+	
+	public Integer getLockTime(){
+		return this.lockTime;
+	}
+			
+	public void setLockDate(java.util.Date lockDate){
+		this.lockDate = lockDate;
+	}
+	
+	public java.util.Date getLockDate(){
+		return this.lockDate;
+	}
+			
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 74 - 0
edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/entity/SysUserLoginLog.java

@@ -0,0 +1,74 @@
+package com.keao.edu.auth.api.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+/**
+ * 对应数据库表(sys_user_login_log):
+ */
+public class SysUserLoginLog {
+
+	private Long id;
+
+	/** 会员ID */
+	@ApiModelProperty(value = "会员ID",required = false)
+	private Integer userId;
+
+	/** 登录IP */
+	@ApiModelProperty(value = "登录IP",required = false)
+	private String loginIp;
+
+	/** 登录时间 */
+	@ApiModelProperty(value = "登录时间",required = false)
+	private java.util.Date loginTime;
+
+	/** 终端类型(0,pc端;1,人工;2,移动端;3,自动) */
+	@ApiModelProperty(value = "终端类型(0,pc端;1,人工;2,移动端;3,自动)",required = false)
+	private Integer source;
+
+	public Long getId() {
+		return id;
+	}
+
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public Integer getUserId() {
+		return userId;
+	}
+
+	public void setUserId(Integer userId) {
+		this.userId = userId;
+	}
+
+	public void setLoginIp(String loginIp) {
+		this.loginIp = loginIp;
+	}
+
+	public String getLoginIp() {
+		return this.loginIp;
+	}
+
+	public void setLoginTime(java.util.Date loginTime) {
+		this.loginTime = loginTime;
+	}
+
+	public java.util.Date getLoginTime() {
+		return this.loginTime;
+	}
+
+	public void setSource(Integer source) {
+		this.source = source;
+	}
+
+	public Integer getSource() {
+		return this.source;
+	}
+
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 52 - 0
edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/entity/SysUserRole.java

@@ -0,0 +1,52 @@
+package com.keao.edu.auth.api.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+/**
+ * 对应数据库表(sys_user_role):
+ */
+public class SysUserRole {
+	//分部经理
+	public static Integer SECTION_MANAGER = 3;
+	//教务老师
+	public static Integer EDUCATIONAL_TEACHER = 4;
+	//运营主管
+	public static Integer OPERATION_EXECUTIVE = 5;
+	//招生主管
+	public static Integer ADMISSIONS_DIRECTOR = 6;
+	//教学主任
+	public static Integer DEAN_OF_STUDIES = 7;
+	//总部管理员
+	public static Integer ADMINISTRATOR = 25;
+
+	/** 用户ID */
+	@ApiModelProperty(value = "用户ID",required = false)
+	private Integer userId;
+	
+	/** 角色ID */
+	@ApiModelProperty(value = "角色ID",required = false)
+	private Integer roleId;
+	
+	public void setUserId(Integer userId){
+		this.userId = userId;
+	}
+	
+	public Integer getUserId(){
+		return this.userId;
+	}
+			
+	public void setRoleId(Integer roleId){
+		this.roleId = roleId;
+	}
+	
+	public Integer getRoleId(){
+		return this.roleId;
+	}
+			
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 36 - 0
edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/enums/SysUserType.java

@@ -0,0 +1,36 @@
+package com.keao.edu.auth.api.enums;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.keao.edu.common.enums.BaseEnum;
+
+public enum SysUserType implements BaseEnum<String, SysUserType> {
+
+	STUDENT("学生"), EDUCATION("教务老师"), TEACHER("指导老师"), SYSTEM("系统內置"), ADMIN("管理员");
+
+	private String desc;
+
+	private SysUserType(String desc) {
+	}
+
+	@Override
+	public String getCode() {
+		return name();
+	}
+
+	public String getDesc() {
+		return desc;
+	}
+
+	public static SysUserType queryByName(String name) {
+		if (StringUtils.isBlank(name)) {
+			return null;
+		}
+		for (SysUserType sysUserType : SysUserType.values()) {
+			if (name.equals(sysUserType.getCode())) {
+				return sysUserType;
+			}
+		}
+		return null;
+	}
+}

+ 42 - 0
edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/enums/UserLockFlag.java

@@ -0,0 +1,42 @@
+package com.keao.edu.auth.api.enums;
+
+import com.keao.edu.common.enums.BaseEnum;
+
+public enum UserLockFlag implements BaseEnum<Integer, UserLockFlag> {
+
+	NORMAL(0, "正常"), LOCKED(9, "锁定"), CANCELLED(1, "冻结");
+
+	private int code;
+
+	UserLockFlag(int code, String remark) {
+		this.code = code;
+		this.remark = remark;
+	}
+
+	private String remark;
+
+	public Integer getCode() {
+		return code;
+	}
+
+	public void setCode(int code) {
+		this.code = code;
+	}
+
+	public String getRemark() {
+		return remark;
+	}
+
+	public void setRemark(String remark) {
+		this.remark = remark;
+	}
+
+	public static UserLockFlag codeOf(int code) {
+		for (UserLockFlag userStatus : UserLockFlag.values()) {
+			if (code == userStatus.getCode()) {
+				return userStatus;
+			}
+		}
+		return null;
+	}
+}

+ 12 - 0
edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/util/SecurityConstants.java

@@ -0,0 +1,12 @@
+package com.keao.edu.auth.api.util;
+
+public interface SecurityConstants {
+
+	public static final String USERNAME_PRINCIPAL_PREFIX = "username:";
+
+	public static final String PHONE_PRINCIPAL_PREFIX = "phone:";
+
+	String PARAM_VERIFY_EXCEPTION = "参数校验异常";
+
+	String VERIFY_FAILURE = "校验失败";
+}

+ 55 - 0
edu-user/edu-user-client-api/src/main/java/com/keao/edu/auth/api/util/SecurityUtils.java

@@ -0,0 +1,55 @@
+package com.keao.edu.auth.api.util;
+
+import com.alibaba.fastjson.JSON;
+import com.keao.edu.auth.api.dto.AuthUser;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+import java.util.Map;
+
+public class SecurityUtils {
+	/**
+	 * 获取Authentication
+	 */
+	public static Authentication getAuthentication() {
+		return SecurityContextHolder.getContext().getAuthentication();
+	}
+
+	/**
+	 * 获取用户
+	 */
+	public static AuthUser getUser(Authentication authentication) {
+		Object principal = authentication.getPrincipal();
+		if (principal instanceof AuthUser) {
+			return (AuthUser) principal;
+		}
+		return null;
+	}
+
+	/**
+	 * 获取用户
+	 */
+	public static Object getPrincipal() {
+		Authentication authentication = getAuthentication();
+		if (authentication == null) {
+			return null;
+		}
+		return authentication.getPrincipal();
+	}
+
+	/**
+	 * 获取用户
+	 */
+	public static AuthUser getUser() {
+		Authentication authentication = getAuthentication();
+		return getUser(authentication);
+	}
+
+	public static String getAuthenticationValue(){
+		return "bearer " + JSON.parseObject(JSON.toJSONString(getAuthentication().getDetails()), Map.class).get("tokenValue").toString();
+	}
+
+	public static String getToken(){
+		return JSON.parseObject(JSON.toJSONString(getAuthentication().getDetails()), Map.class).get("tokenValue").toString();
+	}
+}

+ 10 - 0
edu-user/edu-user-server/src/main/java/com/keao/edu/user/dao/ExamRoomDao.java

@@ -0,0 +1,10 @@
+package com.keao.edu.user.dao;
+
+
+import com.keao.edu.common.dal.BaseDAO;
+import com.keao.edu.user.entity.ExamRoom;
+
+public interface ExamRoomDao extends BaseDAO<Long, ExamRoom> {
+
+	
+}

+ 9 - 0
edu-user/edu-user-server/src/main/java/com/keao/edu/user/service/ExamRoomService.java

@@ -0,0 +1,9 @@
+package com.keao.edu.user.service;
+
+
+import com.keao.edu.common.service.BaseService;
+import com.keao.edu.user.entity.ExamRoom;
+
+public interface ExamRoomService extends BaseService<Long, ExamRoom> {
+
+}

+ 23 - 0
edu-user/edu-user-server/src/main/java/com/keao/edu/user/service/impl/ExamRoomServiceImpl.java

@@ -0,0 +1,23 @@
+package com.keao.edu.user.service.impl;
+
+
+import com.keao.edu.common.dal.BaseDAO;
+import com.keao.edu.common.service.impl.BaseServiceImpl;
+import com.keao.edu.user.dao.ExamRoomDao;
+import com.keao.edu.user.entity.ExamRoom;
+import com.keao.edu.user.service.ExamRoomService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class ExamRoomServiceImpl extends BaseServiceImpl<Long, ExamRoom> implements ExamRoomService {
+	
+	@Autowired
+	private ExamRoomDao examRoomDao;
+
+	@Override
+	public BaseDAO<Long, ExamRoom> getDAO() {
+		return examRoomDao;
+	}
+	
+}

+ 2 - 2
edu-user/edu-user-server/src/main/resources/application.yml

@@ -50,9 +50,9 @@ spring:
     maxOpenPreparedStatements: 20
 
   redis:
-    host: 192.168.3.151
+    host: 47.99.212.176
     port: 6379
-    password:
+    password: dyym
     database: 1
     #连接超时时间(毫秒)
     timeout: 10000

+ 88 - 0
edu-user/edu-user-server/src/main/resources/config/mybatis/ExamRoomMapper.xml

@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<!--
+这个文件是自动生成的。
+不要修改此文件。所有改动将在下次重新自动生成时丢失。
+-->
+<mapper namespace="com.keao.edu.user.dao.ExamRoomDao">
+	
+	<resultMap type="com.keao.edu.auth.api.entity.ExamRoom" id="ExamRoom">
+		<result column="id_" property="id" />
+		<result column="exam_mode_" property="examMode" />
+		<result column="exam_location_id_" property="examLocationId" />
+		<result column="subject_id_list_" property="subjectIdList" />
+		<result column="main_teacher_user_id_" property="mainTeacherUserId" />
+		<result column="assistant_teacher_user_id_list_" property="assistantTeacherUserIdList" />
+		<result column="exam_time_json_" property="examTimeJson" />
+		<result column="del_flag_" property="delFlag" />
+		<result column="create_time_" property="createTime" />
+		<result column="update_time_" property="updateTime" />
+		<result column="tenant_id_" property="tenantId" />
+	</resultMap>
+	
+	<!-- 根据主键查询一条记录 -->
+	<select id="get" resultMap="ExamRoom" >
+		SELECT * FROM exam_room WHERE id_ = #{id} 
+	</select>
+	
+	<!-- 全查询 -->
+	<select id="findAll" resultMap="ExamRoom">
+		SELECT * FROM exam_room ORDER BY id_
+	</select>
+	
+	<!-- 向数据库增加一条记录 -->
+	<insert id="insert" parameterType="com.keao.edu.auth.api.entity.ExamRoom" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
+		INSERT INTO exam_room (id_,exam_mode_,exam_location_id_,subject_id_list_,main_teacher_user_id_,
+		assistant_teacher_user_id_list_,exam_time_json_,del_flag_,create_time_,update_time_,tenant_id_)
+		VALUES(#{id},#{examMode},#{examLocationId},#{subjectIdList},#{mainTeacherUserId},#{assistantTeacherUserIdList},
+		#{examTimeJson},#{delFlag},NOW(),NOW(),#{tenantId})
+	</insert>
+	
+	<!-- 根据主键查询一条记录 -->
+	<update id="update" parameterType="com.keao.edu.auth.api.entity.ExamRoom">
+		UPDATE exam_room <set>
+		<if test="delFlag != null">
+		del_flag_ = #{delFlag},
+		</if>
+		<if test="examTimeJson != null">
+		exam_time_json_ = #{examTimeJson},
+		</if>
+		<if test="subjectIdList != null">
+		subject_id_list_ = #{subjectIdList},
+		</if>
+		<if test="tenantId != null">
+		tenant_id_ = #{tenantId},
+		</if>
+		<if test="updateTime != null">
+		update_time_ = #{updateTime},
+		</if>
+		<if test="examMode != null">
+		exam_mode_ = #{examMode},
+		</if>
+		<if test="examLocationId != null">
+		exam_location_id_ = #{examLocationId},
+		</if>
+		<if test="mainTeacherUserId != null">
+		main_teacher_user_id_ = #{mainTeacherUserId},
+		</if>
+		<if test="assistantTeacherUserIdList != null">
+		assistant_teacher_user_id_list_ = #{assistantTeacherUserIdList},
+		</if>
+		</set> WHERE id_ = #{id}
+	</update>
+	
+	<!-- 根据主键删除一条记录 -->
+	<delete id="delete" >
+		DELETE FROM exam_room WHERE id_ = #{id} 
+	</delete>
+	
+	<!-- 分页查询 -->
+	<select id="queryPage" resultMap="ExamRoom" parameterType="map">
+		SELECT * FROM exam_room ORDER BY id_ <include refid="global.limit"/>
+	</select>
+	
+	<!-- 查询当前表的总记录数 -->
+	<select id="queryCount" resultType="int">
+		SELECT COUNT(*) FROM exam_room
+	</select>
+</mapper>

+ 0 - 17
pom.xml

@@ -78,22 +78,6 @@
 				<scope>import</scope>
 			</dependency>
 
-			<dependency>
-				<groupId>org.springframework.cloud</groupId>
-				<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
-				<version>0.9.0.RELEASE</version>
-				<exclusions>
-					<exclusion>
-						<groupId>com.alibaba</groupId>
-						<artifactId>fastjson</artifactId>
-					</exclusion>
-					<exclusion>
-						<groupId>commons-io</groupId>
-						<artifactId>commons-io</artifactId>
-					</exclusion>
-				</exclusions>
-			</dependency>
-
 			<!-- swagger-spring-boot -->
 			<dependency>
 				<groupId>com.spring4all</groupId>
@@ -116,7 +100,6 @@
 			<dependency>
 				<groupId>com.baomidou</groupId>
 				<artifactId>mybatis-plus</artifactId>
-				<version>3.3.1.tmp</version>
 			</dependency>
 
 			<dependency>