Merge remote-tracking branch 'origin/group2-loginlog'

# Conflicts:
#	kernel-s-system/system-business-notice/pom.xml
pull/3/head
fengshuonan 2021-01-13 20:03:50 +08:00
commit 3a2d344734
17 changed files with 666 additions and 11 deletions

View File

@ -17,6 +17,7 @@ import cn.stylefeng.roses.kernel.jwt.api.exception.JwtException;
import cn.stylefeng.roses.kernel.jwt.api.exception.enums.JwtExceptionEnum;
import cn.stylefeng.roses.kernel.jwt.api.pojo.payload.DefaultJwtPayload;
import cn.stylefeng.roses.kernel.rule.util.HttpServletUtil;
import cn.stylefeng.roses.kernel.system.LoginLogServiceApi;
import cn.stylefeng.roses.kernel.system.UserServiceApi;
import cn.stylefeng.roses.kernel.system.enums.UserStatusEnum;
import cn.stylefeng.roses.kernel.system.pojo.user.UserLoginInfoDTO;
@ -54,6 +55,9 @@ public class AuthServiceImpl implements AuthServiceApi {
@Resource
private PasswordTransferEncryptApi passwordTransferEncryptApi;
@Resource
private LoginLogServiceApi loginLogServiceApi;
@Override
public LoginResponse login(LoginRequest loginRequest) {
return loginAction(loginRequest, true);
@ -69,8 +73,13 @@ public class AuthServiceImpl implements AuthServiceApi {
@Override
public void logout() {
String token = LoginContext.me().getToken();
//退出日志
if (StrUtil.isNotEmpty(token)) {
loginLogServiceApi.loginOutSuccess(LoginContext.me().getLoginUser().getUserId());
}
logoutWithToken(token);
sessionManagerApi.destroySessionCookie();
}
@Override
@ -198,7 +207,9 @@ public class AuthServiceImpl implements AuthServiceApi {
String ip = HttpServletUtil.getRequestClientIp(HttpServletUtil.getRequest());
userServiceApi.updateUserLoginInfo(loginUser.getUserId(), new Date(), ip);
// 11. 组装返回结果
// 11.登录成功日志
loginLogServiceApi.loginSuccess(loginUser.getUserId());
// 12. 组装返回结果
return new LoginResponse(loginUser, jwtToken, defaultJwtPayload.getExpirationDate());
}

View File

@ -24,6 +24,7 @@
<module>system-business-role</module>
<module>system-business-menu</module>
<module>system-business-notice</module>
<module>system-business-login-log</module>
<module>system-spring-boot-starter</module>
</modules>

View File

@ -0,0 +1,66 @@
package cn.stylefeng.roses.kernel.system;
import cn.stylefeng.roses.kernel.system.pojo.loginlog.request.SysLoginLogRequest;
/**
* api
*
* @author chenjinlong
* @date 2021/1/13 11:12
*/
public interface LoginLogServiceApi {
/**
*
*
* @param sysLoginLogRequest
* @author chenjinlong
* @date 2021/1/13 10:56
*/
void add(SysLoginLogRequest sysLoginLogRequest);
/**
*
*
* @param userId id
* @author chenjinlong
* @date 2021/1/13 11:36
*/
void loginSuccess(Long userId);
/**
*
*
* @param userId id
* @param llgMessage
* @author chenjinlong
* @date 2021/1/13 11:36
*/
void loginFail(Long userId, String llgMessage);
/**
*
*
* @param userId id
* @author chenjinlong
* @date 2021/1/13 11:36
*/
void loginOutSuccess(Long userId);
/**
*
*
* @param userId id
* @author chenjinlong
* @date 2021/1/13 11:36
*/
void loginOutFail(Long userId);
/**
*
*
* @author chenjinlong
* @date 2021/1/13 10:55
*/
void deleteAll();
}

View File

@ -0,0 +1,65 @@
package cn.stylefeng.roses.kernel.system.pojo.loginlog.request;
import cn.stylefeng.roses.kernel.rule.pojo.request.BaseRequest;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotNull;
import java.util.Date;
/**
*
*
* @author chenjinlong
* @date 2021/1/13 11:06
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class SysLoginLogRequest extends BaseRequest {
/**
* id
*/
@NotNull(message = "llgId不能为空", groups = {detail.class})
private Long llgId;
/**
*
*/
private String llgName;
/**
*
*/
private String llgSucceed;
/**
*
*/
private String llgMessage;
/**
* ip
*/
private String llgIpAddress;
/**
* id
*/
private Long userId;
/**
*
*/
private Date createTime;
/**
*
*/
private String beginTime;
/**
*
*/
private String endTime;
}

View File

@ -0,0 +1,46 @@
package cn.stylefeng.roses.kernel.system.pojo.loginlog.response;
import lombok.Data;
import java.io.Serializable;
/**
*
*
* @author chenjinlong
* @date 2021/1/13 11:06
*/
@Data
public class SysLoginLogResponse implements Serializable {
/**
* id
*/
private Long llgId;
/**
*
*/
private String llgName;
/**
*
*/
private String llgSucceed;
/**
*
*/
private String llgMessage;
/**
* ip
*/
private String llgIpAddress;
/**
* id
*/
private Long userId;
}

View File

@ -0,0 +1 @@
登录日志相关业务

View File

@ -0,0 +1,59 @@
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>kernel-s-system</artifactId>
<version>1.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>system-business-login-log</artifactId>
<packaging>jar</packaging>
<dependencies>
<!--系统管理的api-->
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>system-api</artifactId>
<version>1.0.0</version>
</dependency>
<!--资源api模块-->
<!--用在资源控制器,资源扫描上-->
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>scanner-api</artifactId>
<version>1.0.0</version>
</dependency>
<!--参数校验模块-->
<!--用在控制器,参数校验-->
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>validator-api</artifactId>
<version>1.0.0</version>
</dependency>
<!--数据库sdk-->
<!--数据库dao框架-->
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>db-sdk-mp</artifactId>
<version>1.0.0</version>
</dependency>
<!--web模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,20 @@
package cn.stylefeng.roses.kernel.loginlog.modular.constants;
public interface LoginLogConstant {
String LOGIN_IN_LOGINNAME = "登录日志";
String LOGIN_OUT_LOGINNAME = "退出日志";
String OPERATION_SUCCESS = "成功";
String OPERATION_FAIL = "失败";
String LOGIN_IN_SUCCESS_MESSAGE = "系统登录成功!";
String LOGIN_IN_SUCCESS_FAIL = "系统登录失败!";
String LOGIN_OUT_SUCCESS_MESSAGE = "系统退出成功!";
String LOGIN_OUT_SUCCESS_FAIL = "系统退出失败!";
}

View File

@ -0,0 +1,64 @@
package cn.stylefeng.roses.kernel.loginlog.modular.controller;
import cn.stylefeng.roses.kernel.loginlog.modular.service.SysLoginLogService;
import cn.stylefeng.roses.kernel.resource.api.annotation.ApiResource;
import cn.stylefeng.roses.kernel.resource.api.annotation.GetResource;
import cn.stylefeng.roses.kernel.rule.pojo.response.ResponseData;
import cn.stylefeng.roses.kernel.rule.pojo.response.SuccessResponseData;
import cn.stylefeng.roses.kernel.system.pojo.loginlog.request.SysLoginLogRequest;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
*
*
* @author chenjinlong
* @date 2021/1/13 17:51
*/
@RestController
@ApiResource(name = "登录日志")
public class SysLoginLogController {
@Resource
private SysLoginLogService sysLoginLogService;
/**
*
*
* @author chenjinlong
* @date 2021/1/13 17:51
*/
@GetResource(name = "清空登录日志", path = "/loginLog/deleteAll")
public ResponseData deleteAll() {
sysLoginLogService.deleteAll();
return new SuccessResponseData();
}
/**
*
*
* @author chenjinlong
* @date 2021/1/13 17:51
*/
@GetResource(name = "查看详情登录日志", path = "/loginLog/detail")
public ResponseData detail(@Validated(SysLoginLogRequest.detail.class) SysLoginLogRequest sysLoginLogRequest) {
return new SuccessResponseData(sysLoginLogService.detail(sysLoginLogRequest));
}
/**
*
*
* @author chenjinlong
* @date 2021/1/13 17:51
*/
@GetResource(name = "分页查询登录日志", path = "/loginLog/page")
public ResponseData page(SysLoginLogRequest sysLoginLogRequest) {
return new SuccessResponseData(sysLoginLogService.page(sysLoginLogRequest));
}
}

View File

@ -0,0 +1,63 @@
package cn.stylefeng.roses.kernel.loginlog.modular.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;
/**
*
*
* @author chenjinlong
* @date 2021/1/13 11:05
*/
@Data
@TableName("sys_login_log")
public class SysLoginLog {
/**
* id
*/
@TableId("llg_id")
private Long llgId;
/**
*
*/
@TableField("llg_name")
private String llgName;
/**
*
*/
@TableField("llg_succeed")
private String llgSucceed;
/**
*
*/
@TableField("llg_message")
private String llgMessage;
/**
* ip
*/
@TableField("llg_ip_address")
private String llgIpAddress;
/**
* id
*/
@TableField(value = "user_id")
private Long userId;
/**
*
*/
@TableField(value = "create_time", fill = FieldFill.INSERT)
private Date createTime;
}

View File

@ -0,0 +1,6 @@
package cn.stylefeng.roses.kernel.loginlog.modular.factory;
public class SysLoginLogFactory {
}

View File

@ -0,0 +1,37 @@
/*
Copyright [2020] [https://www.stylefeng.cn]
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.
GunsAPACHE LICENSE 2.0使
1.LICENSE
2.Guns
3.
4. https://gitee.com/stylefeng/guns-separation
5. https://gitee.com/stylefeng/guns-separation
6.Guns https://www.stylefeng.cn
*/
package cn.stylefeng.roses.kernel.loginlog.modular.mapper;
import cn.stylefeng.roses.kernel.loginlog.modular.entity.SysLoginLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* mapper
*
* @author fengshuonan
* @date 2020/3/13 16:17
*/
public interface SysLoginLogMapper extends BaseMapper<SysLoginLog> {
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.stylefeng.roses.kernel.loginlog.modular.mapper.SysLoginLogMapper">
</mapper>

View File

@ -0,0 +1,71 @@
/*
Copyright [2020] [https://www.stylefeng.cn]
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.
GunsAPACHE LICENSE 2.0使
1.LICENSE
2.Guns
3.
4. https://gitee.com/stylefeng/guns-separation
5. https://gitee.com/stylefeng/guns-separation
6.Guns https://www.stylefeng.cn
*/
package cn.stylefeng.roses.kernel.loginlog.modular.service;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import cn.stylefeng.roses.kernel.loginlog.modular.entity.SysLoginLog;
import cn.stylefeng.roses.kernel.system.LoginLogServiceApi;
import cn.stylefeng.roses.kernel.system.pojo.loginlog.request.SysLoginLogRequest;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* service
*
* @author chenjinlong
* @date 2021/1/13 10:56
*/
public interface SysLoginLogService extends IService<SysLoginLog>, LoginLogServiceApi {
/**
*
*
* @param sysLoginLogRequest
* @author chenjinlong
* @date 2021/1/13 10:55
*/
void delete(SysLoginLogRequest sysLoginLogRequest);
/**
*
*
* @param sysLoginLogRequest
* @author chenjinlong
* @date 2021/1/13 10:56
*/
SysLoginLog detail(SysLoginLogRequest sysLoginLogRequest);
/**
*
*
* @param sysLoginLogRequest
* @author chenjinlong
* @date 2021/1/13 10:57
*/
PageResult<SysLoginLog> page(SysLoginLogRequest sysLoginLogRequest);
}

View File

@ -0,0 +1,133 @@
package cn.stylefeng.roses.kernel.loginlog.modular.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.stylefeng.roses.kernel.db.api.factory.PageFactory;
import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import cn.stylefeng.roses.kernel.loginlog.modular.constants.LoginLogConstant;
import cn.stylefeng.roses.kernel.loginlog.modular.entity.SysLoginLog;
import cn.stylefeng.roses.kernel.loginlog.modular.mapper.SysLoginLogMapper;
import cn.stylefeng.roses.kernel.loginlog.modular.service.SysLoginLogService;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import cn.stylefeng.roses.kernel.rule.util.HttpServletUtil;
import cn.stylefeng.roses.kernel.system.exception.enums.AppExceptionEnum;
import cn.stylefeng.roses.kernel.system.pojo.loginlog.request.SysLoginLogRequest;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* service
*
* @author fengshuonan
* @date 2020/3/13 16:15
*/
@Service
public class SysLoginLogServiceImpl extends ServiceImpl<SysLoginLogMapper, SysLoginLog> implements SysLoginLogService {
@Override
public void add(SysLoginLogRequest sysLoginLogRequest) {
SysLoginLog sysLoginLog = new SysLoginLog();
BeanUtil.copyProperties(sysLoginLogRequest, sysLoginLog);
this.save(sysLoginLog);
}
@Override
public void loginSuccess(Long userId) {
SysLoginLog sysLoginLog = new SysLoginLog();
sysLoginLog.setLlgName(LoginLogConstant.LOGIN_IN_LOGINNAME);
sysLoginLog.setUserId(userId);
sysLoginLog.setLlgIpAddress(HttpServletUtil.getRequestClientIp(HttpServletUtil.getRequest()));
sysLoginLog.setLlgSucceed(LoginLogConstant.OPERATION_SUCCESS);
sysLoginLog.setLlgMessage(LoginLogConstant.LOGIN_IN_SUCCESS_MESSAGE);
this.save(sysLoginLog);
}
@Override
public void loginFail(Long userId, String llgMessage) {
SysLoginLog sysLoginLog = new SysLoginLog();
sysLoginLog.setLlgName(LoginLogConstant.LOGIN_IN_LOGINNAME);
sysLoginLog.setUserId(userId);
sysLoginLog.setLlgIpAddress(HttpServletUtil.getRequestClientIp(HttpServletUtil.getRequest()));
sysLoginLog.setLlgSucceed(LoginLogConstant.OPERATION_FAIL);
sysLoginLog.setLlgMessage(llgMessage);
this.save(sysLoginLog);
}
@Override
public void loginOutSuccess(Long userId) {
SysLoginLog sysLoginLog = new SysLoginLog();
sysLoginLog.setLlgName(LoginLogConstant.LOGIN_OUT_LOGINNAME);
sysLoginLog.setUserId(userId);
sysLoginLog.setLlgIpAddress(HttpServletUtil.getRequestClientIp(HttpServletUtil.getRequest()));
sysLoginLog.setLlgSucceed(LoginLogConstant.OPERATION_SUCCESS);
sysLoginLog.setLlgMessage(LoginLogConstant.LOGIN_OUT_SUCCESS_MESSAGE);
this.save(sysLoginLog);
}
@Override
public void loginOutFail(Long userId) {
SysLoginLog sysLoginLog = new SysLoginLog();
sysLoginLog.setLlgName(LoginLogConstant.LOGIN_OUT_LOGINNAME);
sysLoginLog.setUserId(userId);
sysLoginLog.setLlgIpAddress(HttpServletUtil.getRequestClientIp(HttpServletUtil.getRequest()));
sysLoginLog.setLlgSucceed(LoginLogConstant.OPERATION_FAIL);
sysLoginLog.setLlgMessage(LoginLogConstant.LOGIN_OUT_SUCCESS_FAIL);
this.save(sysLoginLog);
}
@Override
public void delete(SysLoginLogRequest sysLoginLogRequest) {
}
@Override
public void deleteAll() {
this.remove(null);
}
@Override
public SysLoginLog detail(SysLoginLogRequest sysLoginLogRequest) {
return this.querySysLoginLog(sysLoginLogRequest);
}
@Override
public PageResult<SysLoginLog> page(SysLoginLogRequest sysLoginLogRequest) {
LambdaQueryWrapper<SysLoginLog> wrapper = createWrapper(sysLoginLogRequest);
wrapper.orderByDesc(SysLoginLog::getCreateTime);
Page<SysLoginLog> page = this.page(PageFactory.defaultPage(), wrapper);
return PageResultFactory.createPageResult(page);
}
/**
*
*
* @author chenjinlong
* @date 2021/1/13 10:50
*/
private SysLoginLog querySysLoginLog(SysLoginLogRequest sysLoginLogRequest) {
SysLoginLog sysLoginLog = this.getById(sysLoginLogRequest.getLlgId());
if (ObjectUtil.isNull(sysLoginLog)) {
throw new ServiceException(AppExceptionEnum.APP_NOT_EXIST);
}
return sysLoginLog;
}
/**
* wrapper
*
* @author chenjinlong
* @date 2021/1/13 10:50
*/
private LambdaQueryWrapper<SysLoginLog> createWrapper(SysLoginLogRequest sysLoginLogRequest) {
LambdaQueryWrapper<SysLoginLog> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(StrUtil.isNotBlank(sysLoginLogRequest.getLlgName()), SysLoginLog::getLlgName, sysLoginLogRequest.getLlgName());
queryWrapper.ge(StrUtil.isNotBlank(sysLoginLogRequest.getBeginTime()), SysLoginLog::getCreateTime, sysLoginLogRequest.getBeginTime());
queryWrapper.le(StrUtil.isNotBlank(sysLoginLogRequest.getEndTime()), SysLoginLog::getCreateTime, sysLoginLogRequest.getEndTime());
return queryWrapper;
}
}

View File

@ -19,9 +19,9 @@ import cn.stylefeng.roses.kernel.system.pojo.notice.SysNoticeRequest;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
@ -36,15 +36,14 @@ public class SysNoticeServiceImpl extends ServiceImpl<SysNoticeMapper, SysNotice
private static String NOTICE_SCOPE_ALL = "all";
@Autowired
private SysNoticeMapper noticeMapper;
/**
* api
*/
@Autowired
@Resource
private MessageApi messageApi;
private void sendMessage(SysNotice sysNotice){
private void sendMessage(SysNotice sysNotice) {
MessageSendParam message = new MessageSendParam();
// 消息标题
message.setMessageTitle(sysNotice.getNoticeTitle());
@ -64,12 +63,12 @@ public class SysNoticeServiceImpl extends ServiceImpl<SysNoticeMapper, SysNotice
public void add(SysNoticeRequest sysNoticeRequest) {
SysNotice sysNotice = new SysNotice();
BeanUtil.copyProperties(sysNoticeRequest, sysNotice);
if(StrUtil.isBlank(sysNotice.getNoticeScope())){
if (StrUtil.isBlank(sysNotice.getNoticeScope())) {
sysNotice.setNoticeScope(NOTICE_SCOPE_ALL);
}
// 如果保存成功调用发送消息
if(this.save(sysNotice)){
if (this.save(sysNotice)) {
sendMessage(sysNotice);
}
}
@ -79,10 +78,10 @@ public class SysNoticeServiceImpl extends ServiceImpl<SysNoticeMapper, SysNotice
SysNotice sysNotice = this.querySysNotice(sysNoticeRequest);
String noticeScope = sysNotice.getNoticeScope();
if(StrUtil.isBlank(sysNoticeRequest.getNoticeScope())){
if (StrUtil.isBlank(sysNoticeRequest.getNoticeScope())) {
sysNoticeRequest.setNoticeScope(NOTICE_SCOPE_ALL);
}
if(sysNoticeRequest.equals(sysNotice.getNoticeScope())){
if (sysNoticeRequest.equals(sysNotice.getNoticeScope())) {
throw new ServiceException(NoticeExceptionEnum.NOTICE_SCOPE_NOT_EDIT);
}
BeanUtil.copyProperties(sysNoticeRequest, sysNotice);
@ -90,7 +89,7 @@ public class SysNoticeServiceImpl extends ServiceImpl<SysNoticeMapper, SysNotice
// 通知范围不允许修改
sysNotice.setNoticeScope(noticeScope);
if(this.updateById(sysNotice)){
if (this.updateById(sysNotice)) {
sendMessage(sysNotice);
}
}

View File

@ -66,6 +66,14 @@
<version>1.0.0</version>
</dependency>
<!--登录日志的业务-->
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>system-business-login-log</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</project>