新增系统操作日志

newFrame
anthonyywj2 2 years ago
parent d505666984
commit 6f00ab30d8

@ -0,0 +1,40 @@
package com.glxp.api.admin.annotation;
import com.glxp.api.admin.constant.BusinessType;
import com.glxp.api.admin.constant.OperatorType;
import java.lang.annotation.*;
/**
*
*/
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
/**
*
*/
String title() default "";
/**
*
*/
BusinessType businessType() default BusinessType.OTHER;
/**
*
*/
OperatorType operatorType() default OperatorType.MANAGE;
/**
*
*/
boolean isSaveRequestData() default true;
/**
*
*/
boolean isSaveResponseData() default true;
}

@ -0,0 +1,191 @@
package com.glxp.api.admin.aspect;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.glxp.api.admin.annotation.Log;
import com.glxp.api.admin.constant.BusinessStatus;
import com.glxp.api.admin.entity.monitor.OperLogDTO;
import com.glxp.api.admin.service.monitor.OperLogService;
import com.glxp.api.admin.util.JsonUtils;
import com.glxp.api.admin.util.ServletUtils;
import com.glxp.api.admin.util.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.HandlerMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.Map;
/**
*
*/
@Slf4j
@Aspect
@Component
public class LogAspect {
/**
*
*/
public static final String[] EXCLUDE_PROPERTIES = {"password", "oldPassword", "newPassword", "confirmPassword"};
/**
*
*
* @param joinPoint
*/
@AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")
public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) {
handleLog(joinPoint, controllerLog, null, jsonResult);
}
/**
*
*
* @param joinPoint
* @param e
*/
@AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) {
handleLog(joinPoint, controllerLog, e, null);
}
protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) {
try {
// *========数据库日志=========*//
OperLogDTO operLog = new OperLogDTO();
operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
// 请求的地址
String ip = ServletUtils.getClientIP();
operLog.setOperIp(ip);
operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255));
// operLog.setOperName(LoginHelper.getUsername());
if (e != null) {
operLog.setStatus(BusinessStatus.FAIL.ordinal());
operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
}
// 设置方法名称
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
operLog.setMethod(className + "." + methodName + "()");
// 设置请求方式
operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
// 处理设置注解上的参数
getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
// 保存数据库
SpringUtils.getBean(OperLogService.class).recordOper(operLog);
} catch (Exception exp) {
// 记录本地异常日志
log.error("==前置通知异常==");
log.error("异常信息:{}", exp.getMessage());
exp.printStackTrace();
}
}
/**
* Controller
*
* @param log
* @param operLog
* @throws Exception
*/
public void getControllerMethodDescription(JoinPoint joinPoint, Log log, OperLogDTO operLog, Object jsonResult) throws Exception {
// 设置action动作
operLog.setBusinessType(log.businessType().ordinal());
// 设置标题
operLog.setTitle(log.title());
// 设置操作人类别
operLog.setOperatorType(log.operatorType().ordinal());
// 是否需要保存request参数和值
if (log.isSaveRequestData()) {
// 获取参数的信息,传入到数据库中。
setRequestValue(joinPoint, operLog);
}
// 是否需要保存response参数和值
if (log.isSaveResponseData() && ObjectUtil.isNotNull(jsonResult)) {
operLog.setJsonResult(StringUtils.substring(JsonUtils.toJsonString(jsonResult), 0, 2000));
}
}
/**
* log
*
* @param operLog
* @throws Exception
*/
private void setRequestValue(JoinPoint joinPoint, OperLogDTO operLog) throws Exception {
String requestMethod = operLog.getRequestMethod();
if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) {
String params = argsArrayToString(joinPoint.getArgs());
operLog.setOperParam(StringUtils.substring(params, 0, 2000));
} else {
Map<?, ?> paramsMap = (Map<?, ?>) ServletUtils.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
operLog.setOperParam(StringUtils.substring(paramsMap.toString(), 0, 2000));
}
}
/**
*
*/
private String argsArrayToString(Object[] paramsArray) {
StringBuilder params = new StringBuilder();
if (paramsArray != null && paramsArray.length > 0) {
for (Object o : paramsArray) {
if (ObjectUtil.isNotNull(o) && !isFilterObject(o)) {
try {
String str = JsonUtils.toJsonString(o);
Dict dict = JsonUtils.parseMap(str);
if (MapUtil.isNotEmpty(dict)) {
MapUtil.removeAny(dict, EXCLUDE_PROPERTIES);
str = JsonUtils.toJsonString(dict);
}
params.append(str).append(" ");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
return params.toString().trim();
}
/**
*
*
* @param o
* @return truefalse
*/
@SuppressWarnings("rawtypes")
public boolean isFilterObject(final Object o) {
Class<?> clazz = o.getClass();
if (clazz.isArray()) {
return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
} else if (Collection.class.isAssignableFrom(clazz)) {
Collection collection = (Collection) o;
for (Object value : collection) {
return value instanceof MultipartFile;
}
} else if (Map.class.isAssignableFrom(clazz)) {
Map map = (Map) o;
for (Object value : map.entrySet()) {
Map.Entry entry = (Map.Entry) value;
return entry.getValue() instanceof MultipartFile;
}
}
return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse
|| o instanceof BindingResult;
}
}

@ -0,0 +1,52 @@
package com.glxp.api.admin.config;
import lombok.Data;
import lombok.Getter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
*
*/
@Data
@Component
@ConfigurationProperties(prefix = "ruoyi")
public class RuoYiConfig {
/**
*
*/
private String name;
/**
*
*/
private String version;
/**
*
*/
private String copyrightYear;
/**
*
*/
private boolean demoEnabled;
/**
*
*/
private boolean cacheLazy;
/**
*
*/
@Getter
private static boolean addressEnabled;
public void setAddressEnabled(boolean addressEnabled) {
RuoYiConfig.addressEnabled = addressEnabled;
}
}

@ -0,0 +1,18 @@
package com.glxp.api.admin.constant;
/**
*
*
* @author ruoyi
*/
public enum BusinessStatus {
/**
*
*/
SUCCESS,
/**
*
*/
FAIL,
}

@ -0,0 +1,56 @@
package com.glxp.api.admin.constant;
/**
*
*/
public enum BusinessType {
/**
*
*/
OTHER,
/**
*
*/
INSERT,
/**
*
*/
UPDATE,
/**
*
*/
DELETE,
/**
*
*/
GRANT,
/**
*
*/
EXPORT,
/**
*
*/
IMPORT,
/**
* 退
*/
FORCE,
/**
*
*/
GENCODE,
/**
*
*/
CLEAN,
}

@ -105,4 +105,38 @@ public class Constant {
public static final String YES = "Y";
public static final String UTF8 = "UTF-8";
public static final String GBK = "GBK";
/**
*
*/
public static final String FAIL = "1";
/**
*
*/
public static final String SUCCESS = "0";
/**
*
*/
public static final String LOGIN_SUCCESS = "Success";
/**
*
*/
public static final String LOGOUT = "Logout";
/**
*
*/
public static final String REGISTER = "Register";
/**
*
*/
public static final String LOGIN_FAIL = "Error";
}

@ -0,0 +1,21 @@
package com.glxp.api.admin.constant;
/**
*
*/
public enum OperatorType {
/**
*
*/
OTHER,
/**
*
*/
MANAGE,
/**
*
*/
MOBILE
}

@ -2,6 +2,8 @@ package com.glxp.api.admin.controller.auth;
import com.github.pagehelper.PageInfo;
import com.glxp.api.admin.annotation.AuthRuleAnnotation;
import com.glxp.api.admin.annotation.Log;
import com.glxp.api.admin.constant.BusinessType;
import com.glxp.api.admin.entity.auth.AuthAdmin;
import com.glxp.api.admin.entity.auth.AuthRole;
import com.glxp.api.admin.entity.auth.AuthRoleAdmin;
@ -239,6 +241,7 @@ public class AuthAdminController {
*
* @return
*/
@Log(title = "用户管理", businessType = BusinessType.DELETE)
@AuthRuleAnnotation("admin/auth/admin/delete")
@PostMapping("/admin/auth/admin/delete")
public BaseResponse delete(@RequestBody AuthAdminSaveRequest authAdminSaveRequest) {

@ -1,6 +1,7 @@
package com.glxp.api.admin.controller.auth;
import cn.hutool.core.util.StrUtil;
import com.glxp.api.admin.constant.Constant;
import com.glxp.api.admin.controller.BaseController;
import com.glxp.api.admin.dao.auth.AuthLicenseDao;
import com.glxp.api.admin.entity.auth.AuthCheckEntity;
@ -18,6 +19,7 @@ import com.glxp.api.admin.service.auth.*;
import com.glxp.api.admin.service.info.CompanyService;
import com.glxp.api.admin.service.inventory.InvSubWarehouseService;
import com.glxp.api.admin.service.inventory.InvWarehouseService;
import com.glxp.api.admin.service.monitor.LogininforService;
import com.glxp.api.admin.util.*;
import com.glxp.api.common.enums.ResultEnum;
import com.glxp.api.common.res.BaseResponse;
@ -52,6 +54,8 @@ public class LoginController extends BaseController {
@Autowired
private AuthAdminService authAdminService;
@Resource
private LogininforService logininforService;
@Resource
private AuthCheckService authCheckService;
@ -92,7 +96,6 @@ public class LoginController extends BaseController {
if (authAdmin.getUserFlag() == 0) {
throw new JsonException(ResultEnum.DATA_NOT, "该用户已被禁用!");
}
if (StrUtil.isNotEmpty(loginRequest.getImei())) {
DeviceKeyEntity deviceKeyEntity = deviceKeyService.findDeviceByImei(loginRequest.getImei());
if (deviceKeyEntity == null) {
@ -102,7 +105,6 @@ public class LoginController extends BaseController {
} else if (deviceKeyEntity.getIsCheck() == 2) {
return ResultVOUtils.error(412, "该设备被拒绝登录,请联系管理员!");
}
}
// 更新登录状态
@ -128,6 +130,9 @@ public class LoginController extends BaseController {
loginResponse.setToken(token);
loginResponse.setDept(authAdmin.getDept());
loginResponse.setDeptName(authAdmin.getDeptName());
logininforService.recordLogininfor(authAdmin.getEmployeeName(), Constant.LOGIN_SUCCESS, "登录成功!", request);
return ResultVOUtils.success(loginResponse);
}

@ -5,6 +5,8 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageInfo;
import com.glxp.api.admin.annotation.Log;
import com.glxp.api.admin.constant.BusinessType;
import com.glxp.api.admin.controller.BaseController;
import com.glxp.api.admin.entity.auth.AuthAdmin;
import com.glxp.api.admin.entity.auth.AuthRoleAdmin;
@ -144,7 +146,7 @@ public class SysUserController extends BaseController {
return ResultVOUtils.success("授权成功!");
}
@Log(title = "用户管理", businessType = BusinessType.INSERT)
@PostMapping("/save")
public BaseResponse save(@RequestBody @Valid AuthAdminSaveRequest authAdminSaveRequest,
BindingResult bindingResult) {

@ -0,0 +1,63 @@
package com.glxp.api.admin.controller.monitor;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.github.pagehelper.PageInfo;
import com.glxp.api.admin.annotation.Log;
import com.glxp.api.admin.constant.BusinessType;
import com.glxp.api.admin.controller.BaseController;
import com.glxp.api.admin.entity.monitor.SysLogininfor;
import com.glxp.api.admin.req.monitor.SysLogininforRequest;
import com.glxp.api.admin.res.PageSimpleResponse;
import com.glxp.api.admin.service.monitor.ISysLogininforService;
import com.glxp.api.common.res.BaseResponse;
import com.glxp.api.common.util.ResultVOUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.List;
/**
* 访
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/monitor/logininfor")
public class SysLogininforController extends BaseController {
private final ISysLogininforService logininforService;
/**
* 访
*/
@SaCheckPermission("monitor:logininfor:list")
@GetMapping("/list")
public BaseResponse list(SysLogininforRequest sysLogininforRequest) {
List<SysLogininfor> selectLogininforList = logininforService.selectLogininforList(sysLogininforRequest);
PageInfo<SysLogininfor> pageInfo;
pageInfo = new PageInfo<>(selectLogininforList);
PageSimpleResponse<SysLogininfor> pageSimpleResponse = new PageSimpleResponse<>();
pageSimpleResponse.setTotal(pageInfo.getTotal());
pageSimpleResponse.setList(selectLogininforList);
return ResultVOUtils.success(pageSimpleResponse);
}
/**
*
*
* @param infoIds ids
*/
@SaCheckPermission("monitor:logininfor:remove")
@Log(title = "登录日志", businessType = BusinessType.DELETE)
@DeleteMapping("/{infoIds}")
public BaseResponse remove(@PathVariable Long[] infoIds) {
int i = logininforService.deleteLogininforByIds(Arrays.asList(infoIds));
return ResultVOUtils.success("删除成功!");
}
}

@ -0,0 +1,64 @@
package com.glxp.api.admin.controller.monitor;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.github.pagehelper.PageInfo;
import com.glxp.api.admin.annotation.Log;
import com.glxp.api.admin.constant.BusinessType;
import com.glxp.api.admin.controller.BaseController;
import com.glxp.api.admin.entity.info.DeviceKeyEntity;
import com.glxp.api.admin.entity.monitor.SysOperLog;
import com.glxp.api.admin.req.monitor.SysOperLogRequest;
import com.glxp.api.admin.res.PageSimpleResponse;
import com.glxp.api.admin.service.monitor.ISysOperLogService;
import com.glxp.api.common.res.BaseResponse;
import com.glxp.api.common.util.ResultVOUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
*
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/monitor/operlog")
public class SysOperlogController extends BaseController {
private final ISysOperLogService operLogService;
/**
*
*/
@Log(title = "操作日志", businessType = BusinessType.OTHER)
@SaCheckPermission("monitor:operlog:list")
@GetMapping("/list")
public BaseResponse list(SysOperLogRequest sysOperLogRequest) {
List<SysOperLog> selectOperLogList = operLogService.selectOperLogList(sysOperLogRequest);
PageInfo<SysOperLog> pageInfo;
pageInfo = new PageInfo<>(selectOperLogList);
PageSimpleResponse<SysOperLog> pageSimpleResponse = new PageSimpleResponse<>();
pageSimpleResponse.setTotal(pageInfo.getTotal());
pageSimpleResponse.setList(selectOperLogList);
return ResultVOUtils.success(pageSimpleResponse);
}
/**
*
*
* @param operIds ids
*/
@Log(title = "操作日志", businessType = BusinessType.DELETE)
@SaCheckPermission("monitor:operlog:remove")
@DeleteMapping("/{operIds}")
public BaseResponse remove(@PathVariable Long[] operIds) {
int i = operLogService.deleteOperLogByIds(operIds);
return ResultVOUtils.success("删除成功!");
}
}

@ -0,0 +1,31 @@
package com.glxp.api.admin.dao.monitor;
import com.glxp.api.admin.entity.monitor.SysLogininfor;
import com.glxp.api.admin.req.monitor.SysLogininforRequest;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 访
*/
@Mapper
public interface SysLogininforMapper {
int insert(SysLogininfor sysLogininfor);
int deleteBatchIds(@Param("infoIds") List<Long> infoIds);
List<SysLogininfor> selectLogininforList(SysLogininforRequest logininforRequest);
/**
*
*
* @param logininfor 访
*/
void insertLogininfor(SysLogininfor logininfor);
}

@ -0,0 +1,28 @@
package com.glxp.api.admin.dao.monitor;
import com.glxp.api.admin.entity.monitor.SysOperLog;
import com.glxp.api.admin.req.monitor.SysOperLogRequest;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
*
*/
@Mapper
public interface SysOperLogMapper {
List<SysOperLog> selectList(SysOperLogRequest sysOperLogRequest);
int insert(SysOperLog sysOperLog);
int deleteBatchIds(@Param("ids") List<Long> ids);
int delete(Long id);
SysOperLog selectById(Long id);
}

@ -0,0 +1,102 @@
package com.glxp.api.admin.entity.monitor;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
*
*/
@Data
public class OperLogDTO implements Serializable {
private static final long serialVersionUID = 1L;
/**
*
*/
private Long operId;
/**
*
*/
private String title;
/**
* 0 1 2 3
*/
private Integer businessType;
/**
*
*/
private Integer[] businessTypes;
/**
*
*/
private String method;
/**
*
*/
private String requestMethod;
/**
* 0 1 2
*/
private Integer operatorType;
/**
*
*/
private String operName;
/**
*
*/
private String deptName;
/**
* url
*/
private String operUrl;
/**
*
*/
private String operIp;
/**
*
*/
private String operLocation;
/**
*
*/
private String operParam;
/**
*
*/
private String jsonResult;
/**
* 0 1
*/
private Integer status;
/**
*
*/
private String errorMsg;
/**
*
*/
private Date operTime;
}

@ -0,0 +1,68 @@
package com.glxp.api.admin.entity.monitor;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* 访 sys_logininfor
*/
@Data
public class SysLogininfor implements Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
private Long infoId;
/**
*
*/
private String userName;
/**
* 0 1
*/
private String status;
/**
* IP
*/
private String ipaddr;
/**
*
*/
private String loginLocation;
/**
*
*/
private String browser;
/**
*
*/
private String os;
/**
*
*/
private String msg;
/**
* 访
*/
private Date loginTime;
/**
*
*/
private Map<String, Object> params = new HashMap<>();
}

@ -0,0 +1,109 @@
package com.glxp.api.admin.entity.monitor;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* oper_log
*/
@Data
public class SysOperLog implements Serializable {
private static final long serialVersionUID = 1L;
/**
*
*/
private Long operId;
/**
*
*/
private String title;
/**
* 0 1 2 3
*/
private Integer businessType;
/**
*
*/
private Integer[] businessTypes;
/**
*
*/
private String method;
/**
*
*/
private String requestMethod;
/**
* 0 1 2
*/
private Integer operatorType;
/**
*
*/
private String operName;
/**
*
*/
private String deptName;
/**
* url
*/
private String operUrl;
/**
*
*/
private String operIp;
/**
*
*/
private String operLocation;
/**
*
*/
private String operParam;
/**
*
*/
private String jsonResult;
/**
* 0 1
*/
private Integer status;
/**
*
*/
private String errorMsg;
/**
*
*/
private Date operTime;
/**
*
*/
private Map<String, Object> params = new HashMap<>();
}

@ -0,0 +1,21 @@
package com.glxp.api.admin.req.monitor;
import com.glxp.api.admin.req.ListPageRequest;
import lombok.Data;
import java.util.Date;
@Data
public class SysLogininforRequest extends ListPageRequest {
private Long infoId;
private String userName;
private String status;
private String ipaddr;
private String loginLocation;
}

@ -0,0 +1,34 @@
package com.glxp.api.admin.req.monitor;
import com.glxp.api.admin.req.ListPageRequest;
import lombok.Data;
import java.util.Date;
@Data
public class SysOperLogRequest extends ListPageRequest {
private Long operId;
private String title;
private Integer businessType;
private String method;
private String requestMethod;
private Integer operatorType;
private String operName;
private String deptName;
private String operUrl;
private String operIp;
private Integer status;
}

@ -0,0 +1,35 @@
package com.glxp.api.admin.service.monitor;
import com.glxp.api.admin.entity.monitor.SysLogininfor;
import com.glxp.api.admin.req.monitor.SysLogininforRequest;
import java.util.List;
/**
* 访
*
* @author Lion Li
*/
public interface ISysLogininforService {
List<SysLogininfor> selectLogininforList(SysLogininforRequest logininforRequest);
/**
*
*
* @param logininfor 访
*/
void insertLogininfor(SysLogininfor logininfor);
/**
*
*
* @param infoIds ID
* @return
*/
int deleteLogininforByIds(List<Long> infoIds);
}

@ -0,0 +1,46 @@
package com.glxp.api.admin.service.monitor;
import com.glxp.api.admin.entity.monitor.SysOperLog;
import com.glxp.api.admin.req.monitor.SysOperLogRequest;
import java.util.List;
/**
*
*/
public interface ISysOperLogService {
/**
*
*
* @param operLog
*/
void insertOperlog(SysOperLog operLog);
/**
*
*
* @param operLog
* @return
*/
List<SysOperLog> selectOperLogList(SysOperLogRequest sysOperLogRequest);
/**
*
*
* @param operIds ID
* @return
*/
int deleteOperLogByIds(Long[] operIds);
/**
*
*
* @param operId ID
* @return
*/
SysOperLog selectOperLogById(Long operId);
}

@ -0,0 +1,12 @@
package com.glxp.api.admin.service.monitor;
import javax.servlet.http.HttpServletRequest;
/**
* 访
*/
public interface LogininforService {
void recordLogininfor(String username, String status, String message,
HttpServletRequest request, Object... args);
}

@ -0,0 +1,13 @@
package com.glxp.api.admin.service.monitor;
import com.glxp.api.admin.entity.monitor.OperLogDTO;
import org.springframework.scheduling.annotation.Async;
/**
*
*/
public interface OperLogService {
@Async
void recordOper(OperLogDTO operLogDTO);
}

@ -0,0 +1,113 @@
package com.glxp.api.admin.service.monitor.impl;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.github.pagehelper.PageHelper;
import com.glxp.api.admin.constant.Constant;
import com.glxp.api.admin.dao.monitor.SysLogininforMapper;
import com.glxp.api.admin.entity.monitor.SysLogininfor;
import com.glxp.api.admin.req.monitor.SysLogininforRequest;
import com.glxp.api.admin.service.monitor.ISysLogininforService;
import com.glxp.api.admin.service.monitor.LogininforService;
import com.glxp.api.admin.util.AddressUtils;
import com.glxp.api.admin.util.ServletUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
/**
* 访
*/
@RequiredArgsConstructor
@Slf4j
@Service
public class SysLogininforServiceImpl implements ISysLogininforService, LogininforService {
private final SysLogininforMapper baseMapper;
/**
*
*
* @param username
* @param status
* @param message
* @param args
*/
@Async
@Override
public void recordLogininfor(final String username, final String status, final String message,
HttpServletRequest request, final Object... args) {
final UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
final String ip = ServletUtils.getClientIP(request);
String address = AddressUtils.getRealAddressByIP(ip);
StringBuilder s = new StringBuilder();
s.append(getBlock(ip));
s.append(address);
s.append(getBlock(username));
s.append(getBlock(status));
s.append(getBlock(message));
// 打印信息到日志
log.info(s.toString(), args);
// 获取客户端操作系统
String os = userAgent.getOs().getName();
// 获取客户端浏览器
String browser = userAgent.getBrowser().getName();
// 封装对象
SysLogininfor logininfor = new SysLogininfor();
logininfor.setUserName(username);
logininfor.setIpaddr(ip);
logininfor.setLoginLocation(address);
logininfor.setBrowser(browser);
logininfor.setOs(os);
logininfor.setMsg(message);
// 日志状态
if (StringUtils.equalsAny(status, Constant.LOGIN_SUCCESS, Constant.LOGOUT, Constant.REGISTER)) {
logininfor.setStatus(Constant.SUCCESS);
} else if (Constant.LOGIN_FAIL.equals(status)) {
logininfor.setStatus(Constant.FAIL);
}
// 插入数据
insertLogininfor(logininfor);
}
private String getBlock(Object msg) {
if (msg == null) {
msg = "";
}
return "[" + msg.toString() + "]";
}
@Override
public List<SysLogininfor> selectLogininforList(SysLogininforRequest logininfor) {
if (logininfor.getPage() != null) {
int offset = (logininfor.getPage() - 1) * logininfor.getLimit();
PageHelper.offsetPage(offset, logininfor.getLimit());
}
return baseMapper.selectLogininforList(logininfor);
}
/**
*
*
* @param logininfor 访
*/
@Override
public void insertLogininfor(SysLogininfor logininfor) {
logininfor.setLoginTime(new Date());
baseMapper.insert(logininfor);
}
@Override
public int deleteLogininforByIds(List<Long> infoIds) {
return baseMapper.deleteBatchIds(infoIds);
}
}

@ -0,0 +1,90 @@
package com.glxp.api.admin.service.monitor.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.glxp.api.admin.dao.monitor.SysOperLogMapper;
import com.glxp.api.admin.entity.monitor.OperLogDTO;
import com.glxp.api.admin.entity.monitor.SysOperLog;
import com.glxp.api.admin.req.monitor.SysOperLogRequest;
import com.glxp.api.admin.service.monitor.ISysOperLogService;
import com.glxp.api.admin.service.monitor.OperLogService;
import com.glxp.api.admin.util.AddressUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
*
*/
@RequiredArgsConstructor
@Service
public class SysOperLogServiceImpl implements ISysOperLogService, OperLogService {
private final SysOperLogMapper baseMapper;
/**
*
*
* @param operLogDTO
*/
@Async
@Override
public void recordOper(final OperLogDTO operLogDTO) {
SysOperLog operLog = BeanUtil.toBean(operLogDTO, SysOperLog.class);
// 远程查询操作地点
operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
insertOperlog(operLog);
}
@Override
public List<SysOperLog> selectOperLogList(SysOperLogRequest sysOperLogRequest) {
if (sysOperLogRequest.getPage() != null) {
int offset = (sysOperLogRequest.getPage() - 1) * sysOperLogRequest.getLimit();
PageHelper.offsetPage(offset, sysOperLogRequest.getLimit());
}
return baseMapper.selectList(sysOperLogRequest);
}
/**
*
*
* @param operLog
*/
@Override
public void insertOperlog(SysOperLog operLog) {
operLog.setOperTime(new Date());
baseMapper.insert(operLog);
}
/**
*
*
* @param operIds ID
* @return
*/
@Override
public int deleteOperLogByIds(Long[] operIds) {
return baseMapper.deleteBatchIds(Arrays.asList(operIds));
}
/**
*
*
* @param operId ID
* @return
*/
@Override
public SysOperLog selectOperLogById(Long operId) {
return baseMapper.selectById(operId);
}
}

@ -0,0 +1,58 @@
package com.glxp.api.admin.util;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.net.NetUtil;
import cn.hutool.http.HtmlUtil;
import cn.hutool.http.HttpUtil;
import com.glxp.api.admin.config.RuoYiConfig;
import com.glxp.api.admin.constant.Constant;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.bcel.Const;
/**
*
*/
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class AddressUtils {
// IP地址查询
public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp";
// 未知地址
public static final String UNKNOWN = "XX XX";
public static String getRealAddressByIP(String ip) {
String address = UNKNOWN;
if (StringUtils.isBlank(ip)) {
return address;
}
// 内网不查询
ip = "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : HtmlUtil.cleanHtmlTag(ip);
if (NetUtil.isInnerIP(ip)) {
return "内网IP";
}
if (RuoYiConfig.isAddressEnabled()) {
try {
String rspStr = HttpUtil.createGet(IP_URL)
.body("ip=" + ip + "&json=true", Constant.GBK)
.execute()
.body();
if (StringUtils.isEmpty(rspStr)) {
log.error("获取地理位置异常 {}", ip);
return UNKNOWN;
}
Dict obj = JsonUtils.parseMap(rspStr);
String region = obj.getStr("pro");
String city = obj.getStr("city");
return String.format("%s %s", region, city);
} catch (Exception e) {
log.error("获取地理位置异常 {}", ip);
}
}
return UNKNOWN;
}
}

@ -0,0 +1,110 @@
package com.glxp.api.admin.util;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* JSON
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class JsonUtils {
private static final ObjectMapper OBJECT_MAPPER = SpringUtils.getBean(ObjectMapper.class);
public static ObjectMapper getObjectMapper() {
return OBJECT_MAPPER;
}
public static String toJsonString(Object object) {
if (ObjectUtil.isNull(object)) {
return null;
}
try {
return OBJECT_MAPPER.writeValueAsString(object);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
public static <T> T parseObject(String text, Class<T> clazz) {
if (StringUtils.isEmpty(text)) {
return null;
}
try {
return OBJECT_MAPPER.readValue(text, clazz);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static <T> T parseObject(byte[] bytes, Class<T> clazz) {
if (ArrayUtil.isEmpty(bytes)) {
return null;
}
try {
return OBJECT_MAPPER.readValue(bytes, clazz);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static <T> T parseObject(String text, TypeReference<T> typeReference) {
if (StringUtils.isBlank(text)) {
return null;
}
try {
return OBJECT_MAPPER.readValue(text, typeReference);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static Dict parseMap(String text) {
if (StringUtils.isBlank(text)) {
return null;
}
try {
return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructType(Dict.class));
} catch (MismatchedInputException e) {
// 类型不匹配说明不是json
return null;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static List<Dict> parseArrayMap(String text) {
if (StringUtils.isBlank(text)) {
return null;
}
try {
return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, Dict.class));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static <T> List<T> parseArray(String text, Class<T> clazz) {
if (StringUtils.isEmpty(text)) {
return new ArrayList<>();
}
try {
return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

@ -0,0 +1,26 @@
package com.glxp.api.admin.util;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
/**
* i18n
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class MessageUtils {
private static final MessageSource MESSAGE_SOURCE = SpringUtils.getBean(MessageSource.class);
/**
* spring messageSource
*
* @param code
* @param args
* @return
*/
public static String message(String code, Object... args) {
return MESSAGE_SOURCE.getMessage(code, args, LocaleContextHolder.getLocale());
}
}

@ -0,0 +1,173 @@
package com.glxp.api.admin.util;
import cn.hutool.core.convert.Convert;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.http.HttpStatus;
import com.glxp.api.admin.constant.Constant;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
/**
*
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ServletUtils extends ServletUtil {
/**
* String
*/
public static String getParameter(String name) {
return getRequest().getParameter(name);
}
/**
* String
*/
public static String getParameter(String name, String defaultValue) {
return Convert.toStr(getRequest().getParameter(name), defaultValue);
}
/**
* Integer
*/
public static Integer getParameterToInt(String name) {
return Convert.toInt(getRequest().getParameter(name));
}
/**
* Integer
*/
public static Integer getParameterToInt(String name, Integer defaultValue) {
return Convert.toInt(getRequest().getParameter(name), defaultValue);
}
/**
* Boolean
*/
public static Boolean getParameterToBool(String name) {
return Convert.toBool(getRequest().getParameter(name));
}
/**
* Boolean
*/
public static Boolean getParameterToBool(String name, Boolean defaultValue) {
return Convert.toBool(getRequest().getParameter(name), defaultValue);
}
/**
* request
*/
public static HttpServletRequest getRequest() {
return getRequestAttributes().getRequest();
}
/**
* response
*/
public static HttpServletResponse getResponse() {
return getRequestAttributes().getResponse();
}
/**
* session
*/
public static HttpSession getSession() {
return getRequest().getSession();
}
public static ServletRequestAttributes getRequestAttributes() {
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
return (ServletRequestAttributes) attributes;
}
/**
*
*
* @param response
* @param string
*/
public static void renderString(HttpServletResponse response, String string) {
try {
response.setStatus(HttpStatus.HTTP_OK);
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
response.getWriter().print(string);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Ajax
*
* @param request
*/
public static boolean isAjaxRequest(HttpServletRequest request) {
String accept = request.getHeader("accept");
if (accept != null && accept.contains(MediaType.APPLICATION_JSON_VALUE)) {
return true;
}
String xRequestedWith = request.getHeader("X-Requested-With");
if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) {
return true;
}
String uri = request.getRequestURI();
if (StringUtils.equalsAnyIgnoreCase(uri, ".json", ".xml")) {
return true;
}
String ajax = request.getParameter("__ajax");
return StringUtils.equalsAnyIgnoreCase(ajax, "json", "xml");
}
public static String getClientIP() {
return getClientIP(getRequest());
}
/**
*
*
* @param str
* @return
*/
public static String urlEncode(String str) {
try {
return URLEncoder.encode(str, Constant.UTF8);
} catch (UnsupportedEncodingException e) {
return StringUtils.EMPTY;
}
}
/**
*
*
* @param str
* @return
*/
public static String urlDecode(String str) {
try {
return URLDecoder.decode(str, Constant.UTF8);
} catch (UnsupportedEncodingException e) {
return StringUtils.EMPTY;
}
}
}

@ -0,0 +1,63 @@
package com.glxp.api.admin.util;
import cn.hutool.extra.spring.SpringUtil;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.stereotype.Component;
/**
* spring
*/
@Component
public final class SpringUtils extends SpringUtil {
/**
* BeanFactorybeantrue
*
* @param name
* @return boolean
*/
public static boolean containsBean(String name) {
return getBeanFactory().containsBean(name);
}
/**
* beansingletonprototype
* beanNoSuchBeanDefinitionException
*
* @param name
* @return boolean
*/
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
return getBeanFactory().isSingleton(name);
}
/**
* @param name
* @return Class
*/
public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
return getBeanFactory().getType(name);
}
/**
* beanbean
*
* @param name
*/
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
return getBeanFactory().getAliases(name);
}
/**
* aop
*
* @param invoker
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T getAopProxy(T invoker) {
return (T) AopContext.currentProxy();
}
}

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.glxp.api.admin.dao.monitor.SysLogininforMapper">
<resultMap type="com.glxp.api.admin.entity.monitor.SysLogininfor" id="SysLogininforResult">
<id property="infoId" column="info_id"/>
<result property="userName" column="user_name"/>
<result property="status" column="status"/>
<result property="ipaddr" column="ipaddr"/>
<result property="loginLocation" column="login_location"/>
<result property="browser" column="browser"/>
<result property="os" column="os"/>
<result property="msg" column="msg"/>
<result property="loginTime" column="login_time"/>
</resultMap>
<select id="selectLogininforList" parameterType="com.glxp.api.admin.req.monitor.SysLogininforRequest"
resultMap="SysLogininforResult">
select *
FROM sys_logininfor
<where>
<if test="infoId != null ">
and info_id = #{infoId}
</if>
<if test="userName != null and userName != '' ">
AND `user_name` = #{userName}
</if>
<if test="status != null and status != '' ">
AND `status` = #{status}
</if>
<if test="ipaddr != null ">
AND `ipaddr` = #{ipaddr}
</if>
<if test="loginLocation != null ">
AND `login_location` = #{loginLocation}
</if>
</where>
</select>
<select id="selectById" parameterType="java.lang.Long"
resultMap="SysLogininforResult">
select *
FROM sys_logininfor
WHERE oper_id = #{id}
</select>
<insert id="insert" keyProperty="infoId" useGeneratedKeys="true"
parameterType="com.glxp.api.admin.entity.monitor.SysLogininfor">
INSERT INTO sys_logininfor( `user_name`, `status`, ipaddr, `login_location`, browser, `os`, msg
, login_time)
values (#{userName},
#{status}, #{ipaddr},
#{loginLocation}, #{browser}, #{os}, #{msg}, #{loginTime})
</insert>
<delete id="delete" parameterType="java.lang.Long">
delete
from sys_logininfor
where info_id = #{id}
</delete>
<delete id="deleteBatchIds" parameterType="java.util.List"
>
delete
from sys_logininfor
where info_id in
<foreach item="item" index="index" collection="infoIds" open="(" separator="," close=")">
#{item}
</foreach>
</delete>
</mapper>

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.glxp.api.admin.dao.monitor.SysOperLogMapper">
<resultMap type="com.glxp.api.admin.entity.monitor.SysOperLog" id="SysOperLogResult">
<id property="operId" column="oper_id"/>
<result property="title" column="title"/>
<result property="businessType" column="business_type"/>
<result property="method" column="method"/>
<result property="requestMethod" column="request_method"/>
<result property="operatorType" column="operator_type"/>
<result property="operName" column="oper_name"/>
<result property="deptName" column="dept_name"/>
<result property="operUrl" column="oper_url"/>
<result property="operIp" column="oper_ip"/>
<result property="operLocation" column="oper_location"/>
<result property="operParam" column="oper_param"/>
<result property="jsonResult" column="json_result"/>
<result property="status" column="status"/>
<result property="errorMsg" column="error_msg"/>
<result property="operTime" column="oper_time"/>
</resultMap>
<select id="selectList" parameterType="com.glxp.api.admin.req.monitor.SysOperLogRequest"
resultMap="SysOperLogResult">
select *
FROM sys_oper_log
<where>
<if test="operId != null ">
and oper_id = #{operId}
</if>
<if test="title != null and title != '' ">
AND `title` = #{title}
</if>
<if test="businessType != null and businessType != '' ">
AND `business_type` = #{businessType}
</if>
<if test="method != null ">
AND `method` = #{method}
</if>
<if test="requestMethod != null ">
AND `request_method` = #{requestMethod}
</if>
<if test="operatorType != null ">
AND `operator_type` = #{operatorType}
</if>
<if test="operName != null ">
AND `oper_name` = #{operName}
</if>
<if test="deptName != null ">
AND `dept_name` = #{deptName}
</if>
<if test="operUrl != null ">
AND `oper_url` = #{operUrl}
</if>
<if test="operIp != null ">
AND `oper_ip` = #{operIp}
</if>
<if test="status != null ">
AND `status` = #{status}
</if>
</where>
</select>
<select id="selectById" parameterType="java.lang.Long"
resultMap="SysOperLogResult">
select *
FROM sys_oper_log
WHERE oper_id = #{id}
</select>
<insert id="insert" keyProperty="operIp" useGeneratedKeys="true"
parameterType="com.glxp.api.admin.entity.monitor.SysOperLog">
INSERT INTO sys_oper_log(`oper_id`, `title`, business_type, `method`, `request_method`, operator_type
, oper_name, dept_name, oper_url, oper_ip, oper_location, oper_param, json_result, status,
error_msg, oper_time)
values ( #{operId},
#{title}, #{businessType}, #{method}, #{requestMethod}, #{operatorType}, #{operName}, #{deptName}
, #{operUrl}, #{operIp}, #{operLocation}, #{operParam}, #{jsonResult}, #{status}
, #{errorMsg}, #{operTime})
</insert>
<delete id="delete" parameterType="java.lang.Long">
delete
from sys_oper_log
where oper_id = #{id}
</delete>
<delete id="deleteBatchIds" parameterType="java.util.List"
>
delete
from sys_oper_log
where oper_id in
<foreach item="item" index="index" collection="ids" open="(" separator="," close=")">
#{item}
</foreach>
</delete>
</mapper>
Loading…
Cancel
Save