init project

This commit is contained in:
2021-07-08 18:02:26 +08:00
commit 10e056aa44
380 changed files with 28364 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>wms</artifactId>
<groupId>com.mt</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>wms-passport</artifactId>
<dependencies>
<dependency>
<groupId>com.mt</groupId>
<artifactId>wms-core</artifactId>
</dependency>
<dependency>
<groupId>com.mt</groupId>
<artifactId>wms-upms</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- spring session -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<!-- swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
<!-- useragent -->
<dependency>
<groupId>nl.basjes.parse.useragent</groupId>
<artifactId>yauaa</artifactId>
<version>${useragent.version}</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2019.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* 统一用户配置
*
* @author jiff
* @date 2018/11/1
* @since 1.0
*/
@ConfigurationProperties("wms.passport")
@Validated
@Data
@Component
public class PassportConfig {
/**
* 忽略认证的接口地址,此处配置的地址不做认证和鉴权处理,如果会话存在则返回当前用户信息
*/
@NotNull
@Valid
private List<String> ignoreAuthentications = new ArrayList<>();
/**
* 忽略鉴权的接口地址,此处配置的地址只做认证不做鉴权,如果认证通过返回当前用户信息
*/
@NotNull
@Valid
private List<String> ignoreAuthorizations = new ArrayList<>();
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2018.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.config;
import com.mt.wms.passport.resolver.CookieHeaderHttpSessionIdResolver;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.session.web.http.HttpSessionIdResolver;
/**
* @author jiff
* @date 2018/11/1
* @since 1.0
*/
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3 * 24 * 3600)
@AutoConfigureAfter(RedisAutoConfiguration.class)
@Slf4j
public class WebSessionConfig {
/**
* session策略这里配置的是自定义同时支持Cookie和Header方式有提供HeaderCookie等方式
*
* @return
*/
@Bean
public HttpSessionIdResolver httpSessionIdResolver() {
return CookieHeaderHttpSessionIdResolver.token();
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2019.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.constants;
/**
* @author jiff
* @date 2019-08-01
* @since 1.0
*/
public interface PassportConstant {
/**
* 内部临时令牌,用于漫游登录时创建会话
*/
String PASSPORT_INNER_NONCE_TOKEN = "passportInnerNonceToken";
/**
* 内部临时令牌有效期,单位秒
*/
long PASSPORT_INNER_NONCE_TOKEN_EXPIRED = 3L;
/**
* 微信oauthCode获取openId保存到redis有效时间{@value},单位秒
*/
long WECHAT_OAUTH_CODE_EXPIRED = 5 * 60L;
/**
* 异常状态0、正常1、省份异常2、地市异常3、区县异常
*/
int LOGIN_ABNORMAL_STATUS_NORMAL = 0;
int LOGIN_ABNORMAL_STATUS_PROVINCE = 1;
int LOGIN_ABNORMAL_STATUS_CITY = 2;
int LOGIN_ABNORMAL_STATUS_COUNTY = 3;
/**
* 手机号码是否激活0、未激活1、激活根据是否使用过短信验证码登录确认是否激活状态
*/
int MOBILE_ENABLED_VALID = 1;
int MOBILE_ENABLED_INVALID = 0;
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2019.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.controller;
import com.mt.wms.core.base.BaseController;
import com.mt.wms.core.dto.LoginLogDto;
import com.mt.wms.core.vo.R;
import com.mt.wms.passport.service.LogService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author jiff
* @date 2019-07-20
* @since 1.0
*/
@RestController
@RequestMapping("log")
@Slf4j
@Validated
@Api(value = "日志接口", hidden = true)
public class LogController extends BaseController {
@Autowired
private LogService logService;
@PostMapping("loginLog")
@ApiOperation(value = "保存登录日志", notes = "提供给内部调用,后续加上权限控制", hidden = true)
public R<Long> loginLog(@RequestBody LoginLogDto loginLogDto) {
return logService.saveLoginLog(loginLogDto);
}
}

View File

@@ -0,0 +1,307 @@
/*
* Copyright (c) 2018.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.controller;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mt.wms.core.api.Assert;
import com.mt.wms.core.base.BaseController;
import com.mt.wms.core.constants.CommonConstant;
import com.mt.wms.core.constants.RedisConstant;
import com.mt.wms.core.dto.ApiLogDto;
import com.mt.wms.core.dto.LoginLogDto;
import com.mt.wms.core.dto.LoginUser;
import com.mt.wms.core.dto.Permission;
import com.mt.wms.core.errorcode.ApiErrorCode;
import com.mt.wms.core.service.RedisService;
import com.mt.wms.core.vo.R;
import com.mt.wms.core.vo.TokenVo;
import com.mt.wms.passport.config.PassportConfig;
import com.mt.wms.passport.feign.PlatformUpmsService;
import com.mt.wms.passport.params.LoginParam;
import com.mt.wms.passport.params.MobileLoginParam;
import com.mt.wms.passport.service.LogService;
import com.mt.wms.passport.service.PassportService;
import com.mt.wms.passport.service.SessionService;
import com.mt.wms.passport.validator.groups.PasswordLoginGroup;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.Session;
import org.springframework.util.AntPathMatcher;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpSession;
import javax.validation.groups.Default;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author jiff
* @date 2018/11/1
* @since 1.0
*/
@RestController
@RequestMapping(CommonConstant.API_MODULE_PASSPORT)
@Slf4j
@Validated
@Api(value = "统一用户接口", description = "封装用户认证鉴权相关接口")
public class PassportController extends BaseController {
private AntPathMatcher antPathMatcher = new AntPathMatcher();
@Autowired
private PlatformUpmsService platformUpmsService;
@Autowired
private LogService logService;
@Autowired
private SessionService sessionService;
@Autowired
private PassportService passportService;
@Autowired
private RedisService redisService;
@Autowired
private FindByIndexNameSessionRepository<? extends Session> sessionRepository;
@Autowired
private PassportConfig passportConfig;
@PostMapping("login")
@ApiOperation(value = "用户名密码登录", notes = "返回会话令牌")
public R<TokenVo> login(@Validated({Default.class, PasswordLoginGroup.class}) @RequestBody LoginParam loginParam) {
if (log.isDebugEnabled()) {
log.debug("登录请求消息:{}", loginParam);
}
String mobile = loginParam.getMobile();
String password = loginParam.getPassword();
R<LoginUser> r = null;
switch (loginParam.getUserType()) {
case LoginUser.USER_TYPE_PLATFORM:
r = platformUpmsService.login(mobile, password);
break;
default:
break;
}
if (r != null && r.ok()) {
return loginSuccessHandler(r.getData(), loginParam);
}
return failed(r == null ? "登录失败,用户名或密码错误!" : r.getMsg());
}
@PostMapping("mobileLogin")
@ApiOperation(value = "短信验证码登录", notes = "返回会话令牌")
public R<TokenVo> login(@Validated @RequestBody MobileLoginParam loginParam) {
if (log.isDebugEnabled()) {
log.debug("登录请求消息:{}", loginParam);
}
String mobile = loginParam.getMobile();
String smsCode = loginParam.getSmsCode();
String validSmsCode = redisService.get(RedisConstant.genSmsCodeKey(mobile));
if (StringUtils.isNoneBlank(smsCode, validSmsCode) && smsCode.equals(validSmsCode)) {
redisService.del(RedisConstant.genSmsCodeKey(mobile));
R<LoginUser> r = null;
switch (loginParam.getUserType()) {
case LoginUser.USER_TYPE_PLATFORM:
r = platformUpmsService.getLoginUser(mobile);
break;
default:
break;
}
if (r != null && r.ok()) {
LoginUser loginUser = r.getData();
//更新手机号码激活状态
LoginParam loginParam1 = LoginParam.builder().build();
BeanUtils.copyProperties(loginParam, loginParam1);
return loginSuccessHandler(loginUser, loginParam1);
} else {
return failed(r == null ? "登录失败,手机号码或验证码错误!" : r.getMsg());
}
}
return failed("登录失败,手机号码或验证码错误!");
}
private R<TokenVo> loginSuccessHandler(LoginUser loginUser, LoginParam loginParam) {
String unionId = null;
String openId = null;
String wechatAppId = loginParam.getWechatAppId();
String oauthCode = loginParam.getOauthCode();
int appType = loginParam.getAppType();
Long passportUserId = loginUser.getPassportUserId();
//当前登录用户信息存入session中
HttpSession session = getHttpServletRequest().getSession();
loginUser.setAppType(loginParam.getAppType());
loginUser.setLoginType(LoginLogDto.LOGIN_TYPE_SELF);
loginUser.setWechatAppId(wechatAppId);
loginUser.setOpenId(openId);
session.setAttribute(LoginUser.HTTP_HEADER_NAME, JSON.toJSONString(loginUser));
session.setAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, loginUser.getMobile());
//保存登录日志
passportService.saveLoginLog(LoginLogDto.builder()
.sessionId(session.getId())
.passportUserId(loginUser.getPassportUserId())
.userId(loginUser.getUserId())
.orgId(loginUser.getOrgId())
.mobile(loginUser.getMobile())
.userName(loginUser.getUserName())
.userType(loginUser.getUserType())
.appType(loginUser.getAppType())
.appCode(loginUser.getAppCode())
.ip(HttpUtil.getClientIP(getHttpServletRequest()))
.userAgent(getHttpServletRequest().getHeader(HttpHeaders.USER_AGENT))
.loginType(loginUser.getLoginType())
.loginTime(new Date())
.action(LoginLogDto.ACTION_LOGIN)
.build());
if (log.isDebugEnabled()) {
log.debug("登录成功sessionId={}", session.getId());
}
return R.ok("登录成功", TokenVo.builder().token(session.getId()).build());
}
@PostMapping(value = "getLoginUser")
@ApiOperation(value = "获取登录用户", notes = "返回登录用户信息")
public R<LoginUser> getLoginUserVo() {
LoginUser loginUser = getLoginUser();
if (loginUser == null) {
return R.unauthorized();
}
return successful(loginUser);
}
@PostMapping("authorization")
@ApiOperation(value = "用户鉴权", notes = "返回登录用户信息", hidden = true)
public R<LoginUser> authorization(@RequestParam String url, @RequestParam String method) {
if (log.isDebugEnabled()) {
log.debug("用户鉴权url={},method={}", url, method);
}
Assert.notNull(ApiErrorCode.FAILED, url, method);
HttpSession session = getHttpServletRequest().getSession(false);
LoginUser loginUser = null;
if (session != null) {
String loginUserJson = (String) session.getAttribute(LoginUser.HTTP_HEADER_NAME);
if (StringUtils.isNotBlank(loginUserJson)) {
loginUser = JSON.parseObject(loginUserJson, LoginUser.class);
}
}
//如果忽略认证,则直接返回成功
if (isIgnoreAuthentication(url)) {
//登录用户信息为空保存接口调用日志
if (loginUser != null) {
passportService.saveApiLog(ApiLogDto.builder()
.sessionId(session.getId())
.passportUserId(loginUser.getPassportUserId())
.userId(loginUser.getUserId())
.userName(loginUser.getUserName())
.userType(loginUser.getUserType())
.ip(HttpUtil.getClientIP(getHttpServletRequest()))
.userAgent(getHttpServletRequest().getHeader(HttpHeaders.USER_AGENT))
.url(url).method(method)
.time(new Date())
.build());
}
return successful(loginUser);
} else if (loginUser == null) {
return R.unauthorized();
}
boolean hasPermission = false;
//忽略鉴权
if (isIgnoreAuthorization(url)) {
hasPermission = true;
} else {
List<Permission> permissions;
switch (loginUser.getUserType()) {
case LoginUser.USER_TYPE_PLATFORM: {
permissions = platformUpmsService.getPermissions();
break;
}
default:
permissions = new ArrayList<>();
break;
}
if (permissions != null) {
for (Permission permission : permissions) {
if (StringUtils.isNotEmpty(permission.getUrl()) && antPathMatcher.match(permission.getUrl(), url)
&& method.equalsIgnoreCase(permission.getMethod())) {
hasPermission = true;
break;
}
}
}
}
passportService.saveApiLog(ApiLogDto.builder()
.sessionId(session.getId())
.passportUserId(loginUser.getPassportUserId())
.userId(loginUser.getUserId())
.userName(loginUser.getUserName())
.userType(loginUser.getUserType())
.ip(HttpUtil.getClientIP(getHttpServletRequest()))
.userAgent(getHttpServletRequest().getHeader(HttpHeaders.USER_AGENT))
.url(url).method(method)
.time(new Date())
.build());
if (hasPermission) {
return R.ok("鉴权成功", loginUser);
} else {
return R.forbidden();
}
}
/**
* 是否忽略认证
*
* @param url 接口地址
* @return
*/
private boolean isIgnoreAuthentication(String url) {
for (String ignore : passportConfig.getIgnoreAuthentications()) {
if (log.isDebugEnabled()) {
log.debug("ignore authentication url is {}", ignore);
}
if (antPathMatcher.match(ignore, url)) {
return true;
}
}
return false;
}
/**
* 是否忽略鉴权
*
* @param url 接口地址
* @return
*/
private boolean isIgnoreAuthorization(String url) {
for (String ignore : passportConfig.getIgnoreAuthorizations()) {
if (log.isDebugEnabled()) {
log.debug("ignore authorization url is {}", ignore);
}
if (antPathMatcher.match(ignore, url)) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,90 @@
/*
* Copyright (c) 2019.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.controller;
import com.mt.wms.core.base.BaseController;
import com.mt.wms.core.dto.LoginUser;
import com.mt.wms.core.params.MobileParam;
import com.mt.wms.core.vo.PageVo;
import com.mt.wms.core.vo.R;
import com.mt.wms.passport.params.BatchInvalidateSessionParam;
import com.mt.wms.passport.params.QueryLoginLogParam;
import com.mt.wms.passport.params.QuerySessionParam;
import com.mt.wms.passport.params.SessionParam;
import com.mt.wms.passport.service.SessionService;
import com.mt.wms.passport.vo.LoginLogVo;
import com.mt.wms.passport.vo.LoginSessionVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @author jiff
* @date 2019-07-20
* @since 1.0
*/
@RestController
@RequestMapping("session")
@Slf4j
@Validated
@Api(value = "会话接口", description = "会话接口")
public class SessionController extends BaseController {
@Autowired
private SessionService sessionService;
@PostMapping("list")
@ApiOperation(value = "获取在线会话列表", notes = "获取在线会话列表")
public R<PageVo<LoginSessionVo>> list(@RequestBody QuerySessionParam param) {
return sessionService.list(param);
}
@PostMapping("listLog")
@ApiOperation(value = "获取会话日志列表", notes = "获取会话日志列表")
public R<PageVo<LoginLogVo>> listLog(@RequestBody QueryLoginLogParam param) {
return sessionService.listLog(param);
}
@PostMapping(value = "invalidateSession")
@ApiOperation(value = "注销用户会话", notes = "返回被注销的用户会话ID")
public R<String> invalidateSession(@RequestBody SessionParam param) {
return sessionService.invalidateSession(param);
}
@PostMapping(value = "batchInvalidateSession")
@ApiOperation(value = "批量注销用户会话", notes = "返回被注销的用户会话ID")
public R<List<String>> batchInvalidateSession(@RequestBody BatchInvalidateSessionParam param) {
return sessionService.batchInvalidateSession(param);
}
@PostMapping(value = "invalidateSessionByMobile")
@ApiOperation(value = "注销用户会话", notes = "返回被注销的用户会话ID")
public R<List<String>> invalidateSession(@RequestBody MobileParam param) {
return sessionService.invalidateSession(param);
}
@PostMapping(value = "invalidateAllSession")
@ApiOperation(value = "注销所有平台用户会话", notes = "返回被注销的用户会话ID")
public R<List<String>> invalidateSession() {
return sessionService.invalidateAllPlatformSession();
}
@PostMapping(value = "getSession")
@ApiOperation(value = "获取登录用户", notes = "返回登录用户信息")
public R<List<LoginUser>> getLoginSession(@RequestBody MobileParam param) {
return sessionService.getLoginSession(param);
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2020.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.dto;
import com.mt.wms.core.base.BaseDto;
import lombok.*;
import lombok.experimental.Accessors;
/**
* @author jiff
* @date 2020/3/26
* @since 1.0
*/
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@Builder
public class WechatOauthCode2Token extends BaseDto {
private String openId;
private String unionId;
/**
* 公众号访问令牌
*/
private String accessToken;
/**
* 小程序会话标识
*/
private String sessionKey;
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) 2018.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.feign;
import com.mt.wms.core.dto.LoginUser;
import com.mt.wms.core.vo.R;
import com.mt.wms.core.vo.TokenVo;
import com.mt.wms.passport.constants.PassportConstant;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
/**
* @author jiff
* @date 2018-11-30
* @since 1.0
*/
@FeignClient(name = "lis-passport")
public interface InnerService {
@PostMapping("/innerRoamLogin")
R<TokenVo> login(@RequestHeader(PassportConstant.PASSPORT_INNER_NONCE_TOKEN) String token, @RequestBody LoginUser loginUser);
}

View File

@@ -0,0 +1,18 @@
/*
* Copyright (c) 2018.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.feign;
import com.mt.wms.passport.feign.fallback.PlatformUpmsServiceFallback;
import org.springframework.cloud.openfeign.FeignClient;
/**
* @author jiff
* @date 2018/11/1
* @since 1.0
*/
@FeignClient(name = "wms-platform-upms", fallback = PlatformUpmsServiceFallback.class)
public interface PlatformUpmsService extends UpmsService {
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright (c) 2018.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.feign;
import com.mt.wms.core.dto.LoginUser;
import com.mt.wms.core.dto.Permission;
import com.mt.wms.core.utils.SpringContextUtil;
import com.mt.wms.core.vo.LoginUserVo;
import com.mt.wms.core.vo.R;
import com.mt.wms.upms.params.ModifyPasswordParam;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.io.Serializable;
import java.util.List;
/**
* @author jiff
* @date 2018/11/1
* @since 1.0
*/
public interface UpmsService {
/**
* 获取当前用户权限信息
*
* @return 权限信息
*/
@PostMapping("/upms/getPermissions")
List<Permission> getPermissions();
/**
* 获取当前登录用户信息
*
* @return 登录用户信息
*/
@PostMapping("/upms/getLoginUser")
R<LoginUserVo> getLoginUser();
/**
* 获取登录用户信息
*
* @param mobile 手机号码
* @return 登录用户信息
*/
@PostMapping("/upms/getLoginUserByMobile")
R<LoginUser> getLoginUser(@RequestParam("mobile") String mobile);
/**
* 密码登录
*
* @param mobile 手机号码
* @param password 密码
* @return 登录结果
*/
@PostMapping("/upms/login")
R<LoginUser> login(@RequestParam("mobile") String mobile, @RequestParam("password") String password);
/**
* 修改密码
*
* @param param 修改密码参数
* @return 处理结果
*/
@PostMapping("/upms/modifyPassword")
R<Serializable> modifyPassword(@RequestBody ModifyPasswordParam param);
/**
* 退出登录
*
* @return 处理结果
*/
@PostMapping("/upms/logout")
R<Serializable> logout();
/**
* 是否debug模式开发模式允许使用缓存数据
*
* @return true、false
*/
default boolean isDebug() {
return SpringContextUtil.getActiveProfile().equals("dev");
}
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright (c) 2018.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.feign.fallback;
import com.mt.wms.passport.feign.InnerService;
import com.mt.wms.core.dto.LoginUser;
import com.mt.wms.core.vo.R;
import com.mt.wms.core.vo.TokenVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* @author jiff
* @date 2018/11/30
* @since 1.0
*/
@Slf4j
@Service
public class InnerServiceFallback implements InnerService {
@Override
public R<TokenVo> login(String token, LoginUser loginUser) {
return null;
}
}

View File

@@ -0,0 +1,121 @@
/*
* Copyright (c) 2018.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.feign.fallback;
import com.mt.wms.core.dto.LoginUser;
import com.mt.wms.core.dto.Permission;
import com.mt.wms.core.vo.LoginUserVo;
import com.mt.wms.core.vo.R;
import com.mt.wms.passport.feign.PlatformUpmsService;
import com.mt.wms.upms.params.ModifyPasswordParam;
import com.mt.wms.upms.service.UpmsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* @author jiff
* @date 2018/11/1
* @since 1.0
*/
@Slf4j
@Service
public class PlatformUpmsServiceFallback implements PlatformUpmsService {
@Autowired
private UpmsService upmsService;
/**
* 获取当前用户权限信息
*
* @return 权限信息
*/
@Override
public List<Permission> getPermissions() {
if (isDebug()) {
log.warn("平台通用权限管理服务不可用,使用缓存权限数据");
List<Permission> permissions = new ArrayList<>();
permissions.add(Permission.builder().url("/**").method(HttpMethod.GET.name()).build());
permissions.add(Permission.builder().url("/**").method(HttpMethod.POST.name()).build());
return permissions;
}
return upmsService.getPermissions();
}
/**
* 获取当前登录用户信息
*
* @return 登录用户信息
*/
@Override
public R<LoginUserVo> getLoginUser() {
if (isDebug()) {
log.warn("平台通用权限管理服务不可用,使用测试用户数据");
return R.ok(LoginUserVo.builder().userId(1L).mobile("13588441519").userName("jiff")
.orgId(1L).build());
}
return upmsService.getLoginUserVo();
}
/**
* 获取登录用户信息
*
* @param mobile 手机号码
* @return 登录用户信息
*/
@Override
public R<LoginUser> getLoginUser(String mobile) {
if (isDebug()) {
log.warn("平台通用权限管理服务不可用,使用测试用户数据");
return R.ok(LoginUser.builder().userId(1L).mobile(mobile).userName("jiff")
.orgId(1L).userType(LoginUser.USER_TYPE_PLATFORM).build());
}
return upmsService.getLoginUser(mobile);
}
/**
* 密码登录
*
* @param mobile 手机号码
* @param password 密码
* @return 登录结果
*/
@Override
public R<LoginUser> login(String mobile, String password) {
if (isDebug()) {
log.warn("平台通用权限管理服务不可用,使用测试用户数据");
return R.ok(LoginUser.builder().userId(1L).mobile("13588441519").userName("jiff")
.orgId(1L).userType(LoginUser.USER_TYPE_PLATFORM).build());
}
return upmsService.login(mobile, password);
}
/**
* 修改密码
*
* @param param 修改密码参数
* @return 处理结果
*/
@Override
public R<Serializable> modifyPassword(ModifyPasswordParam param) {
return R.failed();
}
/**
* 退出登录
*
* @return 处理结果
*/
@Override
public R<Serializable> logout() {
return upmsService.logout();
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2018.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.listener;
import com.mt.wms.core.dto.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.session.Session;
import org.springframework.session.events.SessionCreatedEvent;
import org.springframework.stereotype.Component;
/**
* @author jiff
* @date 2018-12-12
* @since 1.0
*/
@Slf4j
@Component
public class SessionCreatedEventListener implements ApplicationListener<SessionCreatedEvent> {
/**
* Handle an application event.
*
* @param event the event to respond to
*/
@Override
public void onApplicationEvent(SessionCreatedEvent event) {
String sessionId = event.getSessionId();
Session session = event.getSession();
log.info("创建会话[{}],用户信息:{}", sessionId, session.getAttribute(LoginUser.HTTP_HEADER_NAME));
//session.setMaxInactiveInterval(Duration.ofSeconds(5L)); 无用设置
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2018.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.listener;
import com.mt.wms.core.dto.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.session.Session;
import org.springframework.session.events.SessionExpiredEvent;
import org.springframework.stereotype.Component;
/**
* @author jiff
* @date 2018-12-12
* @since 1.0
*/
@Slf4j
@Component
public class SessionExpiredEventListener implements ApplicationListener<SessionExpiredEvent> {
/**
* Handle an application event.
*
* @param event the event to respond to
*/
@Override
public void onApplicationEvent(SessionExpiredEvent event) {
String sessionId = event.getSessionId();
Session session = event.getSession();
log.info("会话[{}]过期,用户信息:{}", sessionId, session.getAttribute(LoginUser.HTTP_HEADER_NAME));
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 2019.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.params;
import com.mt.wms.core.base.BaseParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* @author jiff
* @date 2019/7/20
* @since 1.0
*/
@EqualsAndHashCode(callSuper = true)
@Data
@Builder
@ApiModel(value = "批量注销会话请求对象", description = "用于管理用户会话")
public class BatchInvalidateSessionParam extends BaseParam {
@ApiModelProperty(value = "会话ID", required = true, example = "[1]")
@NotNull(message = "会话ID不能为空")
private List<String> sessionIds;
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) 2018.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.params;
import com.mt.wms.core.enums.AppTypeEnum;
import com.mt.wms.core.enums.UserTypeEnum;
import com.mt.wms.core.base.BaseParam;
import com.mt.wms.core.validator.constraints.Enum;
import com.mt.wms.passport.validator.groups.WechatLoginGroup;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* @author jiff
* @date 2018/11/13
* @since 1.0
*/
@EqualsAndHashCode(callSuper = true)
@Data
@Builder
@ApiModel("登录请求对象")
public class LoginParam extends BaseParam {
@ApiModelProperty(value = "应用类型:\n" +
"1、\tpc\n" +
"2、\tapp\n" +
"3、\twechat\n" +
"4、\tminiapp", required = true, example = "1")
@Enum(message = "非法的应用类型", target = {AppTypeEnum.class})
@NotNull(message = "应用类型不能为空")
private int appType;
@ApiModelProperty(value = "用户类型:\n" +
"1、\t平台\n" +
"2、\t合作伙伴\n" +
"3、\t医院\n" +
"4、\t用户", required = true, example = "1")
@Enum(message = "非法的用户类型", target = {UserTypeEnum.class})
@NotNull(message = "用户类型不能为空")
private Integer userType;
@ApiModelProperty(value = "用户名", required = true, example = "13588441519")
private String mobile;
@ApiModelProperty(value = "密码", required = true, example = "123456")
private String password;
@ApiModelProperty(value = "微信APPID", required = false, example = "13588441519")
@NotBlank(message = "微信APPID不能为空", groups = {WechatLoginGroup.class})
private String wechatAppId;
@ApiModelProperty(value = "微信OAuthCode用户获取微信用户openid", required = false, example = "13588441519")
private String oauthCode;
@ApiModelProperty(value = "openId", required = true, example = "13588441519")
@NotBlank(message = "openId", groups = {WechatLoginGroup.class})
private String openId;
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2018.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.params;
import com.mt.wms.core.enums.AppTypeEnum;
import com.mt.wms.core.enums.UserTypeEnum;
import com.mt.wms.core.base.BaseParam;
import com.mt.wms.core.validator.constraints.Enum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
/**
* @author jiff
* @date 2018/11/13
* @since 1.0
*/
@EqualsAndHashCode(callSuper = true)
@Data
@Builder
@ApiModel(value = "短信验证码登录请求对象", description = "用于短信验证码登录")
public class MobileLoginParam extends BaseParam {
@ApiModelProperty(value = "应用类型:\n" +
"1、\tpc\n" +
"2、\tapp\n" +
"3、\twechat\n" +
"4、\tminiapp", required = true, example = "3")
@NotNull(message = "用户类型不能为空")
@Enum(message = "非法的应用类型", target = {AppTypeEnum.class})
private int appType;
@ApiModelProperty(value = "用户类型:\n" +
"1、\tPC管理端\n" +
"2、\t移动端", required = true, example = "1")
@Enum(message = "非法的用户类型", target = {UserTypeEnum.class})
@NotNull(message = "用户类型不能为空")
private Integer userType;
@ApiModelProperty(value = "手机号码", required = true, example = "13588441519")
@NotBlank(message = "手机号码不能为空")
@Pattern(regexp = "^1[3456789]\\d{9}$", message = "手机号码格式不正确")
private String mobile;
@ApiModelProperty(value = "短信验证码", required = true, example = "1234")
@Length(min = 4, max = 4, message = "短信验证码长度为4位")
private String smsCode;
@ApiModelProperty(value = "微信APPID", required = false, example = "13588441519")
private String wechatAppId;
@ApiModelProperty(value = "微信OAuthCode用户获取微信用户openid", required = false, example = "13588441519")
private String oauthCode;
}

View File

@@ -0,0 +1,212 @@
/*
* Copyright (c) 2019.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.params;
import com.mt.wms.core.enums.AppTypeEnum;
import com.mt.wms.core.enums.UserTypeEnum;
import com.mt.wms.core.params.BasePageParam;
import com.mt.wms.core.validator.constraints.Enum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 登录会话日志
* </p>
*
* @author jiff
* @since 2019-07-20
*/
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Data
@Builder
@ApiModel("查询会话日志请求对象")
public class QueryLoginLogParam extends BasePageParam {
private static final long serialVersionUID = 1L;
/**
* 会话ID
*/
@ApiModelProperty("会话ID")
private String sessionId;
/**
* 父会话ID漫游登录时需要保存发起漫游用户的会话ID
*/
@ApiModelProperty("父会话ID漫游登录时需要保存发起漫游用户的会话ID")
private String parentSessionId;
/**
* 统一用户ID
*/
@ApiModelProperty("统一用户ID")
private Long passportUserId;
/**
* 用户ID
*/
@ApiModelProperty("用户ID")
private Long userId;
/**
* 合作伙伴ID合作伙伴用户或者医院用户登录时会存储
*/
@ApiModelProperty("合作伙伴ID合作伙伴用户或者医院用户登录时会存储")
private Long partnerId;
/**
* 医院ID
*/
@ApiModelProperty("医院ID")
private Long hospitalId;
/**
* 组织ID
*/
@ApiModelProperty("组织ID")
private Long orgId;
/**
* 手机号
*/
@ApiModelProperty("手机号")
private String mobile;
/**
* 用户名称
*/
@ApiModelProperty("用户名称")
private String userName;
/**
* 用户类型1、平台用户2、合作伙伴用户3、医院用户4、患者
*/
@ApiModelProperty(value = "用户类型1、平台用户2、合作伙伴用户3、医院用户4、患者", example = "1")
@Enum(message = "非法的用户类型", target = {UserTypeEnum.class})
private Integer userType;
/**
* 应用类型1、pc2、app3、wechat4、miniapp
*/
@ApiModelProperty(value = "应用类型:\n" +
"1、\tpc\n" +
"2、\tapp\n" +
"3、\twechat\n" +
"4、\tminiapp", required = false, example = "1")
@Enum(message = "非法的应用类型", target = {AppTypeEnum.class})
private Integer appType;
/**
* 应用编码:暂未使用
*/
@ApiModelProperty("应用编码:暂未使用")
private Integer appCode;
/**
* 登录类型1、自主登录2、漫游登录
*/
@ApiModelProperty("登录类型1、自主登录2、漫游登录")
private Integer loginType;
/**
* 退出类型1、自主退出2、管理退出3超时退出
*/
@ApiModelProperty(value = "退出类型1、自主退出2、管理退出3超时退出", example = "1")
private Integer logoutType;
/**
* 异常状态0、正常1、省份异常2、地市异常3、区县异常
*/
@ApiModelProperty(value = "异常状态0、正常1、省份异常2、地市异常3、区县异常", example = "0")
private Integer abnormalStatus;
/**
* 开始时间
*/
@ApiModelProperty(value = "开始时间格式yyyy-MM-dd", example = "2019-08-01")
private String startTime;
/**
* 结束时间
*/
@ApiModelProperty(value = "结束时间格式yyyy-MM-dd", example = "2019-08-01")
private String endTime;
/**
* 退出开始时间
*/
@ApiModelProperty(value = "退出开始时间格式yyyy-MM-dd", example = "2019-08-01")
private String logoutStartTime;
/**
* 退出结束时间
*/
@ApiModelProperty(value = "退出结束时间格式yyyy-MM-dd", example = "2019-08-01")
private String logoutEndTime;
/**
* 设备类型
*/
@ApiModelProperty("设备类型")
private String deviceClass;
/**
* 设备名称
*/
@ApiModelProperty("设备名称")
private String deviceName;
/**
* 设备品牌
*/
@ApiModelProperty("设备品牌")
private String deviceBrand;
/**
* 操作系统
*/
@ApiModelProperty("操作系统")
private String os;
/**
* 浏览器
*/
@ApiModelProperty("浏览器")
private String browser;
/**
* 省份
*/
@ApiModelProperty("省份")
private String province;
/**
* 地市
*/
@ApiModelProperty("地市")
private String city;
/**
* 区县
*/
@ApiModelProperty("区县")
private String county;
/**
* IP地址
*/
@ApiModelProperty(value = "IP地址", example = "192.168.1.1")
private String ip;
}

View File

@@ -0,0 +1,191 @@
/*
* Copyright (c) 2019.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.params;
import com.mt.wms.core.enums.AppTypeEnum;
import com.mt.wms.core.enums.UserTypeEnum;
import com.mt.wms.core.params.BasePageParam;
import com.mt.wms.core.validator.constraints.Enum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 登录会话
* </p>
*
* @author jiff
* @since 2019-07-20
*/
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Data
@Builder
@ApiModel("查询会话请求对象")
public class QuerySessionParam extends BasePageParam {
private static final long serialVersionUID = 1L;
/**
* 会话ID
*/
@ApiModelProperty("会话ID")
private String sessionId;
/**
* 父会话ID漫游登录时需要保存发起漫游用户的会话ID
*/
@ApiModelProperty("父会话ID漫游登录时需要保存发起漫游用户的会话ID")
private String parentSessionId;
/**
* 统一用户ID
*/
@ApiModelProperty("统一用户ID")
private Long passportUserId;
/**
* 用户ID
*/
@ApiModelProperty("用户ID")
private Long userId;
/**
* 合作伙伴ID合作伙伴用户或者医院用户登录时会存储
*/
@ApiModelProperty("合作伙伴ID合作伙伴用户或者医院用户登录时会存储")
private Long partnerId;
/**
* 医院ID
*/
@ApiModelProperty("医院ID")
private Long hospitalId;
/**
* 组织ID
*/
@ApiModelProperty("组织ID")
private Long orgId;
/**
* 手机号
*/
@ApiModelProperty("手机号")
private String mobile;
/**
* 用户名称
*/
@ApiModelProperty("用户名称")
private String userName;
/**
* 用户类型1、平台用户2、合作伙伴用户3、医院用户4、患者
*/
@ApiModelProperty(value = "用户类型1、平台用户2、合作伙伴用户3、医院用户4、患者", example = "1")
@Enum(message = "非法的用户类型", target = {UserTypeEnum.class})
private Integer userType;
/**
* 应用类型1、pc2、app3、wechat4、miniapp
*/
@ApiModelProperty(value = "应用类型:\n" +
"1、\tpc\n" +
"2、\tapp\n" +
"3、\twechat\n" +
"4、\tminiapp", required = false, example = "1")
@Enum(message = "非法的应用类型", target = {AppTypeEnum.class})
private Integer appType;
/**
* 应用编码:暂未使用
*/
@ApiModelProperty("应用编码:暂未使用")
private Integer appCode;
/**
* 登录类型1、自主登录2、漫游登录
*/
@ApiModelProperty("登录类型1、自主登录2、漫游登录")
private Integer loginType;
/**
* 开始时间
*/
@ApiModelProperty(value = "开始时间格式yyyy-MM-dd", example = "2019-08-01")
private String startTime;
/**
* 结束时间
*/
@ApiModelProperty(value = "结束时间格式yyyy-MM-dd", example = "2019-08-01")
private String endTime;
/**
* 设备类型
*/
@ApiModelProperty("设备类型")
private String deviceClass;
/**
* 设备名称
*/
@ApiModelProperty("设备名称")
private String deviceName;
/**
* 设备品牌
*/
@ApiModelProperty("设备品牌")
private String deviceBrand;
/**
* 操作系统
*/
@ApiModelProperty("操作系统")
private String os;
/**
* 浏览器
*/
@ApiModelProperty("浏览器")
private String browser;
/**
* 省份
*/
@ApiModelProperty("省份")
private String province;
/**
* 地市
*/
@ApiModelProperty("地市")
private String city;
/**
* 区县
*/
@ApiModelProperty("区县")
private String county;
/**
* IP地址
*/
@ApiModelProperty(value = "IP地址", example = "192.168.1.1")
private String ip;
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2019.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.params;
import com.mt.wms.core.base.BaseParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotNull;
/**
* @author jiff
* @date 2019/7/20
* @since 1.0
*/
@EqualsAndHashCode(callSuper = true)
@Data
@Builder
@ApiModel(value = "会话请求对象", description = "用于管理用户会话")
public class SessionParam extends BaseParam {
@ApiModelProperty(value = "会话ID", required = true, example = "1")
@NotNull(message = "会话ID不能为空")
private String sessionId;
}

View File

@@ -0,0 +1,164 @@
/*
* Copyright 2014-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mt.wms.passport.resolver;
import org.springframework.session.web.http.CookieHttpSessionIdResolver;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
import org.springframework.session.web.http.HttpSessionIdResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.List;
/**
* A {@link HttpSessionIdResolver} that uses a header to resolve the session id.
* Specifically, this implementation will allow specifying a header name using
* {@link #CookieHeaderHttpSessionIdResolver(String)}. Convenience factory methods for creating
* instances that use common header names, such as "X-Auth-Token" and
* "Authentication-Info", are available as well.
* <p>
* When a session is created, the HTTP response will have a response header of the
* specified name and the value of the session id. For example:
*
* <pre>
* HTTP/1.1 200 OK
* X-Auth-Token: f81d4fae-7dec-11d0-a765-00a0c91e6bf6
* </pre>
* <p>
* The client should now include the session in each request by specifying the same header
* in their request. For example:
*
* <pre>
* GET /messages/ HTTP/1.1
* Host: example.com
* X-Auth-Token: f81d4fae-7dec-11d0-a765-00a0c91e6bf6
* </pre>
* <p>
* When the session is invalidated, the server will send an HTTP response that has the
* header name and a blank value. For example:
*
* <pre>
* HTTP/1.1 200 OK
* X-Auth-Token:
* </pre>
*
* @author Rob Winch
* @author Vedran Pavic
* @since 1.0
*/
public class CookieHeaderHttpSessionIdResolver implements HttpSessionIdResolver {
private static final String HEADER_TOKEN = "token";
private static final String HEADER_X_AUTH_TOKEN = "X-Auth-Token";
private static final String HEADER_AUTHENTICATION_INFO = "Authentication-Info";
private final String headerName;
private static final String WRITTEN_SESSION_ID_ATTR = CookieHttpSessionIdResolver.class
.getName().concat(".WRITTEN_SESSION_ID_ATTR");
private CookieSerializer cookieSerializer = new DefaultCookieSerializer();
/**
* Convenience factory to create {@link CookieHeaderHttpSessionIdResolver} that uses
* "X-Auth-Token" header.
*
* @return the instance configured to use "X-Auth-Token" header
*/
public static CookieHeaderHttpSessionIdResolver token() {
return new CookieHeaderHttpSessionIdResolver(HEADER_TOKEN);
}
/**
* Convenience factory to create {@link CookieHeaderHttpSessionIdResolver} that uses
* "X-Auth-Token" header.
*
* @return the instance configured to use "X-Auth-Token" header
*/
public static CookieHeaderHttpSessionIdResolver xAuthToken() {
return new CookieHeaderHttpSessionIdResolver(HEADER_X_AUTH_TOKEN);
}
/**
* Convenience factory to create {@link CookieHeaderHttpSessionIdResolver} that uses
* "Authentication-Info" header.
*
* @return the instance configured to use "Authentication-Info" header
*/
public static CookieHeaderHttpSessionIdResolver authenticationInfo() {
return new CookieHeaderHttpSessionIdResolver(HEADER_AUTHENTICATION_INFO);
}
/**
* The name of the header to obtain the session id from.
*
* @param headerName the name of the header to obtain the session id from.
*/
public CookieHeaderHttpSessionIdResolver(String headerName) {
if (headerName == null) {
throw new IllegalArgumentException("headerName cannot be null");
}
this.headerName = headerName;
}
@Override
public List<String> resolveSessionIds(HttpServletRequest request) {
String headerValue = request.getHeader(this.headerName);
return headerValue != null ? Collections.singletonList(headerValue)
: this.cookieSerializer.readCookieValues(request);
}
@Override
public void setSessionId(HttpServletRequest request, HttpServletResponse response,
String sessionId) {
response.setHeader(this.headerName, sessionId);
//cookie
if (sessionId.equals(request.getAttribute(WRITTEN_SESSION_ID_ATTR))) {
return;
}
request.setAttribute(WRITTEN_SESSION_ID_ATTR, sessionId);
this.cookieSerializer
.writeCookieValue(new CookieSerializer.CookieValue(request, response, sessionId));
}
@Override
public void expireSession(HttpServletRequest request, HttpServletResponse response) {
response.setHeader(this.headerName, "");
//cookie
this.cookieSerializer.writeCookieValue(new CookieSerializer.CookieValue(request, response, ""));
}
/**
* Sets the {@link CookieSerializer} to be used.
*
* @param cookieSerializer the cookieSerializer to set. Cannot be null.
*/
public void setCookieSerializer(CookieSerializer cookieSerializer) {
if (cookieSerializer == null) {
throw new IllegalArgumentException("cookieSerializer cannot be null");
}
this.cookieSerializer = cookieSerializer;
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2019.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.service;
import com.mt.wms.core.dto.ApiLogDto;
import com.mt.wms.core.dto.LoginLogDto;
import com.mt.wms.core.vo.R;
/**
* 日志服务
*
* @author jiff
* @date 2019-07-20
* @since 1.0
*/
public interface LogService {
/**
* 保存登录日志
*
* @param loginLogDto
* @return
*/
R<Long> saveLoginLog(LoginLogDto loginLogDto);
/**
* 保存接口日志
*
* @param apiLogDto
* @return
*/
R<Long> saveApiLog(ApiLogDto apiLogDto);
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) 2018.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.service;
import com.mt.wms.core.dto.ApiLogDto;
import com.mt.wms.core.dto.LoginLogDto;
import com.mt.wms.core.dto.Permission;
import java.util.List;
/**
* @author jiff
* @date 2018/11/1
* @since 1.0
*/
public interface PassportService {
List<Permission> getAllPermission();
void saveLoginLog(LoginLogDto loginLogDto);
void saveApiLog(ApiLogDto apiLogDto);
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright (c) 2019.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.service;
import com.mt.wms.core.dto.LoginUser;
import com.mt.wms.core.params.MobileParam;
import com.mt.wms.core.vo.PageVo;
import com.mt.wms.core.vo.R;
import com.mt.wms.passport.params.BatchInvalidateSessionParam;
import com.mt.wms.passport.params.QueryLoginLogParam;
import com.mt.wms.passport.params.QuerySessionParam;
import com.mt.wms.passport.params.SessionParam;
import com.mt.wms.passport.vo.LoginLogVo;
import com.mt.wms.passport.vo.LoginSessionVo;
import java.util.List;
/**
* 会话服务
*
* @author jiff
* @date 2019-07-20
* @since 1.0
*/
public interface SessionService {
/**
* 获取登录会话列表
*
* @param param
* @return
*/
R<PageVo<LoginSessionVo>> list(QuerySessionParam param);
/**
* 获取登录会话日志列表
*
* @param param
* @return
*/
R<PageVo<LoginLogVo>> listLog(QueryLoginLogParam param);
/**
* 注销用户会话
*
* @param param
* @return
*/
R<String> invalidateSession(SessionParam param);
/**
* 批量注销用户会话
*
* @param param
* @return
*/
R<List<String>> batchInvalidateSession(BatchInvalidateSessionParam param);
/**
* 根据手机号码注销用户会话,该手机号码所有会话都注销
*
* @param param
* @return
*/
R<List<String>> invalidateSession(MobileParam param);
/**
* 注销所有平台用户会话
*
* @return
*/
R<List<String>> invalidateAllPlatformSession();
/**
* 获取登录用户
*
* @param param
* @return
*/
R<List<LoginUser>> getLoginSession(MobileParam param);
}

View File

@@ -0,0 +1,129 @@
/*
* Copyright (c) 2020.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mt.wms.core.base.BaseService;
import com.mt.wms.core.dal.entity.LoginLog;
import com.mt.wms.core.dal.entity.LoginSession;
import com.mt.wms.core.dal.entity.SysOrg;
import com.mt.wms.core.dal.service.LoginLogServiceBiz;
import com.mt.wms.core.dal.service.LoginSessionServiceBiz;
import com.mt.wms.core.dal.service.SysOrgServiceBiz;
import com.mt.wms.core.dto.ApiLogDto;
import com.mt.wms.core.dto.LoginLogDto;
import com.mt.wms.core.enums.UserTypeEnum;
import com.mt.wms.core.vo.R;
import com.mt.wms.passport.service.LogService;
import nl.basjes.parse.useragent.UserAgent;
import nl.basjes.parse.useragent.UserAgentAnalyzer;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.time.ZoneId;
/**
* @author jiff
* @date 2019-07-20
* @since 1.0
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class LogServiceImpl extends BaseService implements LogService {
@Autowired
private LoginSessionServiceBiz loginSessionServiceBiz;
@Autowired
private LoginLogServiceBiz loginLogServiceBiz;
@Autowired
private SysOrgServiceBiz sysOrgServiceBiz;
private UserAgentAnalyzer uaa = UserAgentAnalyzer
.newBuilder()
.withoutCache()
.hideMatcherLoadStats()
// .withField(UserAgent.OPERATING_SYSTEM_NAME)
.build();
/**
* 保存登录日志
*
* @param loginLogDto
* @return
*/
@Override
public R<Long> saveLoginLog(LoginLogDto loginLogDto) {
int action = loginLogDto.getAction();
//保存登录会话信息
if (action == LoginLogDto.ACTION_LOGIN) {
LoginSession loginSession = loginSessionServiceBiz.getOne(new QueryWrapper<LoginSession>().eq(LoginSession.SESSION_ID, loginLogDto.getSessionId()).last("LIMIT 1"));
if (loginSession == null) {
loginSession = new LoginSession();
BeanUtils.copyProperties(loginLogDto, loginSession);
loginSession.setLoginTime(LocalDateTime.ofInstant(loginLogDto.getLoginTime().toInstant(), ZoneId.systemDefault()));
if (ObjectUtils.allNotNull(loginLogDto.getOrgId())) {
if (loginLogDto.getUserType() == UserTypeEnum.PLATFORM.getValue()) {
SysOrg org = sysOrgServiceBiz.getById(loginLogDto.getOrgId());
if (org != null) {
loginSession.setOrgName(org.getName());
}
}
}
UserAgent userAgent = uaa.parse(loginLogDto.getUserAgent());
loginSession.setDeviceClass(userAgent.getValue(UserAgent.DEVICE_CLASS))
.setDeviceName(userAgent.getValue(UserAgent.DEVICE_NAME))
.setDeviceBrand(userAgent.getValue(UserAgent.DEVICE_BRAND))
.setOs(userAgent.getValue(UserAgent.OPERATING_SYSTEM_NAME_VERSION))
.setBrowser(userAgent.getValue(UserAgent.AGENT_NAME_VERSION));
loginSession.setCreator(loginLogDto.getUserId())
.setCreatorName(loginLogDto.getUserName())
.setCreateTime(LocalDateTime.now());
loginSessionServiceBiz.save(loginSession);
}
} else {
//删除登录会话,保存登录日志
LoginSession loginSession = loginSessionServiceBiz.getOne(new QueryWrapper<LoginSession>().eq(LoginSession.SESSION_ID, loginLogDto.getSessionId()).last("LIMIT 1"));
if (loginSession != null) {
LoginLog loginLog = new LoginLog();
BeanUtils.copyProperties(loginSession, loginLog);
loginLog.setLogoutType(loginLogDto.getLogoutType())
.setLogoutTime(LocalDateTime.ofInstant(loginLogDto.getLogoutTime().toInstant(), ZoneId.systemDefault()))
.setLogoutIp(loginLogDto.getIp())
.setLogoutUserAgent(loginLogDto.getUserAgent());
if (loginLogDto.getLogoutType() == LoginLogDto.LOGOUT_TYPE_MANAGE) {
loginLog.setUpdater(loginLogDto.getUserId())
.setUpdaterName(loginLogDto.getUserName())
.setUpdateTime(LocalDateTime.now());
} else {
loginLog.setUpdater(loginSession.getUserId())
.setUpdaterName(loginSession.getUserName())
.setUpdateTime(LocalDateTime.now());
}
loginSessionServiceBiz.removeById(loginSession.getId());
loginLogServiceBiz.save(loginLog);
}
}
return successful(null);
}
/**
* 保存接口日志
*
* @param apiLogDto
* @return
*/
@Override
public R<Long> saveApiLog(ApiLogDto apiLogDto) {
return null;
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2018.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.service.impl;
import com.mt.wms.core.dto.ApiLogDto;
import com.mt.wms.core.dto.LoginLogDto;
import com.mt.wms.core.dto.Permission;
import com.mt.wms.passport.service.PassportService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author jiff
* @date 2018/11/1
* @since 1.0
*/
@Service
public class PassportServiceImpl implements PassportService {
@Autowired
private RedisTemplate redisTemplate;
@Override
public List<Permission> getAllPermission() {
return null;
}
@Override
public void saveLoginLog(LoginLogDto loginLogDto) {
}
@Override
public void saveApiLog(ApiLogDto apiLogDto) {
}
}

View File

@@ -0,0 +1,270 @@
/*
* Copyright (c) 2019.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.service.impl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mt.wms.core.base.BaseService;
import com.mt.wms.core.dal.entity.LoginLog;
import com.mt.wms.core.dal.entity.LoginSession;
import com.mt.wms.core.dal.entity.SysUser;
import com.mt.wms.core.dal.service.LoginLogServiceBiz;
import com.mt.wms.core.dal.service.LoginSessionServiceBiz;
import com.mt.wms.core.dal.service.SysUserServiceBiz;
import com.mt.wms.core.dto.LoginLogDto;
import com.mt.wms.core.dto.LoginUser;
import com.mt.wms.core.params.MobileParam;
import com.mt.wms.core.vo.PageVo;
import com.mt.wms.core.vo.R;
import com.mt.wms.passport.params.BatchInvalidateSessionParam;
import com.mt.wms.passport.params.QueryLoginLogParam;
import com.mt.wms.passport.params.QuerySessionParam;
import com.mt.wms.passport.params.SessionParam;
import com.mt.wms.passport.service.PassportService;
import com.mt.wms.passport.service.SessionService;
import com.mt.wms.passport.vo.LoginLogVo;
import com.mt.wms.passport.vo.LoginSessionVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.Session;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @author jiff
* @date 2019-07-20
* @since 1.0
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class SessionServiceImpl extends BaseService implements SessionService {
@Autowired
private LoginSessionServiceBiz loginSessionServiceBiz;
@Autowired
private LoginLogServiceBiz loginLogServiceBiz;
@Autowired
private SysUserServiceBiz sysUserServiceBiz;
@Autowired
private PassportService passportService;
@Autowired
private FindByIndexNameSessionRepository<? extends Session> sessionRepository;
/**
* 获取登录会话列表
*
* @param param
* @return
*/
@Override
public R<PageVo<LoginSessionVo>> list(QuerySessionParam param) {
LoginUser loginUser = getLoginUser();
QueryWrapper<LoginSession> wrapper = new QueryWrapper<>();
wrapper.eq(ObjectUtils.isNotNull(param.getSessionId()), LoginSession.SESSION_ID, param.getSessionId())
.eq(ObjectUtils.isNotNull(param.getMobile()), LoginSession.MOBILE, param.getMobile())
.eq(ObjectUtils.isNotNull(param.getUserType()), LoginSession.USER_TYPE, param.getUserType())
.eq(ObjectUtils.isNotNull(param.getAppType()), LoginSession.APP_TYPE, param.getAppType())
.eq(ObjectUtils.isNotNull(param.getLoginType()), LoginSession.LOGIN_TYPE, param.getLoginType())
.eq(ObjectUtils.isNotNull(param.getIp()), LoginSession.IP, param.getIp())
.eq(StringUtils.isNotBlank(param.getDeviceClass()), LoginSession.DEVICE_CLASS, param.getDeviceClass())
.like(StringUtils.isNotBlank(param.getDeviceBrand()), LoginSession.DEVICE_BRAND, param.getDeviceBrand())
.like(StringUtils.isNotBlank(param.getOs()), LoginSession.OS, param.getOs())
.like(StringUtils.isNotBlank(param.getBrowser()), LoginSession.BROWSER, param.getBrowser())
.like(StringUtils.isNotBlank(param.getUserName()), LoginSession.USER_NAME, param.getUserName());
//LocalDate.parse不允许null不能使用QueryWrapper#ge(boolean condition, R column, Object val)
if (StringUtils.isNotBlank(param.getStartTime())) {
wrapper.ge(LoginSession.LOGIN_TIME, LocalDate.parse(param.getStartTime(), DateTimeFormatter.ISO_LOCAL_DATE).atStartOfDay());
}
if (StringUtils.isNotBlank(param.getEndTime())) {
wrapper.le(LoginSession.LOGIN_TIME, LocalDate.parse(param.getEndTime(), DateTimeFormatter.ISO_LOCAL_DATE).atTime(LocalTime.MAX));
}
//根据登录时间倒序
wrapper.orderByDesc(LoginSession.LOGIN_TIME);
IPage<LoginSession> page = loginSessionServiceBiz.page(new Page<>(param.getCurrent(), param.getSize()), wrapper);
return successful(new PageVo<>(page, LoginSessionVo.class));
}
/**
* 获取登录会话日志列表
*
* @param param
* @return
*/
@Override
public R<PageVo<LoginLogVo>> listLog(QueryLoginLogParam param) {
LoginUser loginUser = getLoginUser();
QueryWrapper<LoginLog> wrapper = new QueryWrapper<>();
wrapper.eq(ObjectUtils.isNotNull(param.getSessionId()), LoginLog.SESSION_ID, param.getSessionId())
.eq(ObjectUtils.isNotNull(param.getMobile()), LoginLog.MOBILE, param.getMobile())
.eq(ObjectUtils.isNotNull(param.getUserType()), LoginLog.USER_TYPE, param.getUserType())
.eq(ObjectUtils.isNotNull(param.getAppType()), LoginLog.APP_TYPE, param.getAppType())
.eq(ObjectUtils.isNotNull(param.getLoginType()), LoginLog.LOGIN_TYPE, param.getLoginType())
.eq(ObjectUtils.isNotNull(param.getLogoutType()), LoginLog.LOGOUT_TYPE, param.getLogoutType())
.eq(ObjectUtils.isNotNull(param.getIp()), LoginLog.IP, param.getIp())
.eq(StringUtils.isNotBlank(param.getDeviceClass()), LoginLog.DEVICE_CLASS, param.getDeviceClass())
.like(StringUtils.isNotBlank(param.getDeviceBrand()), LoginLog.DEVICE_BRAND, param.getDeviceBrand())
.like(StringUtils.isNotBlank(param.getOs()), LoginLog.OS, param.getOs())
.like(StringUtils.isNotBlank(param.getBrowser()), LoginLog.BROWSER, param.getBrowser())
.like(StringUtils.isNotBlank(param.getUserName()), LoginLog.USER_NAME, param.getUserName());
//LocalDate.parse不允许null不能使用QueryWrapper#ge(boolean condition, R column, Object val)
//登录时间
if (StringUtils.isNotBlank(param.getStartTime())) {
wrapper.ge(LoginLog.LOGIN_TIME, LocalDate.parse(param.getStartTime(), DateTimeFormatter.ISO_LOCAL_DATE).atStartOfDay());
}
if (StringUtils.isNotBlank(param.getEndTime())) {
wrapper.le(LoginLog.LOGIN_TIME, LocalDate.parse(param.getEndTime(), DateTimeFormatter.ISO_LOCAL_DATE).atTime(LocalTime.MAX));
}
//退出时间
if (StringUtils.isNotBlank(param.getLogoutStartTime())) {
wrapper.ge(LoginLog.LOGOUT_TIME, LocalDate.parse(param.getLogoutStartTime(), DateTimeFormatter.ISO_LOCAL_DATE).atStartOfDay());
}
if (StringUtils.isNotBlank(param.getLogoutEndTime())) {
wrapper.le(LoginLog.LOGOUT_TIME, LocalDate.parse(param.getLogoutEndTime(), DateTimeFormatter.ISO_LOCAL_DATE).atTime(LocalTime.MAX));
}
//根据退出时间倒序
wrapper.orderByDesc(LoginLog.LOGOUT_TIME);
IPage<LoginLog> page = loginLogServiceBiz.page(new Page<>(param.getCurrent(), param.getSize()), wrapper);
return successful(new PageVo<>(page, LoginLogVo.class));
}
/**
* 注销用户会话
*
* @param param
* @return
*/
@Override
public R<String> invalidateSession(SessionParam param) {
LoginUser loginUser = getLoginUser();
if (loginUser == null) {
return R.unauthorized();
}
//记录退出时间
passportService.saveLoginLog(LoginLogDto.builder()
.sessionId(param.getSessionId())
.action(LoginLogDto.ACTION_LOGOUT)
.logoutType(LoginLogDto.LOGOUT_TYPE_MANAGE)
.logoutTime(new Date())
.userId(loginUser.getUserId())
.userName(loginUser.getUserName())
.build());
sessionRepository.deleteById(param.getSessionId());
return successful(param.getSessionId());
}
/**
* 批量注销用户会话
*
* @param param
* @return
*/
@Override
public R<List<String>> batchInvalidateSession(BatchInvalidateSessionParam param) {
LoginUser loginUser = getLoginUser();
if (loginUser == null) {
return R.unauthorized();
}
for (String sessionId : param.getSessionIds()) {
//记录退出时间
passportService.saveLoginLog(LoginLogDto.builder()
.sessionId(sessionId)
.action(LoginLogDto.ACTION_LOGOUT)
.logoutType(LoginLogDto.LOGOUT_TYPE_MANAGE)
.logoutTime(new Date())
.userId(loginUser.getUserId())
.userName(loginUser.getUserName())
.build());
sessionRepository.deleteById(sessionId);
}
return successful(param.getSessionIds());
}
/**
* 根据手机号码注销用户会话,该手机号码所有会话都注销
*
* @param param
* @return
*/
@Override
public R<List<String>> invalidateSession(MobileParam param) {
LoginUser loginUser = getLoginUser();
if (loginUser == null) {
return R.unauthorized();
}
List<String> sessionIds = new ArrayList<>();
Map<String, ? extends Session> sessions = sessionRepository.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, param.getMobile());
for (Session session : sessions.values()) {
//记录退出时间
passportService.saveLoginLog(LoginLogDto.builder()
.sessionId(session.getId())
.action(LoginLogDto.ACTION_LOGOUT)
.logoutType(LoginLogDto.LOGOUT_TYPE_MANAGE)
.logoutTime(new Date())
.userId(loginUser.getUserId())
.userName(loginUser.getUserName())
.build());
sessionRepository.deleteById(session.getId());
sessionIds.add(session.getId());
}
return successful(sessionIds);
}
/**
* 注销所有平台用户会话
*
* @return
*/
@Override
public R<List<String>> invalidateAllPlatformSession() {
List<String> sessionIds = new ArrayList<>();
List<SysUser> users = sysUserServiceBiz.list();
for (SysUser user : users) {
R<List<String>> r = invalidateSession(MobileParam.builder().mobile(user.getMobile()).build());
if (r.ok()) {
sessionIds.addAll(r.getData());
}
}
return successful(sessionIds);
}
/**
* 获取登录用户
*
* @param param
* @return
*/
@Override
public R<List<LoginUser>> getLoginSession(MobileParam param) {
List<LoginUser> loginUsers = new ArrayList<>();
Map<String, ? extends Session> sessions = sessionRepository.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, param.getMobile());
for (Session session : sessions.values()) {
String loginUserJson = session.getAttribute(LoginUser.HTTP_HEADER_NAME);
if (StringUtils.isNotBlank(loginUserJson)) {
LoginUser loginUser = JSON.parseObject(loginUserJson, LoginUser.class);
loginUser.setSessionId(session.getId());
loginUsers.add(loginUser);
}
}
return successful(loginUsers);
}
}

View File

@@ -0,0 +1,16 @@
/*
* Copyright (c) 2019.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.validator.groups;
/**
* 密码登录验证组
*
* @author jiff
* @date 2019/3/29
* @since 1.0
*/
public interface PasswordLoginGroup {
}

View File

@@ -0,0 +1,16 @@
/*
* Copyright (c) 2019.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.validator.groups;
/**
* 微信登录验证组
*
* @author jiff
* @date 2019/3/29
* @since 1.0
*/
public interface WechatLoginGroup {
}

View File

@@ -0,0 +1,279 @@
/*
* Copyright (c) 2019.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.mt.wms.core.vo.CommonVo;
import com.mt.wms.core.vo.PageVo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
/**
* <p>
* 登录日志表
* </p>
*
* @author jiff
* @since 2019-07-20
*/
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Data
@Builder
@ApiModel("登录日志视图对象")
public class LoginLogVo extends CommonVo implements PageVo.ConvertVo {
private static final long serialVersionUID = 1L;
/**
* 主键,自增
*/
@ApiModelProperty(value = "id")
private Long id;
/**
* 会话ID
*/
@ApiModelProperty("会话ID")
private String sessionId;
/**
* 父会话ID漫游登录时需要保存发起漫游用户的会话ID
*/
@ApiModelProperty("父会话ID漫游登录时需要保存发起漫游用户的会话ID")
private String parentSessionId;
/**
* 父用户名称
*/
@ApiModelProperty("父用户名称")
private String parentUserName;
/**
* 统一用户ID
*/
@ApiModelProperty("统一用户ID")
private Long passportUserId;
/**
* 用户ID
*/
@ApiModelProperty("用户ID")
private Long userId;
/**
* 合作伙伴ID合作伙伴用户或者医院用户登录时会存储
*/
@ApiModelProperty("合作伙伴ID合作伙伴用户或者医院用户登录时会存储")
private Long partnerId;
/**
* 医院ID
*/
@ApiModelProperty("医院ID")
private Long hospitalId;
/**
* 组织ID
*/
@ApiModelProperty("组织ID")
private Long orgId;
/**
* 手机号
*/
@ApiModelProperty("手机号")
private String mobile;
/**
* 用户名称
*/
@ApiModelProperty("用户名称")
private String userName;
/**
* 合作伙伴名称
*/
@ApiModelProperty("合作伙伴名称")
private String partnerName;
/**
* 医院名称
*/
@ApiModelProperty("医院名称")
private String hospitalName;
/**
* 组织名称
*/
@ApiModelProperty("组织名称")
private String orgName;
/**
* 用户类型1、平台用户2、合作伙伴用户3、医院用户4、患者
*/
@ApiModelProperty("用户类型1、平台用户2、合作伙伴用户3、医院用户4、患者")
private Integer userType;
/**
* 应用类型1、pc2、app3、wechat4、miniapp
*/
@ApiModelProperty("应用类型1、pc2、app3、wechat4、miniapp")
private Integer appType;
/**
* 应用编码:暂未使用
*/
@ApiModelProperty("应用编码:暂未使用")
private Integer appCode;
/**
* 登录类型1、自主登录2、漫游登录
*/
@ApiModelProperty(value = "登录类型1、自主登录2、漫游登录", example = "1")
private Integer loginType;
/**
* 退出类型1、自主退出2、管理退出3超时退出
*/
@ApiModelProperty(value = "退出类型1、自主退出2、管理退出3超时退出", example = "1")
private Integer logoutType;
/**
* 登录时间
*/
@ApiModelProperty("登录时间")
private LocalDateTime loginTime;
/**
* 退出时间
*/
@ApiModelProperty("退出时间")
private LocalDateTime logoutTime;
/**
* 设备类型
*/
@ApiModelProperty("设备类型")
private String deviceClass;
/**
* 设备名称
*/
@ApiModelProperty("设备名称")
private String deviceName;
/**
* 设备品牌
*/
@ApiModelProperty("设备品牌")
private String deviceBrand;
/**
* 操作系统
*/
@ApiModelProperty("操作系统")
private String os;
/**
* 浏览器
*/
@ApiModelProperty("浏览器")
private String browser;
/**
* 国家
*/
@ApiModelProperty("国家")
private String country;
/**
* 省份
*/
@ApiModelProperty("省份")
private String province;
/**
* 地市
*/
@ApiModelProperty("地市")
private String city;
/**
* 区县
*/
@ApiModelProperty("区县")
private String county;
/**
* 地址
*/
@ApiModelProperty("地址")
private String address;
/**
* 精度
*/
@ApiModelProperty("精度")
private String lng;
/**
* 纬度
*/
@ApiModelProperty("纬度")
private String lat;
/**
* 网络服务提供商
*/
@ApiModelProperty("网络服务提供商")
private String isp;
/**
* IP地址
*/
@ApiModelProperty("IP地址")
private String ip;
/**
* 用户代理,存放用户登录时客户端信息
*/
@ApiModelProperty("用户代理")
private String userAgent;
/**
* 退出地址
*/
@TableField("退出地址")
private String logoutAddress;
/**
* 退出IP地址
*/
@TableField("退出IP地址")
private String logoutIp;
/**
* 退出用户代理,存放用户退出时客户端信息
*/
@TableField("退出用户代理,存放用户退出时客户端信息")
private String logoutUserAgent;
/**
* 异常状态0、正常1、省份异常2、地市异常3、区县异常
*/
@ApiModelProperty(value = "异常状态0、正常1、省份异常2、地市异常3、区县异常", example = "0")
private Integer abnormalStatus;
}

View File

@@ -0,0 +1,240 @@
/*
* Copyright (c) 2019.
* http://www.ulabcare.com
*/
package com.mt.wms.passport.vo;
import com.mt.wms.core.vo.CommonVo;
import com.mt.wms.core.vo.PageVo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
/**
* <p>
* 登录会话
* </p>
*
* @author jiff
* @since 2019-07-20
*/
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Data
@Builder
@ApiModel("会话视图对象")
public class LoginSessionVo extends CommonVo implements PageVo.ConvertVo {
private static final long serialVersionUID = 1L;
/**
* 主键,自增
*/
@ApiModelProperty(value = "id")
private Long id;
/**
* 会话ID
*/
@ApiModelProperty("会话ID")
private String sessionId;
/**
* 父会话ID漫游登录时需要保存发起漫游用户的会话ID
*/
@ApiModelProperty("父会话ID漫游登录时需要保存发起漫游用户的会话ID")
private String parentSessionId;
/**
* 父用户名称
*/
@ApiModelProperty("父用户名称")
private String parentUserName;
/**
* 统一用户ID
*/
@ApiModelProperty("统一用户ID")
private Long passportUserId;
/**
* 用户ID
*/
@ApiModelProperty("用户ID")
private Long userId;
/**
* 合作伙伴ID合作伙伴用户或者医院用户登录时会存储
*/
@ApiModelProperty("合作伙伴ID合作伙伴用户或者医院用户登录时会存储")
private Long partnerId;
/**
* 医院ID
*/
@ApiModelProperty("医院ID")
private Long hospitalId;
/**
* 组织ID
*/
@ApiModelProperty("组织ID")
private Long orgId;
/**
* 手机号
*/
@ApiModelProperty("手机号")
private String mobile;
/**
* 用户名称
*/
@ApiModelProperty("用户名称")
private String userName;
/**
* 合作伙伴名称
*/
@ApiModelProperty("合作伙伴名称")
private String partnerName;
/**
* 医院名称
*/
@ApiModelProperty("医院名称")
private String hospitalName;
/**
* 组织名称
*/
@ApiModelProperty("组织名称")
private String orgName;
/**
* 用户类型1、平台用户2、合作伙伴用户3、医院用户4、患者
*/
@ApiModelProperty("用户类型1、平台用户2、合作伙伴用户3、医院用户4、患者")
private Integer userType;
/**
* 应用类型1、pc2、app3、wechat4、miniapp
*/
@ApiModelProperty("应用类型1、pc2、app3、wechat4、miniapp")
private Integer appType;
/**
* 应用编码:暂未使用
*/
@ApiModelProperty("应用编码:暂未使用")
private Integer appCode;
/**
* 登录类型1、自主登录2、漫游登录
*/
@ApiModelProperty("登录类型1、自主登录2、漫游登录")
private Integer loginType;
/**
* 登录时间
*/
@ApiModelProperty("登录时间")
private LocalDateTime loginTime;
/**
* 设备类型
*/
@ApiModelProperty("设备类型")
private String deviceClass;
/**
* 设备名称
*/
@ApiModelProperty("设备名称")
private String deviceName;
/**
* 设备品牌
*/
@ApiModelProperty("设备品牌")
private String deviceBrand;
/**
* 操作系统
*/
@ApiModelProperty("操作系统")
private String os;
/**
* 浏览器
*/
@ApiModelProperty("浏览器")
private String browser;
/**
* 国家
*/
@ApiModelProperty("国家")
private String country;
/**
* 省份
*/
@ApiModelProperty("省份")
private String province;
/**
* 地市
*/
@ApiModelProperty("地市")
private String city;
/**
* 区县
*/
@ApiModelProperty("区县")
private String county;
/**
* 地址
*/
@ApiModelProperty("地址")
private String address;
/**
* 精度
*/
@ApiModelProperty("精度")
private String lng;
/**
* 纬度
*/
@ApiModelProperty("纬度")
private String lat;
/**
* 网络服务提供商
*/
@ApiModelProperty("网络服务提供商")
private String isp;
/**
* IP地址
*/
@ApiModelProperty("IP地址")
private String ip;
/**
* 用户代理,存放用户登录时客户端信息
*/
@ApiModelProperty("用户代理")
private String userAgent;
}