Commit ab9dd386 by yuwei

项目初始化

parent 1adde32c
......@@ -11,5 +11,12 @@
<artifactId>datax-common-log</artifactId>
<dependencies>
<dependency>
<groupId>cn.datax</groupId>
<artifactId>system-service-api</artifactId>
<version>${app.version}</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
......@@ -4,6 +4,14 @@ import java.lang.reflect.Method;
import cn.datax.common.log.annotation.LogAop;
import cn.datax.common.log.async.AsyncTask;
import cn.datax.common.utils.RequestHolder;
import cn.datax.common.utils.SecurityUtil;
import cn.datax.service.system.api.dto.LogDto;
import cn.hutool.core.util.URLUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
......@@ -13,6 +21,8 @@ import org.aspectj.lang.reflect.MethodSignature;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest;
@Slf4j
@Aspect
public class LogAspect {
......@@ -25,16 +35,6 @@ public class LogAspect {
public void logPointCut() {}
/**
* 通知方法会在目标方法返回后执行
*
* @param joinPoint 切点
*/
@AfterReturning(pointcut = "logPointCut()")
public void doAfterReturning(JoinPoint joinPoint) {
handleLog(joinPoint, null);
}
/**
* 通知方法会将目标方法封装起来
*
* @param joinPoint 切点
......@@ -43,10 +43,10 @@ public class LogAspect {
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
Object result = joinPoint.proceed();
log.info("响应结果为{}", result);
long endTime = System.currentTimeMillis();
log.info("响应时间为{}毫秒", endTime - startTime);
//如果这里不返回result,则目标对象实际返回值会被置为null
LogDto logDto = getLog();
logDto.setTime(String.valueOf(endTime - startTime));
handleLog(joinPoint, logDto);
return result;
}
......@@ -58,31 +58,45 @@ public class LogAspect {
*/
@AfterThrowing(value = "logPointCut()", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
handleLog(joinPoint, e);
LogDto logDto = getLog();
logDto.setExCode(e.getClass().getSimpleName()).setExMsg(e.getMessage());
handleLog(joinPoint, logDto);
}
private LogDto getLog(){
LogDto log = new LogDto();
HttpServletRequest request = RequestHolder.getHttpServletRequest();
log.setUserId(SecurityUtil.getUserId());
log.setUserName(SecurityUtil.getUserName());
log.setRemoteAddr(ServletUtil.getClientIP(request));
log.setRequestUri(URLUtil.getPath(request.getRequestURI()));
UserAgent ua = UserAgentUtil.parse(request.getHeader("User-Agent"));
log.setBrowser(ua.getBrowser().toString());
log.setOs(ua.getOs().toString());
log.setParams(HttpUtil.toParams(request.getParameterMap()));
return log;
}
protected void handleLog(final JoinPoint joinPoint, final Exception e) {
try {
// 获得注解
LogAop logAop = getAnnotationLog(joinPoint);
if(logAop == null) {
return;
}
// 设置方法名称
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
log.info("[类名]:{},[方法]:{},[模块]:{},[描述]:{}", className, methodName, logAop.module(), logAop.value());
// 异步保存数据库
asyncTask.doTask();
} catch (Exception exp) {
log.error("前置通知异常信息:{}", exp.getMessage(), exp);
protected void handleLog(final JoinPoint joinPoint, LogDto logDto) {
// 获得注解
LogAop logAop = getAnnotationLog(joinPoint);
if(null == logAop) {
return;
}
// 设置方法名称
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
logDto.setModule(logAop.module()).setTitle(logAop.value())
.setClassName(className).setMethodName(methodName);
log.info("[类名]:{},[方法]:{},[模块]:{},[描述]:{}", className, methodName, logAop.module(), logAop.value());
// 异步保存数据库
asyncTask.doTask(logDto);
}
/**
* 是否存在注解,如果存在就获取
*/
private LogAop getAnnotationLog(JoinPoint joinPoint) throws Exception {
private LogAop getAnnotationLog(JoinPoint joinPoint) {
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
......
package cn.datax.common.log.async;
import cn.datax.service.system.api.dto.LogDto;
import cn.datax.service.system.api.feign.LogServiceFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
......@@ -8,16 +11,16 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
public class AsyncTask {
@Autowired
private LogServiceFeign logServiceFeign;
@Async("dataLogExecutor")
public void doTask() {
public void doTask(LogDto logDto) {
log.info("开始做任务--模拟日志");
long start = System.currentTimeMillis();
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
log.info("日志体{}", logDto.toString());
logServiceFeign.saveLog(logDto);
long end = System.currentTimeMillis();
log.info("完成任务,耗时:" + (end - start) + "毫秒");
}
......
......@@ -11,11 +11,15 @@ import org.springframework.context.annotation.Import;
* @since 2019/10/30
*/
@ComponentScan({"cn.datax.common.log"})
@Import({LogAsyncConfig.class})
public class AutoConfiguration {
@Bean
public LogAspect logAspect() {
return new LogAspect();
}
@Bean
public LogAsyncConfig logAsyncConfig() {
return new LogAsyncConfig();
}
}
......@@ -11,23 +11,69 @@ public class DataMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.setInsertFieldValByName("createTime", LocalDateTime.now(), metaObject);
this.setInsertFieldValByName("updateTime", LocalDateTime.now(), metaObject);
this.setInsertFieldValByName("status", 1, metaObject);
boolean bolCreateTime = metaObject.hasSetter("createTime");
Object createdTime = getFieldValByName("createdTime", metaObject);
if(bolCreateTime){
if (null == createdTime) {
this.setInsertFieldValByName("createTime", LocalDateTime.now(), metaObject);
}
}
boolean bolUpdateTime = metaObject.hasSetter("updateTime");
Object updateTime = getFieldValByName("updateTime", metaObject);
if(bolUpdateTime){
if (null == updateTime) {
this.setInsertFieldValByName("updateTime", LocalDateTime.now(), metaObject);
}
}
boolean bolStatus = metaObject.hasSetter("status");
Object status = getFieldValByName("status", metaObject);
if(bolStatus){
if (null == status) {
this.setInsertFieldValByName("status", 1, metaObject);
}
}
String userId = getUserId();
if(StrUtil.isNotBlank(userId)){
this.setInsertFieldValByName("createBy", userId, metaObject);
this.setInsertFieldValByName("updateBy", userId, metaObject);
boolean bolCreateBy = metaObject.hasSetter("createBy");
Object createBy = getFieldValByName("createBy", metaObject);
if(bolCreateBy) {
if (null == createBy) {
this.setInsertFieldValByName("createBy", userId, metaObject);
}
}
boolean bolUpdateBy = metaObject.hasSetter("updateBy");
Object updateBy = getFieldValByName("updateBy", metaObject);
if(bolUpdateBy) {
if (null == updateBy) {
this.setInsertFieldValByName("updateBy", userId, metaObject);
}
}
}
}
@Override
public void updateFill(MetaObject metaObject) {
this.setUpdateFieldValByName("updateTime", LocalDateTime.now(), metaObject);
boolean bolUpdateTime = metaObject.hasSetter("updateTime");
Object updateTime = getFieldValByName("updateTime", metaObject);
if(bolUpdateTime){
if (null == updateTime) {
this.setUpdateFieldValByName("updateTime", LocalDateTime.now(), metaObject);
}
}
String userId = getUserId();
if(StrUtil.isNotBlank(userId)){
this.setInsertFieldValByName("updateBy", userId, metaObject);
boolean bolUpdateBy = metaObject.hasSetter("updateBy");
Object updateBy = getFieldValByName("updateBy", metaObject);
if(bolUpdateBy) {
if (null == updateBy) {
this.setUpdateFieldValByName("updateBy", userId, metaObject);
}
}
}
}
......
package cn.datax.service.system.api.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
@ApiModel(value = "日志Model")
@Data
@Accessors(chain = true)
public class LogDto implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "主键ID")
private String id;
@ApiModelProperty(value = "所属模块")
private String module;
@ApiModelProperty(value = "日志标题")
private String title;
@ApiModelProperty(value = "用户ID")
private String userId;
@ApiModelProperty(value = "用户名称")
private String userName;
@ApiModelProperty(value = "请求IP")
private String remoteAddr;
@ApiModelProperty(value = "请求URI")
private String requestUri;
@ApiModelProperty(value = "方法类名")
private String className;
@ApiModelProperty(value = "方法名称")
private String methodName;
@ApiModelProperty(value = "请求参数")
private String params;
@ApiModelProperty(value = "请求耗时")
private String time;
@ApiModelProperty(value = "浏览器名称")
private String browser;
@ApiModelProperty(value = "操作系统")
private String os;
@ApiModelProperty(value = "错误类型")
private String exCode;
@ApiModelProperty(value = "错误信息")
private String exMsg;
}
package cn.datax.service.system.api.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
*
* </p>
*
* @author yuwei
* @since 2019-09-11
*/
@Data
@Accessors(chain = true)
@TableName("sys_log")
public class LogEntity implements Serializable {
private static final long serialVersionUID=1L;
/**
* 主键
*/
@TableId(value = "id", type = IdType.ID_WORKER_STR)
private String id;
/**
* 所属模块
*/
private String module;
/**
* 日志标题
*/
private String title;
/**
* 用户ID
*/
private String userId;
/**
* 用户名称
*/
private String userName;
/**
* 请求IP
*/
private String remoteAddr;
/**
* 请求URI
*/
private String requestUri;
/**
* 方法类名
*/
private String className;
/**
* 方法名称
*/
private String methodName;
/**
* 请求参数
*/
private String params;
/**
* 请求耗时
*/
private String time;
/**
* 浏览器名称
*/
private String browser;
/**
* 操作系统
*/
private String os;
/**
* 错误类型
*/
private String exCode;
/**
* 错误信息
*/
private String exMsg;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@TableField(value = "create_time", fill = FieldFill.INSERT)
private LocalDateTime createTime;
}
package cn.datax.service.system.api.feign;
import cn.datax.common.core.R;
import cn.datax.service.system.api.dto.LogDto;
import cn.datax.service.system.api.feign.factory.LogServiceFeignFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@FeignClient(contextId = "logServiceFeign", value = "datax-service-system", fallbackFactory = LogServiceFeignFallbackFactory.class)
public interface LogServiceFeign {
@PostMapping("/logs")
R saveLog(@RequestBody LogDto logDto);
}
package cn.datax.service.system.api.feign.factory;
import cn.datax.service.system.api.feign.LogServiceFeign;
import cn.datax.service.system.api.feign.fallback.LogServiceFeignFallbackImpl;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;
@Component
public class LogServiceFeignFallbackFactory implements FallbackFactory<LogServiceFeign> {
@Override
public LogServiceFeign create(Throwable throwable) {
return new LogServiceFeignFallbackImpl(throwable);
}
}
package cn.datax.service.system.api.feign.fallback;
import cn.datax.common.core.R;
import cn.datax.service.system.api.dto.LogDto;
import cn.datax.service.system.api.feign.LogServiceFeign;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@AllArgsConstructor
public class LogServiceFeignFallbackImpl implements LogServiceFeign {
private final Throwable cause;
@Override
public R saveLog(LogDto logDto) {
log.error("feign 调用出错,信息:{}", cause.getLocalizedMessage());
return null;
}
}
package cn.datax.service.system.api.vo;
import lombok.Data;
import java.io.Serializable;
@Data
public class LogVo implements Serializable {
private static final long serialVersionUID=1L;
private String id;
private String module;
private String title;
private String userId;
private String userName;
private String remoteAddr;
private String requestUri;
private String className;
private String methodName;
private String params;
private String time;
private String browser;
private String os;
private String exCode;
private String exMsg;
}
package cn.datax.service.system.controller;
import cn.datax.common.base.BaseController;
import cn.datax.common.core.R;
import cn.datax.service.system.api.dto.LogDto;
import cn.datax.service.system.api.entity.LogEntity;
import cn.datax.service.system.service.LogService;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* <p>
* 前端控制器
* </p>
*
* @author yuwei
* @since 2019-09-04
*/
@Api(value="系统管理接口", tags = {"系统管理"})
@RestController
@RequestMapping("/logs")
public class LogController extends BaseController {
@Autowired
private LogService logService;
@ApiOperation(value = "创建日志", notes = "根据log对象创建日志")
@ApiImplicitParam(name = "log", value = "日志详细实体log", required = true, dataType = "logDto")
@PostMapping()
public R saveLog(@RequestBody LogDto log) {
logService.saveLog(log);
return R.ok();
}
@ApiOperation(value = "日志分页查询", notes = "")
@ApiImplicitParams({
@ApiImplicitParam(name = "pageNum", value = "当前页码", required = true, dataType = "int", example = "1"),
@ApiImplicitParam(name = "pageSize", value = "分页条数", required = true, dataType = "int", example = "20"),
@ApiImplicitParam(name = "log", value = "日志详细实体log", required = false, dataTypeClass = LogDto.class)
})
@GetMapping("/page")
public R getPostPage(@RequestParam(value="pageNum", defaultValue="1") Integer pageNum,
@RequestParam(value="pageSize", defaultValue="20") Integer pageSize,
LogDto log) {
QueryWrapper<LogEntity> queryWrapper = Wrappers.emptyWrapper();
queryWrapper.like(StrUtil.isNotBlank(log.getTitle()), "title", log.getTitle());
IPage<LogEntity> page = logService.page(new Page<>(pageNum, pageSize), queryWrapper);
return R.ok().setData(page);
}
}
package cn.datax.service.system.controller;
import cn.datax.common.core.R;
import cn.datax.common.log.annotation.LogAop;
import cn.datax.common.validate.ValidateGroupForSave;
import cn.datax.common.validate.ValidateGroupForUpdate;
import cn.datax.service.system.api.dto.UserDto;
......@@ -45,6 +46,7 @@ public class UserController extends BaseController {
@Autowired
private UserMapper userMapper;
@LogAop(module = "datax-service-system", value = "根据id获取用户详细信息")
@ApiOperation(value = "获取用户详细信息", notes = "根据url的id来获取用户详细信息")
@ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "String", paramType = "path")
@GetMapping("/{id}")
......
package cn.datax.service.system.dao;
import cn.datax.common.base.BaseDao;
import cn.datax.service.system.api.entity.LogEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author yuwei
* @since 2019-11-19
*/
@Mapper
public interface LogDao extends BaseDao<LogEntity> {
}
package cn.datax.service.system.mapstruct;
import cn.datax.common.mapstruct.EntityMapper;
import cn.datax.service.system.api.dto.LogDto;
import cn.datax.service.system.api.entity.LogEntity;
import cn.datax.service.system.api.vo.LogVo;
import org.mapstruct.Mapper;
@Mapper(componentModel = "spring")
public interface LogMapper extends EntityMapper<LogDto, LogEntity, LogVo> {
}
package cn.datax.service.system.service;
import cn.datax.common.base.BaseService;
import cn.datax.service.system.api.dto.LogDto;
import cn.datax.service.system.api.entity.LogEntity;
/**
* <p>
* 服务类
* </p>
*
* @author yuwei
* @since 2019-11-19
*/
public interface LogService extends BaseService<LogEntity> {
void saveLog(LogDto log);
}
package cn.datax.service.system.service.impl;
import cn.datax.service.system.api.dto.LogDto;
import cn.datax.service.system.api.entity.LogEntity;
import cn.datax.service.system.dao.LogDao;
import cn.datax.service.system.mapstruct.LogMapper;
import cn.datax.service.system.service.LogService;
import cn.datax.common.base.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
* <p>
* 服务实现类
* </p>
*
* @author yuwei
* @since 2019-11-19
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class LogServiceImpl extends BaseServiceImpl<LogDao, LogEntity> implements LogService {
@Autowired
private LogDao logDao;
@Autowired
private LogMapper logMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public void saveLog(LogDto logDto) {
LogEntity log = logMapper.toEntity(logDto);
logDao.insert(log);
}
}
<?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.datax.service.system.dao.LogDao">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.datax.service.system.api.entity.LogEntity">
<result column="id" property="id" />
<result column="create_time" property="createTime" />
<result column="module" property="module" />
<result column="title" property="title" />
<result column="user_id" property="userId" />
<result column="user_name" property="userName" />
<result column="remote_addr" property="remoteAddr" />
<result column="request_uri" property="requestUri" />
<result column="class_name" property="className" />
<result column="method_name" property="methodName" />
<result column="params" property="params" />
<result column="time" property="time" />
<result column="browser" property="browser" />
<result column="os" property="os" />
<result column="ex_code" property="exCode" />
<result column="ex_msg" property="exMsg" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
create_time,
module, title, user_id, user_name, remote_addr, request_uri, class_name, method_name, params, time, browser, os, ex_code, ex_msg
</sql>
</mapper>
......@@ -123,8 +123,8 @@ public class CodeGenerator {
strategy.setSuperMapperClass("cn.datax.common.base.BaseDao");
strategy.setControllerMappingHyphenStyle(true);
strategy.setTablePrefix("sys_");
strategy.setInclude(new String[]{"sys_user", "sys_role", "sys_dept", "sys_menu", "sys_post", "sys_user_role", "sys_user_dept", "sys_user_post", "sys_role_menu"});
// strategy.setInclude(new String[]{"tbl_file"});
// strategy.setInclude(new String[]{"sys_user", "sys_role", "sys_dept", "sys_menu", "sys_post", "sys_user_role", "sys_user_dept", "sys_user_post", "sys_role_menu"});
strategy.setInclude(new String[]{"sys_log"});
mpg.setStrategy(strategy);
mpg.setTemplateEngine(new VelocityTemplateEngine());
mpg.execute();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment