Browse Source

Merge branch 'master' of http://git.kdan.cc:8865/Server_Service/pdf_office_back_end

wangPH 2 năm trước cách đây
mục cha
commit
6cc248373b

+ 59 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/controller/LoginDeviceController.java

@@ -0,0 +1,59 @@
+package cn.kdan.cloud.pdf.office.account.controller;
+
+import cn.kdan.cloud.pdf.office.account.constant.UserConstant;
+import cn.kdan.cloud.pdf.office.account.model.LoginDevice;
+import cn.kdan.cloud.pdf.office.account.service.LoginDeviceService;
+import cn.kdan.cloud.pdf.office.common.constant.CommonConstant;
+import cn.kdan.cloud.pdf.office.common.pojo.ResultMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @author tangxiangan
+ */
+@RestController
+@RequestMapping("loginDevice")
+public class LoginDeviceController {
+
+    @Autowired
+    private LoginDeviceService loginDeviceService;
+
+
+    /**
+     * 记录登录设备
+     * @param loginDevice
+     * @return
+     */
+    @PostMapping("create")
+    public ResultMap<Boolean> create(@RequestBody LoginDevice loginDevice) {
+        loginDeviceService.create(loginDevice);
+        return new ResultMap<>(CommonConstant.SUCCESS, CommonConstant.RESULT_SUCCESS, Boolean.TRUE);
+    }
+
+    /**
+     * 获取用户的设备登录情况
+     * @param userId
+     * @return
+     */
+    @GetMapping("getByUserId")
+    public ResultMap<List<LoginDevice>> getByUserId(@RequestParam("userId") String userId) {
+        return new ResultMap<>(CommonConstant.SUCCESS, CommonConstant.RESULT_SUCCESS,loginDeviceService.getByUserId(userId));
+    }
+
+
+    /**
+     * 删除登录设备记录
+     * @param deviceSign
+     * @param appId
+     * @return
+     */
+    @PostMapping("delete")
+    public ResultMap<Boolean> delete(@RequestParam("deviceSign") String deviceSign,@RequestParam("appId") String appId) {
+        loginDeviceService.delete(deviceSign,appId);
+        return new ResultMap<>(CommonConstant.SUCCESS, CommonConstant.RESULT_SUCCESS,Boolean.TRUE);
+    }
+
+
+}

+ 274 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/model/LoginDevice.java

@@ -0,0 +1,274 @@
+package cn.kdan.cloud.pdf.office.account.model;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class LoginDevice implements Serializable {
+    private String id;
+
+    private String productId;
+
+    private String uniqueSn;
+
+    private String userId;
+
+    private String model;
+
+    private String os;
+
+    private String language;
+
+    private String timeZone;
+
+    private String appVersion;
+
+    private Short platform;
+
+    private Date updatedAt;
+
+    private Date createdAt;
+
+    private String appId;
+
+    private static final long serialVersionUID = 1L;
+
+    public String getId() {
+        return id;
+    }
+
+    public LoginDevice withId(String id) {
+        this.setId(id);
+        return this;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getProductId() {
+        return productId;
+    }
+
+    public LoginDevice withProductId(String productId) {
+        this.setProductId(productId);
+        return this;
+    }
+
+    public void setProductId(String productId) {
+        this.productId = productId;
+    }
+
+    public String getUniqueSn() {
+        return uniqueSn;
+    }
+
+    public LoginDevice withUniqueSn(String uniqueSn) {
+        this.setUniqueSn(uniqueSn);
+        return this;
+    }
+
+    public void setUniqueSn(String uniqueSn) {
+        this.uniqueSn = uniqueSn;
+    }
+
+    public String getUserId() {
+        return userId;
+    }
+
+    public LoginDevice withUserId(String userId) {
+        this.setUserId(userId);
+        return this;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public String getModel() {
+        return model;
+    }
+
+    public LoginDevice withModel(String model) {
+        this.setModel(model);
+        return this;
+    }
+
+    public void setModel(String model) {
+        this.model = model;
+    }
+
+    public String getOs() {
+        return os;
+    }
+
+    public LoginDevice withOs(String os) {
+        this.setOs(os);
+        return this;
+    }
+
+    public void setOs(String os) {
+        this.os = os;
+    }
+
+    public String getLanguage() {
+        return language;
+    }
+
+    public LoginDevice withLanguage(String language) {
+        this.setLanguage(language);
+        return this;
+    }
+
+    public void setLanguage(String language) {
+        this.language = language;
+    }
+
+    public String getTimeZone() {
+        return timeZone;
+    }
+
+    public LoginDevice withTimeZone(String timeZone) {
+        this.setTimeZone(timeZone);
+        return this;
+    }
+
+    public void setTimeZone(String timeZone) {
+        this.timeZone = timeZone;
+    }
+
+    public String getAppVersion() {
+        return appVersion;
+    }
+
+    public LoginDevice withAppVersion(String appVersion) {
+        this.setAppVersion(appVersion);
+        return this;
+    }
+
+    public void setAppVersion(String appVersion) {
+        this.appVersion = appVersion;
+    }
+
+    public Short getPlatform() {
+        return platform;
+    }
+
+    public LoginDevice withPlatform(Short platform) {
+        this.setPlatform(platform);
+        return this;
+    }
+
+    public void setPlatform(Short platform) {
+        this.platform = platform;
+    }
+
+    public Date getUpdatedAt() {
+        return updatedAt;
+    }
+
+    public LoginDevice withUpdatedAt(Date updatedAt) {
+        this.setUpdatedAt(updatedAt);
+        return this;
+    }
+
+    public void setUpdatedAt(Date updatedAt) {
+        this.updatedAt = updatedAt;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public LoginDevice withCreatedAt(Date createdAt) {
+        this.setCreatedAt(createdAt);
+        return this;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public String getAppId() {
+        return appId;
+    }
+
+    public LoginDevice withAppId(String appId) {
+        this.setAppId(appId);
+        return this;
+    }
+
+    public void setAppId(String appId) {
+        this.appId = appId;
+    }
+
+    @Override
+    public boolean equals(Object that) {
+        if (this == that) {
+            return true;
+        }
+        if (that == null) {
+            return false;
+        }
+        if (getClass() != that.getClass()) {
+            return false;
+        }
+        LoginDevice other = (LoginDevice) that;
+        return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
+            && (this.getProductId() == null ? other.getProductId() == null : this.getProductId().equals(other.getProductId()))
+            && (this.getUniqueSn() == null ? other.getUniqueSn() == null : this.getUniqueSn().equals(other.getUniqueSn()))
+            && (this.getUserId() == null ? other.getUserId() == null : this.getUserId().equals(other.getUserId()))
+            && (this.getModel() == null ? other.getModel() == null : this.getModel().equals(other.getModel()))
+            && (this.getOs() == null ? other.getOs() == null : this.getOs().equals(other.getOs()))
+            && (this.getLanguage() == null ? other.getLanguage() == null : this.getLanguage().equals(other.getLanguage()))
+            && (this.getTimeZone() == null ? other.getTimeZone() == null : this.getTimeZone().equals(other.getTimeZone()))
+            && (this.getAppVersion() == null ? other.getAppVersion() == null : this.getAppVersion().equals(other.getAppVersion()))
+            && (this.getPlatform() == null ? other.getPlatform() == null : this.getPlatform().equals(other.getPlatform()))
+            && (this.getUpdatedAt() == null ? other.getUpdatedAt() == null : this.getUpdatedAt().equals(other.getUpdatedAt()))
+            && (this.getCreatedAt() == null ? other.getCreatedAt() == null : this.getCreatedAt().equals(other.getCreatedAt()))
+            && (this.getAppId() == null ? other.getAppId() == null : this.getAppId().equals(other.getAppId()));
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
+        result = prime * result + ((getProductId() == null) ? 0 : getProductId().hashCode());
+        result = prime * result + ((getUniqueSn() == null) ? 0 : getUniqueSn().hashCode());
+        result = prime * result + ((getUserId() == null) ? 0 : getUserId().hashCode());
+        result = prime * result + ((getModel() == null) ? 0 : getModel().hashCode());
+        result = prime * result + ((getOs() == null) ? 0 : getOs().hashCode());
+        result = prime * result + ((getLanguage() == null) ? 0 : getLanguage().hashCode());
+        result = prime * result + ((getTimeZone() == null) ? 0 : getTimeZone().hashCode());
+        result = prime * result + ((getAppVersion() == null) ? 0 : getAppVersion().hashCode());
+        result = prime * result + ((getPlatform() == null) ? 0 : getPlatform().hashCode());
+        result = prime * result + ((getUpdatedAt() == null) ? 0 : getUpdatedAt().hashCode());
+        result = prime * result + ((getCreatedAt() == null) ? 0 : getCreatedAt().hashCode());
+        result = prime * result + ((getAppId() == null) ? 0 : getAppId().hashCode());
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getClass().getSimpleName());
+        sb.append(" [");
+        sb.append("Hash = ").append(hashCode());
+        sb.append(", id=").append(id);
+        sb.append(", productId=").append(productId);
+        sb.append(", uniqueSn=").append(uniqueSn);
+        sb.append(", userId=").append(userId);
+        sb.append(", model=").append(model);
+        sb.append(", os=").append(os);
+        sb.append(", language=").append(language);
+        sb.append(", timeZone=").append(timeZone);
+        sb.append(", appVersion=").append(appVersion);
+        sb.append(", platform=").append(platform);
+        sb.append(", updatedAt=").append(updatedAt);
+        sb.append(", createdAt=").append(createdAt);
+        sb.append(", appId=").append(appId);
+        sb.append(", serialVersionUID=").append(serialVersionUID);
+        sb.append("]");
+        return sb.toString();
+    }
+}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1131 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/model/LoginDeviceExample.java


+ 36 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/service/LoginDeviceService.java

@@ -0,0 +1,36 @@
+package cn.kdan.cloud.pdf.office.account.service;
+
+import cn.kdan.cloud.pdf.office.account.model.LoginDevice;
+import cn.kdan.cloud.pdf.office.account.model.User;
+import cn.kdan.cloud.pdf.office.common.dto.UserRegisterDTO;
+import cn.kdan.cloud.pdf.office.common.vo.UserInfoVO;
+
+import java.util.List;
+
+/**
+ * 登录设备服务
+ * @author tangxiangan
+ */
+public interface LoginDeviceService {
+    /**
+     * 插入登录设备信息
+     *
+     * @param loginDevice 登录设备
+     */
+    void create (LoginDevice loginDevice);
+
+    /**
+     * 获取用户某个产品的设备登录情况
+     * @param userId 用户id
+     * @return
+     */
+    List<LoginDevice> getByUserId(String userId);
+
+    /**
+     * 删除登录设备记录
+     *
+     * @param deviceSign 设备码
+     * @param appId 产品id
+     */
+    void delete(String deviceSign, String appId);
+}

+ 41 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/service/impl/LoginDeviceServiceImpl.java

@@ -0,0 +1,41 @@
+package cn.kdan.cloud.pdf.office.account.service.impl;
+
+import cn.kdan.cloud.pdf.office.account.mapper.LoginDeviceMapper;
+import cn.kdan.cloud.pdf.office.account.model.LoginDevice;
+import cn.kdan.cloud.pdf.office.account.model.LoginDeviceExample;
+import cn.kdan.cloud.pdf.office.account.service.LoginDeviceService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * @author tangxiangan
+ */
+@Service
+public class LoginDeviceServiceImpl implements LoginDeviceService {
+
+    @Resource
+    private LoginDeviceMapper loginDeviceMapper;
+
+    @Override
+    public void create(LoginDevice loginDevice) {
+        loginDeviceMapper.insert(loginDevice);
+    }
+
+
+    @Override
+    public List<LoginDevice> getByUserId(String userId) {
+        LoginDeviceExample example = new LoginDeviceExample();
+        example.createCriteria().andUserIdEqualTo(userId);
+        return loginDeviceMapper.selectByExample(example);
+    }
+
+    @Override
+    public void delete(String deviceSign,String appId) {
+        LoginDeviceExample example = new LoginDeviceExample();
+        example.createCriteria().andUniqueSnEqualTo(deviceSign).andAppIdEqualTo(appId);
+        loginDeviceMapper.deleteByExample(example);
+    }
+
+}

+ 2 - 1
pdf-office-account/src/main/resources/generatorConfig.xml

@@ -40,6 +40,7 @@
 			<property name="enableSubPackages" value="true" />
 		</javaClientGenerator>
 <!--		<table tableName="oauth_client_details"/>-->
-		<table tableName="user"/>
+<!--		<table tableName="user"/>-->
+		<table tableName="login_device"/>
 	</context>
 </generatorConfiguration>

+ 47 - 0
pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/feign/LoginDeviceApi.java

@@ -0,0 +1,47 @@
+package cn.kdan.cloud.pdf.office.api.account.feign;
+
+import cn.kdan.cloud.pdf.office.api.account.feign.hystrix.LoginDeviceApiHystrix;
+import cn.kdan.cloud.pdf.office.api.account.vo.LoginDevice;
+import cn.kdan.cloud.pdf.office.common.constant.CommonConstant;
+import cn.kdan.cloud.pdf.office.common.pojo.ResultMap;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
+
+
+/**
+ * @author tangxiangan
+ */
+@Component
+@FeignClient(value = CommonConstant.ACCOUNT_PROVIDER_NAME + "/loginDevice", fallback = LoginDeviceApiHystrix.class)
+public interface LoginDeviceApi {
+
+
+    @PostMapping(value = "create")
+    ResultMap<Boolean> create(@RequestBody LoginDevice loginDevice);
+
+    /**
+     * 删除登录设备记录
+     * @param deviceSign
+     * @param appId
+     * @return
+     */
+    @PostMapping("delete")
+    ResultMap<Boolean> delete(@RequestParam("deviceSign") String deviceSign, @RequestParam("appId") String appId) ;
+
+
+    /**
+     * 获取用户的设备登录情况
+     * @param userId
+     * @return
+     */
+    @GetMapping("getByUserId")
+    ResultMap<List<LoginDevice>> getByUserId(@RequestParam("userId") String userId);
+
+
+}

+ 33 - 0
pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/feign/hystrix/LoginDeviceApiHystrix.java

@@ -0,0 +1,33 @@
+package cn.kdan.cloud.pdf.office.api.account.feign.hystrix;
+
+
+import cn.kdan.cloud.pdf.office.api.account.feign.LoginDeviceApi;
+import cn.kdan.cloud.pdf.office.api.account.vo.LoginDevice;
+import cn.kdan.cloud.pdf.office.common.constant.CommonConstant;
+import cn.kdan.cloud.pdf.office.common.pojo.ResultMap;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+
+/**
+ * @author tangxiangan
+ */
+@Service
+public class LoginDeviceApiHystrix implements LoginDeviceApi {
+
+    @Override
+    public ResultMap<Boolean> create(LoginDevice loginDevice) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
+    @Override
+    public ResultMap<Boolean> delete(String deviceSign, String appId) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+
+    @Override
+    public ResultMap<List<LoginDevice>> getByUserId(String userId) {
+        return new ResultMap<>(CommonConstant.ERROR, CommonConstant.RESULT_ERROR_SERVICE_NOT_AVAILABLE);
+    }
+}

+ 35 - 0
pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/vo/LoginDevice.java

@@ -0,0 +1,35 @@
+package cn.kdan.cloud.pdf.office.api.account.vo;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * @author tangxiangan
+ */
+@Data
+public class LoginDevice {
+    private String id;
+
+    private String productId;
+
+    private String uniqueSn;
+
+    private String userId;
+
+    private String model;
+
+    private String os;
+
+    private String language;
+
+    private String timeZone;
+
+    private String appVersion;
+
+    private Short platform;
+
+    private Date updatedAt;
+
+    private Date createdAt;
+}

+ 0 - 19
pdf-office-sso/src/main/java/cn/kdan/cloud/pdf/office/sso/constant/AuthConstant.java

@@ -8,40 +8,21 @@ public class AuthConstant {
     public final static int EXCEPTION_CODE_USER_NOT_FOUND = 302;
     public final static String EXCEPTION_MSG_USER_NOT_FOUND = "当前登录用户没有注册,详细信息请联系管理员";
 
-    public final static int EXCEPTION_CODE_USER_STATUS_IS_FROZEN = 303;
-    public final static String EXCEPTION_MSG_USER_STATUS_IS_FROZEN = "账号正处于冻结状态";
-
-    public final static int EXCEPTION_CODE_USER_STATUS_IS_INACTIVE = 304;
-    public final static String EXCEPTION_MSG_USER_STATUS_IS_INACTIVE = "当前登录用户没有激活或被禁用,详细信息请联系管理员";
-
-    public final static int EXCEPTION_CODE_USER_IS_LOCKED = 305;
-    public final static String EXCEPTION_MSG_USER_IS_LOCKED = "登录尝试次数过多,账号已被锁定";
-
     public final static int EXCEPTION_CODE_USER_PASSWORD_ERROR = 306;
     public final static String EXCEPTION_MSG_USER_PASSWORD_ERROR = "账号密码错误";
 
     public final static int EXCEPTION_CODE_SESSION_NOT_FOUND = 307;
     public final static String EXCEPTION_MSG_SESSION_NOT_FOUND = "账号不存在";
 
-    public final static int EXCEPTION_CODE_USER_INFO_NOT_COMPLETE = 308;
-    public final static String EXCEPTION_MSG_USER_INFO_NOT_COMPLETE = "用户资料尚未完善!";
-
     public final static int EXCEPTION_CODE_TOKEN_IS_INVALID = 310;
     public final static String EXCEPTION_MSG_TOKEN_IS_INVALID = "无效的token或者token已过期";
     public final static String EXCEPTION_MSG_PLEASE_ADD_AUTH_CONFIG = "please add auth config";
-    public final static int EXCEPTION_CODE_USER_NOT_ORG = 311;
-    public final static String EXCEPTION_MSG_USER_NOT_ORG = "该用户不属于任何机构,请联系系统管理员";
-
-    public final static int EXCEPTION_CODE_USER_PASSWORD_EXPIRED = 312;
-    public final static String EXCEPTION_MSG_USER_PASSWORD_EXPIRED = "用户密码已过期,请修改或重置密码";
 
     public final static String EXCEPTION_MSG_DEVICE_NUM_MAX = "login device is max num 2";
 
     public final static int EXCEPTION_CODE_USER_NOT_LOGIN = 313;
     public final static String EXCEPTION_MSG_USER_NOT_LOGIN = "用户没有登录,请登录后再访问";
 
-    public final static String EXCEPTION_MSG_NO_PERMISSION = "您没有当前平台的操作权限。";
-
     public final static int EXCEPTION_CODE_GET_CODE_FAIL = 314;
     public final static String EXCEPTION_MSG_GET_CODE_FAIL = "获取授权码失败";
 

+ 8 - 1
pdf-office-sso/src/main/java/cn/kdan/cloud/pdf/office/sso/service/AuthService.java

@@ -27,7 +27,14 @@ public interface AuthService {
     TokenVO emailLogin(String email, String code, String appId, String platformType, String deviceSign, HttpServletRequest request);
 
 
-    void invalidToken(String token);
+    /**
+     * 登出(token失效,清除登录设备信息)
+     * @param token token
+     * @param userId 用户id
+     * @param deviceSign 设备号
+     * @param appId appId
+     */
+    void logout(String token, String userId, String deviceSign, String appId);
 
     /**
      * 登录时判断邮箱验证码是否正确

+ 50 - 30
pdf-office-sso/src/main/java/cn/kdan/cloud/pdf/office/sso/service/impl/AuthServiceImpl.java

@@ -1,18 +1,22 @@
 package cn.kdan.cloud.pdf.office.sso.service.impl;
 
+import cn.kdan.cloud.pdf.office.api.account.feign.LoginDeviceApi;
 import cn.kdan.cloud.pdf.office.api.account.feign.OauthClientDetailsApi;
 import cn.kdan.cloud.pdf.office.api.account.feign.UserApi;
+import cn.kdan.cloud.pdf.office.api.account.vo.LoginDevice;
 import cn.kdan.cloud.pdf.office.api.account.vo.OauthClientDetails;
 import cn.kdan.cloud.pdf.office.common.constant.CommonConstant;
+import cn.kdan.cloud.pdf.office.common.enums.EmailCodeTypeEnum;
 import cn.kdan.cloud.pdf.office.common.exception.BackendRuntimeException;
 import cn.kdan.cloud.pdf.office.common.pojo.CustomUserDetails;
+import cn.kdan.cloud.pdf.office.common.utils.CommonUtils;
+import cn.kdan.cloud.pdf.office.common.utils.RedisUtils;
+import cn.kdan.cloud.pdf.office.common.vo.TokenVO;
 import cn.kdan.cloud.pdf.office.common.vo.UserInfoVO;
 import cn.kdan.cloud.pdf.office.sso.constant.AuthConstant;
-import cn.kdan.cloud.pdf.office.common.enums.EmailCodeTypeEnum;
 import cn.kdan.cloud.pdf.office.sso.service.AuthService;
-import cn.kdan.cloud.pdf.office.common.utils.RedisUtils;
-import cn.kdan.cloud.pdf.office.common.vo.TokenVO;
 import cn.kdan.cloud.pdf.office.sso.utils.TokenUtils;
+import com.alibaba.nacos.common.utils.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -43,6 +47,7 @@ import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import java.security.Principal;
 import java.util.*;
+import java.util.stream.Collectors;
 
 @Service
 @RefreshScope
@@ -51,12 +56,13 @@ public class AuthServiceImpl implements AuthService {
     private final Logger logger = LoggerFactory.getLogger(AuthServiceImpl.class);
 
     @Autowired
-    private RedisUtils<String,String> redisUtils;
+    private RedisUtils<String, String> redisUtils;
 
 
     @Autowired
     private UserApi userApi;
-
+    @Autowired
+    private LoginDeviceApi loginDeviceApi;
     @Autowired
     private OauthClientDetailsApi oauthClientDetailsApi;
 
@@ -67,7 +73,6 @@ public class AuthServiceImpl implements AuthService {
     private TokenEndpoint tokenEndpoint;
 
 
-
     @Value("${security.oauth2.client.user-authorization-uri}")
     private String authorizeUrl;
 
@@ -121,15 +126,15 @@ public class AuthServiceImpl implements AuthService {
         //如果是管理平台就去查管理平台的用户表
         UserInfoVO userInfoVO = userApi.getByAppAccount(email,appId,platformType).getResult();
         //检查用户存在
-        // checkUser(userInfoVO);
+        checkUser(userInfoVO);
         //检查邮件验证码
-       // checkEmailCodeValid(EmailCodeTypeEnum.LOGIN,email,code);
+        checkEmailCodeValid(EmailCodeTypeEnum.LOGIN,email,code);
         // 检查设备是否达到上限
-        //checkLoginDeviceNum(userInfoVO.getId());
+        checkLoginDeviceNum(userInfoVO.getId(), deviceSign);
         TokenVO vo = getTokenByUser(code, userInfoVO);
         //关联设备登录
-        //relateTokenAndDevice(vo.getAccess_token(),userInfoVO.getId(),deviceSign,appId);
-        return getTokenByUser(code, userInfoVO);
+        relateTokenAndDevice(vo.getAccess_token(), userInfoVO.getId(), deviceSign, appId);
+        return vo;
     }
 
     @Resource
@@ -137,7 +142,7 @@ public class AuthServiceImpl implements AuthService {
     private TokenStore tokenStore;
 
     @Override
-    public void invalidToken(String token) {
+    public void logout(String token, String userId, String deviceSign, String appId) {
         OAuth2AccessToken oAuth2AccessToken = tokenStore.readAccessToken(token);
         if (oAuth2AccessToken != null) {
             OAuth2RefreshToken oAuth2RefreshToken = oAuth2AccessToken.getRefreshToken();
@@ -146,6 +151,7 @@ public class AuthServiceImpl implements AuthService {
             tokenStore.removeRefreshToken(oAuth2RefreshToken);
             tokenStore.removeAccessTokenUsingRefreshToken(oAuth2RefreshToken);
         }
+        deleteTokenAndDevice(userId, deviceSign, appId);
     }
 
     /**
@@ -153,25 +159,32 @@ public class AuthServiceImpl implements AuthService {
      *
      * @param userInfoVO
      */
-    private void checkUser(UserInfoVO userInfoVO){
-        if(ObjectUtils.isEmpty(userInfoVO)){
+    private void checkUser(UserInfoVO userInfoVO) {
+        if (ObjectUtils.isEmpty(userInfoVO)) {
             throw new BackendRuntimeException(AuthConstant.EXCEPTION_MSG_USER_NOT_FOUND);
         }
     }
 
-    private void checkLoginDeviceNum(String userId){
-        //根据userId查询如果list>2
-//        if(list.size()>=2){
-//            throw new BackendRuntimeException(AuthConstant.EXCEPTION_MSG_DEVICE_NUM_MAX);
-//        }
+    /**
+     * 检查设备是否达到上限
+     * @param userId 用户id
+     * @param deviceSign 设备
+     */
+    private void checkLoginDeviceNum(String userId, String deviceSign) {
+        //根据userId查询如果list>2,并且设备号不属于其中的某一个
+        List<LoginDevice> list = loginDeviceApi.getByUserId(userId).getResult();
+        List<String> snList = list.stream().map(LoginDevice::getUniqueSn).collect(Collectors.toList());
+        if (CollectionUtils.isNotEmpty(list)&&list.size() >= 2&&!snList.contains(deviceSign)) {
+            throw new BackendRuntimeException(AuthConstant.EXCEPTION_MSG_DEVICE_NUM_MAX);
+        }
     }
 
     /**
      * 校验邮件验证码
      *
-     * @param type 邮件验证码类型
+     * @param type    邮件验证码类型
      * @param account 用户
-     * @param code 验证码
+     * @param code    验证码
      */
     private void checkEmailCodeValid(EmailCodeTypeEnum type, String account, String code) {
         //获取用户存在redis中的登录邮箱验证码
@@ -229,18 +242,25 @@ public class AuthServiceImpl implements AuthService {
      * @param deviceSign
      * @param appId
      */
-    private void relateTokenAndDevice(String token,String userId,String deviceSign,String appId){
-        //todo 登录设备表插入数据关联用户
-        redisUtils.hset(appId+AuthConstant.DEVICE_LOGIN_TOKEN_KEY,userId + CommonConstant.STRIKE_THROUGH + deviceSign ,token );
+    private void relateTokenAndDevice(String token,String userId,String deviceSign,String appId) {
+        // 登录设备表插入数据关联用户
+        LoginDevice loginDevice = new LoginDevice();
+        loginDevice.setId(CommonUtils.generateId());
+        loginDevice.setCreatedAt(new Date());
+        loginDevice.setUniqueSn(deviceSign);
+        loginDevice.setUserId(userId);
+        loginDeviceApi.create(loginDevice);
+        redisUtils.hset(appId + AuthConstant.DEVICE_LOGIN_TOKEN_KEY, userId + CommonConstant.STRIKE_THROUGH + deviceSign, token);
     }
 
-    private void deleteTokenAndDevice(String token,String userId,String deviceSign,String appId){
-        //todo 登录设备表删除数据关联用户
-        redisUtils.hdel(appId+AuthConstant.DEVICE_LOGIN_TOKEN_KEY,userId + CommonConstant.STRIKE_THROUGH + deviceSign );
+    private void deleteTokenAndDevice(String userId, String deviceSign, String appId) {
+        // 登录设备表删除数据关联用户
+        loginDeviceApi.delete(deviceSign, appId);
+        redisUtils.hdel(appId + AuthConstant.DEVICE_LOGIN_TOKEN_KEY, userId + CommonConstant.STRIKE_THROUGH + deviceSign);
     }
 
-    private TokenVO convert(OAuth2AccessToken token){
-        if(token == null) {
+    private TokenVO convert(OAuth2AccessToken token) {
+        if (token == null) {
             return null;
         }
         TokenVO tokenVO = new TokenVO();
@@ -258,7 +278,7 @@ public class AuthServiceImpl implements AuthService {
         keySet.add(AuthConstant.ACCESS+token);
         keySet.add(AuthConstant.AUTH+token);
         keySet.add(AuthConstant.ACCESS_TO_REFRESH + token);
-        long time = 30 * 60L;
+        long time = 30 * 24 * 60 * 60L;
         keySet.forEach(key -> redisUtils.expire(key, time));
     }