mirror of
https://codeup.aliyun.com/64f7d6b8ce01efaafef1e678/coal/coal.git
synced 2026-01-25 15:55:18 +08:00
添加用户登录历史记录表
This commit is contained in:
@@ -7,6 +7,7 @@ import lombok.Getter;
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
@UtilityClass
|
||||
@@ -16,6 +17,9 @@ public class Ctx {
|
||||
private static ConfigurableApplicationContext context;
|
||||
|
||||
public static String getUserId() {
|
||||
if (!isLoggedIn()) {
|
||||
return null;
|
||||
}
|
||||
return getAuthentication().getUser().getId();
|
||||
}
|
||||
|
||||
@@ -25,26 +29,37 @@ public class Ctx {
|
||||
}
|
||||
|
||||
public static String getSessionId() {
|
||||
if (!isLoggedIn()) {
|
||||
return null;
|
||||
}
|
||||
return getAuthentication().getSessionId();
|
||||
}
|
||||
|
||||
private static SessionService.MyAuthentication getAuthentication() {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
if( ! (authentication instanceof SessionService.MyAuthentication))
|
||||
return null;
|
||||
|
||||
|
||||
return (SessionService.MyAuthentication)
|
||||
SecurityContextHolder.getContext().getAuthentication();
|
||||
authentication;
|
||||
}
|
||||
|
||||
public static boolean isOrgAdmin() {
|
||||
|
||||
return getAuthentication().getUser().getOrgAdmin();
|
||||
return isLoggedIn() && getAuthentication().getUser().getOrgAdmin();
|
||||
}
|
||||
|
||||
public static boolean isSysAdmin() {
|
||||
|
||||
return getAuthentication().getUser().getSysAdmin();
|
||||
return isLoggedIn() && getAuthentication().getUser().getSysAdmin();
|
||||
}
|
||||
|
||||
public static UserDto currentUser() {
|
||||
return getAuthentication().getUser();
|
||||
if (!isLoggedIn()) {
|
||||
return null;
|
||||
}
|
||||
return getAuthentication().getUser();
|
||||
}
|
||||
|
||||
public static void setContext(ConfigurableApplicationContext context) {
|
||||
|
||||
@@ -52,7 +52,7 @@ public class LoginUserController {
|
||||
|
||||
@PostMapping("/logout")
|
||||
public Boolean logout(@RequestBody IdRequest request) {
|
||||
this.service.logout(request);
|
||||
this.service.adminLogout(request);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import cn.lihongjie.coal.loginUser.dto.UpdateLoginUserDto;
|
||||
import cn.lihongjie.coal.loginUser.entity.LoginUserEntity;
|
||||
import cn.lihongjie.coal.loginUser.mapper.LoginUserMapper;
|
||||
import cn.lihongjie.coal.loginUser.repository.LoginUserRepository;
|
||||
import cn.lihongjie.coal.loginUserHis.service.LoginUserHisService;
|
||||
import cn.lihongjie.coal.session.SessionService;
|
||||
import cn.lihongjie.coal.sysconfig.service.SysConfigService;
|
||||
import cn.lihongjie.coal.user.service.UserService;
|
||||
@@ -144,6 +145,8 @@ class LoginUserService extends BaseService<LoginUserEntity, LoginUserRepository>
|
||||
this.save(entity);
|
||||
}
|
||||
|
||||
@Autowired LoginUserHisService loginUserHisService;
|
||||
|
||||
public void deleteExpireSession() {
|
||||
|
||||
List<LoginUserEntity> list = this.repository.findAllByExpireTimeBefore(LocalDateTime.now());
|
||||
@@ -151,6 +154,7 @@ class LoginUserService extends BaseService<LoginUserEntity, LoginUserRepository>
|
||||
log.info("删除过期会话 {} 个", list.size());
|
||||
for (LoginUserEntity user : list) {
|
||||
this.deleteLogin(user.getId());
|
||||
loginUserHisService.logExpired(user.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -232,4 +236,11 @@ class LoginUserService extends BaseService<LoginUserEntity, LoginUserRepository>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void adminLogout(IdRequest request) {
|
||||
logout(request);
|
||||
|
||||
loginUserHisService.logAdminLogout(request.getIds());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package cn.lihongjie.coal.loginUserHis.controller;
|
||||
|
||||
import cn.lihongjie.coal.annotation.SysLog;
|
||||
import cn.lihongjie.coal.base.dto.CommonQuery;
|
||||
import cn.lihongjie.coal.base.dto.IdRequest;
|
||||
import cn.lihongjie.coal.loginUserHis.dto.CreateLoginUserHisDto;
|
||||
import cn.lihongjie.coal.loginUserHis.dto.LoginUserHisDto;
|
||||
import cn.lihongjie.coal.loginUserHis.dto.UpdateLoginUserHisDto;
|
||||
import cn.lihongjie.coal.loginUserHis.service.LoginUserHisService;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
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;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/loginUserHis")
|
||||
@SysLog(
|
||||
module = "用户登录历史"
|
||||
)
|
||||
@Slf4j
|
||||
public class LoginUserHisController {
|
||||
@Autowired
|
||||
private LoginUserHisService service;
|
||||
|
||||
@PostMapping("/create")
|
||||
public LoginUserHisDto create(@RequestBody CreateLoginUserHisDto request) {
|
||||
return this.service.create(request)
|
||||
;
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public LoginUserHisDto update(@RequestBody UpdateLoginUserHisDto request) {
|
||||
return this.service.update(request)
|
||||
;
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@RequestBody IdRequest request) {
|
||||
this.service.delete(request);
|
||||
return true
|
||||
;
|
||||
}
|
||||
|
||||
@PostMapping("/getById")
|
||||
public LoginUserHisDto getById(@RequestBody IdRequest request) {
|
||||
return this.service.getById(request.getId())
|
||||
;
|
||||
}
|
||||
|
||||
@PostMapping("/list")
|
||||
public Page<LoginUserHisDto> list(@RequestBody CommonQuery request) {
|
||||
return this.service.list(request)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package cn.lihongjie.coal.loginUserHis.dto;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.CommonDto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import org.hibernate.annotations.Comment;
|
||||
import org.hibernate.annotations.Formula;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
public class CreateLoginUserHisDto extends CommonDto {
|
||||
private String user;
|
||||
|
||||
private String userName;
|
||||
private String ip;
|
||||
private String location;
|
||||
private String ua;
|
||||
private String captcha;
|
||||
|
||||
@Comment("登录状态")
|
||||
private String status;
|
||||
|
||||
|
||||
@Formula(
|
||||
"(select i.name\n"
|
||||
+ "from t_dictionary d,\n"
|
||||
+ " t_dictionary_item i\n"
|
||||
+ "where d.id = i.dictionary_id\n"
|
||||
+ " and d.code = 'loginUserHis.status'\n"
|
||||
+ " and i.code = status)")
|
||||
private String statusName;
|
||||
|
||||
@Comment("session id")
|
||||
private String sessionId;
|
||||
|
||||
@Comment("登录时间")
|
||||
private LocalDateTime loginTime;
|
||||
|
||||
@Comment("登出时间")
|
||||
private LocalDateTime logoutTime;
|
||||
|
||||
@Comment("登出类型")
|
||||
private String logoutType;
|
||||
|
||||
|
||||
@Formula(
|
||||
"(select i.name\n"
|
||||
+ "from t_dictionary d,\n"
|
||||
+ " t_dictionary_item i\n"
|
||||
+ "where d.id = i.dictionary_id\n"
|
||||
+ " and d.code = 'loginUserHis.logoutType'\n"
|
||||
+ " and i.code = logout_type)")
|
||||
private String logoutTypeName;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package cn.lihongjie.coal.loginUserHis.dto;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.CommonDto;
|
||||
import cn.lihongjie.coal.user.dto.UserDto;
|
||||
|
||||
import jakarta.persistence.ManyToOne;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import org.hibernate.annotations.Comment;
|
||||
import org.hibernate.annotations.Formula;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
public class LoginUserHisDto extends CommonDto {
|
||||
@ManyToOne
|
||||
private UserDto user;
|
||||
|
||||
private String userName;
|
||||
private String ip;
|
||||
private String location;
|
||||
private String ua;
|
||||
private String captcha;
|
||||
|
||||
@Comment("登录状态")
|
||||
private String status;
|
||||
|
||||
|
||||
@Formula(
|
||||
"(select i.name\n"
|
||||
+ "from t_dictionary d,\n"
|
||||
+ " t_dictionary_item i\n"
|
||||
+ "where d.id = i.dictionary_id\n"
|
||||
+ " and d.code = 'loginUserHis.status'\n"
|
||||
+ " and i.code = status)")
|
||||
private String statusName;
|
||||
|
||||
@Comment("session id")
|
||||
private String sessionId;
|
||||
|
||||
@Comment("登录时间")
|
||||
private LocalDateTime loginTime;
|
||||
|
||||
@Comment("登出时间")
|
||||
private LocalDateTime logoutTime;
|
||||
|
||||
@Comment("登出类型")
|
||||
private String logoutType;
|
||||
|
||||
|
||||
@Formula(
|
||||
"(select i.name\n"
|
||||
+ "from t_dictionary d,\n"
|
||||
+ " t_dictionary_item i\n"
|
||||
+ "where d.id = i.dictionary_id\n"
|
||||
+ " and d.code = 'loginUserHis.logoutType'\n"
|
||||
+ " and i.code = logout_type)")
|
||||
private String logoutTypeName;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package cn.lihongjie.coal.loginUserHis.dto;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.CommonDto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import org.hibernate.annotations.Comment;
|
||||
import org.hibernate.annotations.Formula;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
public class UpdateLoginUserHisDto extends CommonDto {
|
||||
private String user;
|
||||
|
||||
private String userName;
|
||||
private String ip;
|
||||
private String location;
|
||||
private String ua;
|
||||
private String captcha;
|
||||
@Comment("登录状态")
|
||||
private String status;
|
||||
|
||||
|
||||
@Formula(
|
||||
"(select i.name\n"
|
||||
+ "from t_dictionary d,\n"
|
||||
+ " t_dictionary_item i\n"
|
||||
+ "where d.id = i.dictionary_id\n"
|
||||
+ " and d.code = 'loginUserHis.status'\n"
|
||||
+ " and i.code = status)")
|
||||
private String statusName;
|
||||
|
||||
@Comment("session id")
|
||||
private String sessionId;
|
||||
|
||||
@Comment("登录时间")
|
||||
private LocalDateTime loginTime;
|
||||
|
||||
@Comment("登出时间")
|
||||
private LocalDateTime logoutTime;
|
||||
|
||||
@Comment("登出类型")
|
||||
private String logoutType;
|
||||
|
||||
|
||||
@Formula(
|
||||
"(select i.name\n"
|
||||
+ "from t_dictionary d,\n"
|
||||
+ " t_dictionary_item i\n"
|
||||
+ "where d.id = i.dictionary_id\n"
|
||||
+ " and d.code = 'loginUserHis.logoutType'\n"
|
||||
+ " and i.code = logout_type)")
|
||||
private String logoutTypeName;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package cn.lihongjie.coal.loginUserHis.entity;
|
||||
|
||||
import cn.lihongjie.coal.base.entity.CommonEntity;
|
||||
import cn.lihongjie.coal.user.entity.UserEntity;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import org.hibernate.annotations.Comment;
|
||||
import org.hibernate.annotations.Formula;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@Entity
|
||||
public class LoginUserHisEntity extends CommonEntity {
|
||||
|
||||
|
||||
|
||||
@ManyToOne
|
||||
private UserEntity user;
|
||||
|
||||
|
||||
|
||||
private String userName;
|
||||
private String ip;
|
||||
private String location;
|
||||
private String ua;
|
||||
private String captcha;
|
||||
|
||||
@Comment("登录状态")
|
||||
private String loginStatus;
|
||||
|
||||
|
||||
@Formula(
|
||||
"(select i.name\n"
|
||||
+ "from t_dictionary d,\n"
|
||||
+ " t_dictionary_item i\n"
|
||||
+ "where d.id = i.dictionary_id\n"
|
||||
+ " and d.code = 'loginUserHis.loginStatus'\n"
|
||||
+ " and i.code = login_status)")
|
||||
private String loginStatusName;
|
||||
|
||||
@Comment("session id")
|
||||
private String sessionId;
|
||||
|
||||
@Comment("登录时间")
|
||||
private LocalDateTime loginTime;
|
||||
|
||||
@Comment("登出时间")
|
||||
private LocalDateTime logoutTime;
|
||||
|
||||
@Comment("登出类型")
|
||||
private String logoutType;
|
||||
|
||||
|
||||
@Formula(
|
||||
"(select i.name\n"
|
||||
+ "from t_dictionary d,\n"
|
||||
+ " t_dictionary_item i\n"
|
||||
+ "where d.id = i.dictionary_id\n"
|
||||
+ " and d.code = 'loginUserHis.logoutType'\n"
|
||||
+ " and i.code = logout_type)")
|
||||
private String logoutTypeName;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package cn.lihongjie.coal.loginUserHis.mapper;
|
||||
|
||||
import cn.lihongjie.coal.base.mapper.BaseMapper;
|
||||
import cn.lihongjie.coal.base.mapper.CommonMapper;
|
||||
import cn.lihongjie.coal.loginUserHis.dto.CreateLoginUserHisDto;
|
||||
import cn.lihongjie.coal.loginUserHis.dto.LoginUserHisDto;
|
||||
import cn.lihongjie.coal.loginUserHis.dto.UpdateLoginUserHisDto;
|
||||
import cn.lihongjie.coal.loginUserHis.entity.LoginUserHisEntity;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.control.DeepClone;
|
||||
|
||||
@Mapper(
|
||||
componentModel = org.mapstruct.MappingConstants.ComponentModel.SPRING,
|
||||
uses = {CommonMapper.class},
|
||||
mappingControl = DeepClone.class
|
||||
)
|
||||
public interface LoginUserHisMapper extends BaseMapper<LoginUserHisEntity, LoginUserHisDto, CreateLoginUserHisDto, UpdateLoginUserHisDto> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package cn.lihongjie.coal.loginUserHis.repository;
|
||||
|
||||
import cn.lihongjie.coal.base.dao.BaseRepository;
|
||||
import cn.lihongjie.coal.loginUserHis.entity.LoginUserHisEntity;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface LoginUserHisRepository extends BaseRepository<LoginUserHisEntity> {
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
package cn.lihongjie.coal.loginUserHis.service;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.CommonQuery;
|
||||
import cn.lihongjie.coal.base.dto.IdRequest;
|
||||
import cn.lihongjie.coal.base.service.BaseService;
|
||||
import cn.lihongjie.coal.loginUserHis.dto.CreateLoginUserHisDto;
|
||||
import cn.lihongjie.coal.loginUserHis.dto.LoginUserHisDto;
|
||||
import cn.lihongjie.coal.loginUserHis.dto.UpdateLoginUserHisDto;
|
||||
import cn.lihongjie.coal.loginUserHis.entity.LoginUserHisEntity;
|
||||
import cn.lihongjie.coal.loginUserHis.mapper.LoginUserHisMapper;
|
||||
import cn.lihongjie.coal.loginUserHis.repository.LoginUserHisRepository;
|
||||
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@Transactional
|
||||
public class LoginUserHisService extends BaseService<LoginUserHisEntity, LoginUserHisRepository> {
|
||||
@Autowired
|
||||
private LoginUserHisRepository repository;
|
||||
|
||||
@Autowired
|
||||
private LoginUserHisMapper mapper;
|
||||
|
||||
@Autowired
|
||||
private ConversionService conversionService;
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
@Override
|
||||
public LoginUserHisEntity save(LoginUserHisEntity entity) {
|
||||
return super.save(entity);
|
||||
}
|
||||
|
||||
public LoginUserHisDto create(CreateLoginUserHisDto request) {
|
||||
LoginUserHisEntity entity = mapper.toEntity(request);
|
||||
|
||||
|
||||
this.repository.save(entity);
|
||||
return getById(entity.getId())
|
||||
;
|
||||
}
|
||||
|
||||
public LoginUserHisDto update(UpdateLoginUserHisDto request) {
|
||||
LoginUserHisEntity entity = this.repository.get(request.getId());
|
||||
this.mapper.updateEntity(entity, request);
|
||||
|
||||
this.repository.save(entity);
|
||||
|
||||
return getById(entity.getId())
|
||||
;
|
||||
}
|
||||
|
||||
public void delete(IdRequest request) {
|
||||
this.repository.deleteAllById(request.getIds())
|
||||
;
|
||||
}
|
||||
|
||||
public LoginUserHisDto getById(String id) {
|
||||
LoginUserHisEntity entity = repository.get(id);
|
||||
|
||||
|
||||
return mapper.toDto(entity)
|
||||
;
|
||||
}
|
||||
|
||||
public Page<LoginUserHisDto> list(CommonQuery query) {
|
||||
Page<LoginUserHisEntity> page = repository.findAll(query.specification(conversionService), PageRequest.of(query.getPageNo(), query.getPageSize(), Sort.by(query.getOrders())));
|
||||
|
||||
|
||||
return page.map(this.mapper::toDto)
|
||||
;
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void logExpired(final String sessionId) {
|
||||
logoutWithType(List.of(sessionId), "1");
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void logUserLogout(String sessionId) {
|
||||
logoutWithType(List.of(sessionId), "0");
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void logAdminLogout(List<String> ids) {
|
||||
|
||||
logoutWithType(ids, "2");
|
||||
|
||||
}
|
||||
|
||||
private void logoutWithType(List<String> ids, String logoutType) {
|
||||
List<LoginUserHisEntity> his = findAll(new Specification<LoginUserHisEntity>() {
|
||||
@Override
|
||||
public Predicate toPredicate(Root<LoginUserHisEntity> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
|
||||
|
||||
return root.get("sessionId").in(ids);
|
||||
}
|
||||
});
|
||||
|
||||
for (LoginUserHisEntity hi : his) {
|
||||
hi.setLogoutType(logoutType);
|
||||
hi.setLogoutTime(LocalDateTime.now());
|
||||
save(hi);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import cn.lihongjie.coal.user.dto.UserDto;
|
||||
import cn.lihongjie.coal.user.service.UserService;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@@ -42,10 +41,8 @@ public class LoginController extends BaseController {
|
||||
public Object logout() {
|
||||
if (Ctx.isLoggedIn()) {
|
||||
|
||||
this.service.logout(
|
||||
((SessionService.MyAuthentication)
|
||||
SecurityContextHolder.getContext().getAuthentication())
|
||||
.getSessionId());
|
||||
this.service.userLogout(
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import cn.lihongjie.coal.ip.IpQueryService;
|
||||
import cn.lihongjie.coal.loginUser.dto.LoginUserDto;
|
||||
import cn.lihongjie.coal.loginUser.entity.LoginUserEntity;
|
||||
import cn.lihongjie.coal.loginUser.service.LoginUserService;
|
||||
import cn.lihongjie.coal.loginUserHis.entity.LoginUserHisEntity;
|
||||
import cn.lihongjie.coal.loginUserHis.service.LoginUserHisService;
|
||||
import cn.lihongjie.coal.organization.entity.OrganizationEntity;
|
||||
import cn.lihongjie.coal.organization.service.OrganizationService;
|
||||
import cn.lihongjie.coal.sysconfig.service.SysConfigService;
|
||||
@@ -37,6 +39,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -44,8 +47,7 @@ import java.util.concurrent.TimeUnit;
|
||||
@Service
|
||||
@Slf4j
|
||||
@Transactional
|
||||
public
|
||||
class SessionService {
|
||||
public class SessionService {
|
||||
|
||||
@Autowired UserService userService;
|
||||
|
||||
@@ -87,72 +89,104 @@ class SessionService {
|
||||
|
||||
@Autowired IpQueryService ipQueryService;
|
||||
|
||||
@Autowired LoginUserHisService loginUserHisService;
|
||||
|
||||
@SneakyThrows
|
||||
public void login(LoginDto dto) {
|
||||
HttpServletRequest request =
|
||||
((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
|
||||
.getRequest();
|
||||
UserEntity user = null;
|
||||
|
||||
if (sysConfigService.isEnable(Constants.SYSCONFIG_ENABLE_CAPTCHA)) {
|
||||
|
||||
String captchaId = dto.getCaptchaId();
|
||||
if (captchaId == null){
|
||||
throw new BizException("验证码错误, 请刷新验证码重试");
|
||||
}
|
||||
|
||||
String expectCaptcha = stringRedisTemplate.opsForValue().get(captchaId);
|
||||
|
||||
if (expectCaptcha == null) {
|
||||
throw new BizException("验证码已失效");
|
||||
}
|
||||
|
||||
if (!StringUtils.equals(expectCaptcha, dto.getCaptcha())) {
|
||||
stringRedisTemplate.opsForValue().getAndDelete(captchaId);
|
||||
throw new BizException("验证码错误, 请刷新验证码重试");
|
||||
}
|
||||
}
|
||||
|
||||
UserEntity user =
|
||||
userService
|
||||
.findByUsername(dto.getUsername())
|
||||
.orElseThrow(() -> new BizException("用户名或者密码错误"));
|
||||
|
||||
if (user.isDisabled()) {
|
||||
throw new BizException("用户被禁用");
|
||||
}
|
||||
|
||||
OrganizationEntity organization = organizationService.get(user.getOrganizationId());
|
||||
if (organization.isDisabled()) {
|
||||
throw new BizException("用户所在机构被禁用");
|
||||
}
|
||||
|
||||
if (!userService.isValidPassword(dto.getPassword(), user.getPassword())) {
|
||||
throw new BizException("用户名或者密码错误");
|
||||
}
|
||||
|
||||
LoginUserEntity entity = new LoginUserEntity();
|
||||
entity.setUser(user);
|
||||
entity.setCaptcha(dto.getCaptcha());
|
||||
entity.setIp(RequestUtils.getIp(request));
|
||||
entity.setUa(RequestUtils.getUa(request));
|
||||
try {
|
||||
|
||||
entity.setLocation(ipQueryService.query(entity.getIp()));
|
||||
if (sysConfigService.isEnable(Constants.SYSCONFIG_ENABLE_CAPTCHA)) {
|
||||
|
||||
String captchaId = dto.getCaptchaId();
|
||||
if (captchaId == null) {
|
||||
throw new BizException("验证码错误, 请刷新验证码重试");
|
||||
}
|
||||
|
||||
String expectCaptcha = stringRedisTemplate.opsForValue().get(captchaId);
|
||||
|
||||
if (expectCaptcha == null) {
|
||||
throw new BizException("验证码已失效");
|
||||
}
|
||||
|
||||
if (!StringUtils.equals(expectCaptcha, dto.getCaptcha())) {
|
||||
stringRedisTemplate.opsForValue().getAndDelete(captchaId);
|
||||
throw new BizException("验证码错误, 请刷新验证码重试");
|
||||
}
|
||||
}
|
||||
|
||||
user =
|
||||
userService
|
||||
.findByUsername(dto.getUsername())
|
||||
.orElseThrow(() -> new BizException("用户名或者密码错误"));
|
||||
|
||||
if (user.isDisabled()) {
|
||||
throw new BizException("用户被禁用");
|
||||
}
|
||||
|
||||
OrganizationEntity organization = organizationService.get(user.getOrganizationId());
|
||||
if (organization.isDisabled()) {
|
||||
throw new BizException("用户所在机构被禁用");
|
||||
}
|
||||
|
||||
if (!userService.isValidPassword(dto.getPassword(), user.getPassword())) {
|
||||
throw new BizException("用户名或者密码错误");
|
||||
}
|
||||
|
||||
LoginUserEntity entity = new LoginUserEntity();
|
||||
entity.setUser(user);
|
||||
entity.setCaptcha(dto.getCaptcha());
|
||||
entity.setIp(RequestUtils.getIp(request));
|
||||
entity.setUa(RequestUtils.getUa(request));
|
||||
try {
|
||||
|
||||
entity.setLocation(ipQueryService.query(entity.getIp()));
|
||||
} catch (Exception e) {
|
||||
log.warn("查询ip地址失败 {}", entity.getIp(), e);
|
||||
}
|
||||
loginUserService.newLogin(entity);
|
||||
|
||||
LoginUserDto loginUserDto = loginUserService.getFromCache(entity);
|
||||
|
||||
String sessionId = entity.getId();
|
||||
|
||||
SecurityContext context = SecurityContextHolder.createEmptyContext();
|
||||
|
||||
context.setAuthentication(
|
||||
new MyAuthentication(loginUserDto, loginUserDto.getUser(), sessionId));
|
||||
|
||||
SecurityContextHolder.setContext(context);
|
||||
LoginUserHisEntity his = new LoginUserHisEntity();
|
||||
his.setIp(RequestUtils.getIp(request));
|
||||
his.setUa(RequestUtils.getUa(request));
|
||||
his.setCaptcha(dto.getCaptcha());
|
||||
his.setUserName(dto.getUsername());
|
||||
his.setLoginStatus("1");
|
||||
his.setLocation(ipQueryService.query(his.getIp()));
|
||||
his.setLoginTime(LocalDateTime.now());
|
||||
his.setUser(user);
|
||||
his.setSessionId(sessionId);
|
||||
loginUserHisService.save(his);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.warn("查询ip地址失败 {}", entity.getIp(), e);
|
||||
|
||||
LoginUserHisEntity his = new LoginUserHisEntity();
|
||||
his.setIp(RequestUtils.getIp(request));
|
||||
his.setUa(RequestUtils.getUa(request));
|
||||
his.setCaptcha(dto.getCaptcha());
|
||||
his.setUserName(dto.getUsername());
|
||||
his.setLoginStatus("1");
|
||||
his.setLocation(ipQueryService.query(his.getIp()));
|
||||
his.setLoginTime(LocalDateTime.now());
|
||||
his.setUser(user);
|
||||
his.setRemarks(e.getMessage());
|
||||
loginUserHisService.save(his);
|
||||
throw e;
|
||||
}
|
||||
loginUserService.newLogin(entity);
|
||||
|
||||
LoginUserDto loginUserDto = loginUserService.getFromCache(entity);
|
||||
|
||||
String sessionId = entity.getId();
|
||||
|
||||
SecurityContext context = SecurityContextHolder.createEmptyContext();
|
||||
|
||||
context.setAuthentication(
|
||||
new MyAuthentication(loginUserDto, loginUserDto.getUser(), sessionId));
|
||||
|
||||
SecurityContextHolder.setContext(context);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@@ -210,6 +244,24 @@ class SessionService {
|
||||
loginUserService.logout(new IdRequest(sessionId));
|
||||
}
|
||||
|
||||
public void userLogout() {
|
||||
|
||||
|
||||
loginUserService.logout(
|
||||
new IdRequest(
|
||||
((SessionService.MyAuthentication)
|
||||
SecurityContextHolder.getContext().getAuthentication())
|
||||
.getSessionId()));
|
||||
|
||||
loginUserHisService.logUserLogout(
|
||||
((SessionService.MyAuthentication)
|
||||
SecurityContextHolder.getContext().getAuthentication())
|
||||
.getSessionId());
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void anonymousSession() {
|
||||
|
||||
SecurityContext context = SecurityContextHolder.createEmptyContext();
|
||||
|
||||
@@ -55,8 +55,7 @@ import java.util.stream.Collectors;
|
||||
@Service
|
||||
@Slf4j
|
||||
@Transactional
|
||||
public
|
||||
class UserService extends BaseService<UserEntity, UserRepository> {
|
||||
public class UserService extends BaseService<UserEntity, UserRepository> {
|
||||
|
||||
@Autowired UserRepository repository;
|
||||
|
||||
@@ -178,15 +177,11 @@ class UserService extends BaseService<UserEntity, UserRepository> {
|
||||
|
||||
public void resetPwd(String userId, String password) {
|
||||
|
||||
UserEntity user =
|
||||
repository.findById(userId).orElseThrow(() -> new BizException("用户不存在"));
|
||||
|
||||
|
||||
UserEntity user = repository.findById(userId).orElseThrow(() -> new BizException("用户不存在"));
|
||||
|
||||
user.setPassword(passwordEncoder.encode(password));
|
||||
|
||||
repository.save(user);
|
||||
|
||||
}
|
||||
|
||||
public Page<UserDto> list(CommonQuery query) {
|
||||
@@ -308,6 +303,7 @@ class UserService extends BaseService<UserEntity, UserRepository> {
|
||||
}
|
||||
|
||||
public void clearUserCache(String id) {
|
||||
if (StringUtils.isEmpty(id)) return;
|
||||
try {
|
||||
|
||||
cacheManager.getCache(Constants.CACHE_USER_RESOURCES).evict(id);
|
||||
|
||||
@@ -1703,6 +1703,42 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"code": "loginUserHis.loginStatus",
|
||||
"name": "登录状态",
|
||||
"item": [
|
||||
{
|
||||
"code": "0",
|
||||
"name": "成功"
|
||||
},
|
||||
{
|
||||
"code": "1",
|
||||
"name": "失败"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"code": "loginUserHis.logoutType",
|
||||
"name": "登出类型",
|
||||
"item": [
|
||||
{
|
||||
"code": "0",
|
||||
"name": "主动退出"
|
||||
},
|
||||
{
|
||||
"code": "1",
|
||||
"name": "会话过期"
|
||||
},
|
||||
|
||||
{
|
||||
"code": "2",
|
||||
"name": "管理员踢出"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
|
||||
{
|
||||
"code": "permission.type",
|
||||
"name": "权限类型",
|
||||
|
||||
Reference in New Issue
Block a user