Просмотр исходного кода

管理后台 记录操作日志

dengsixing 3 лет назад
Родитель
Сommit
6a8fed49dd

+ 12 - 0
4dkankan-center-manage/pom.xml

@@ -21,6 +21,12 @@
 
     <dependency>
       <groupId>com.fdkankan</groupId>
+      <artifactId>4dkankan-common-utils</artifactId>
+      <version>2.0.0-SNAPSHOT</version>
+    </dependency>
+
+    <dependency>
+      <groupId>com.fdkankan</groupId>
       <artifactId>4dkankan-utils-fyun</artifactId>
       <version>2.0.0-SNAPSHOT</version>
     </dependency>
@@ -32,6 +38,12 @@
     </dependency>
 
     <dependency>
+      <groupId>com.fdkankan</groupId>
+      <artifactId>4dkankan-utils-mongodb</artifactId>
+      <version>2.0.0-SNAPSHOT</version>
+    </dependency>
+
+    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
     </dependency>

+ 40 - 0
4dkankan-center-manage/src/main/java/com/fdkankan/manage/bean/MenuBean.java

@@ -0,0 +1,40 @@
+package com.fdkankan.manage.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * <p>
+ * 菜单类
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/5/30
+ **/
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class MenuBean {
+
+    /**
+     * 菜单id
+     */
+    private Integer id;
+
+    /**
+     * 菜单名称
+     */
+    private String name;
+
+    /**
+     * url
+     */
+    private String uri;
+
+    /*
+    父菜单
+     */
+    private MenuBean parent;
+
+}

+ 49 - 0
4dkankan-center-manage/src/main/java/com/fdkankan/manage/controller/TestController.java

@@ -1,13 +1,23 @@
 package com.fdkankan.manage.controller;
 
+import com.alibaba.fastjson.JSON;
+import com.dtflys.forest.annotation.Post;
 import com.fdkankan.common.response.ResultData;
+import com.fdkankan.manage.bean.MenuBean;
 import com.fdkankan.manage.entity.Agent;
 import com.fdkankan.manage.service.IAgentService;
+import com.fdkankan.redis.constant.RedisKey;
+import com.fdkankan.redis.util.RedisUtil;
 import java.util.List;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
+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.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
 
 /**
  * <p>
@@ -22,6 +32,9 @@ import org.springframework.web.bind.annotation.RestController;
 public class TestController {
 
     @Autowired
+    RedisUtil redisUtil;
+
+    @Autowired
     private IAgentService agentService;
 
     @GetMapping("/test")
@@ -32,5 +45,41 @@ public class TestController {
         return ResultData.ok(list.toArray());
     }
 
+    @PostMapping("/test3")
+    public ResultData test3(String num, @RequestParam("file") MultipartFile file){
+
+        List<Agent> list = agentService.list();
+
+        return ResultData.ok(list.toArray());
+    }
+
+    @PostMapping("/test1")
+    public ResultData test(@RequestBody Map<String, String> params){
+
+        List<Agent> list = agentService.list();
+
+        return ResultData.ok(list.toArray());
+    }
+
+    @GetMapping("/setMenu")
+    public ResultData test(){
+        MenuBean menuBean1 = new MenuBean();
+        menuBean1.setId(1);
+        menuBean1.setName("a");
+        menuBean1.setUri("a");
+        MenuBean menuBean2 = new MenuBean();
+        menuBean2.setId(2);
+        menuBean2.setName("b");
+        menuBean2.setUri("b");
+        menuBean2.setParent(menuBean1);
+        MenuBean menuBean3 = new MenuBean();
+        menuBean3.setId(3);
+        menuBean3.setName("c");
+        menuBean3.setUri("c");
+        menuBean3.setParent(menuBean2);
+        redisUtil.hset(RedisKey.MANAGE_MENU, "/service/manage/test", JSON.toJSONString(menuBean3));
+        return ResultData.ok();
+    }
+
 
 }

+ 67 - 0
4dkankan-center-manage/src/main/java/com/fdkankan/manage/entity/OperLog.java

@@ -0,0 +1,67 @@
+package com.fdkankan.manage.entity;
+
+import java.util.Date;
+import java.util.Map;
+import lombok.Builder;
+import lombok.Data;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+import org.springframework.data.mongodb.core.mapping.Field;
+
+/**
+ * 操作日志
+ */
+@Data
+@Document("OperLog")
+@Builder
+public class OperLog {
+
+    @Id
+    private String id;
+
+    /**
+     * 用户id
+     */
+    @Field("userId")
+    private Long userId;
+
+    /**
+     * 账号
+     */
+    @Field("userName")
+    private String userName;
+
+    /**
+     * 姓名
+     */
+    @Field("nickName")
+    private String nickName;
+
+    /**请求路径*/
+    @Field("requestPath")
+    private String requestPath;
+
+    /**请求url*/
+    @Field("uri")
+    private String uri;
+
+    /**请求方式*/
+    @Field("method")
+    private String method;
+
+    /**请求方式*/
+    @Field("params")
+    private String params;
+
+    /**请求ip*/
+    @Field("ip")
+    private String ip;
+
+    @Field("browser")
+    private String browser;
+
+    /**请求时间*/
+    @Field("requestTime")
+    private Date requestTime;
+
+}

+ 183 - 0
4dkankan-center-manage/src/main/java/com/fdkankan/manage/interceptor/VisitLogInterceptor.java

@@ -0,0 +1,183 @@
+package com.fdkankan.manage.interceptor;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.servlet.ServletUtil;
+import cn.hutool.http.ContentType;
+import cn.hutool.http.useragent.UserAgent;
+import cn.hutool.http.useragent.UserAgentUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.util.JwtUtil;
+import com.fdkankan.manage.bean.MenuBean;
+import com.fdkankan.manage.entity.OperLog;
+import com.fdkankan.redis.constant.RedisKey;
+import com.fdkankan.redis.util.RedisUtil;
+import io.jsonwebtoken.Claims;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Objects;
+import javax.servlet.http.HttpServletRequest;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.multipart.MultipartFile;
+
+@Component
+@Aspect
+@Slf4j
+public class VisitLogInterceptor {
+
+	@Autowired
+	private RedisUtil redisUtil;
+
+	@Autowired
+	private MongoTemplate mongoTemplate;
+
+	@Value("${server.servlet.context-path:null}")
+	private String contextPath;
+
+	// 切入点表达式
+	@Pointcut("execution(public * com.fdkankan.manage.controller..*.*(..))")
+	public void privilege() {
+	}
+
+	@Around("privilege()")
+	public Object around(ProceedingJoinPoint pjp) throws Throwable {
+
+		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+
+		//获取客户端ip
+		String clientIP = ServletUtil.getClientIP(request);
+
+		//获取uri
+		String uri = request.getRequestURI();
+		if(StrUtil.isNotEmpty(contextPath)){
+			uri = uri.replaceFirst(contextPath, "");
+		}
+
+		//获取请求方式
+		String method = request.getMethod();
+
+		//获取浏览器信息
+		String browser = this.getBrowser(request);
+
+		//获取参数
+		String params = this.getParams(pjp, request);
+
+		//获取操作路径
+		String requestPath = this.getRequestPath(uri);
+
+		//放行
+		Object result = pjp.proceed();
+
+		//获取用户信息 如果已登录,从token中获取用户信息,如果是登录接口,查询数据库获取用户信息
+		Map<String, Object> userInfo = this.getUserInfo(request, uri, result);
+		Long userId = (Long)userInfo.get("userId");
+		String userName = (String)userInfo.get("userName");
+		String nickName = (String)userInfo.get("nickName");
+
+		OperLog operLog = OperLog.builder()
+			.userId(userId)
+			.userName(userName)
+			.nickName(nickName)
+			.requestPath(requestPath)
+			.uri(uri)
+			.method(method)
+			.params(params)
+			.ip(clientIP)
+			.browser(browser)
+			.requestTime(Calendar.getInstance().getTime())
+			.build();
+		mongoTemplate.insert(operLog);
+
+		return result;
+	}
+
+	private String getRequestPath(String uri){
+		String hget = redisUtil.hget(RedisKey.MANAGE_MENU, uri);
+		MenuBean menuBean = JSON.parseObject(hget, MenuBean.class);
+		LinkedList<String> menuList = new LinkedList<>();
+		this.getRequestPathHandler(menuList, menuBean);
+		StringBuilder sb = new StringBuilder();
+		menuList.stream().forEach(str->sb.append("->").append(str));
+		return sb.substring(2);
+	}
+
+	private void getRequestPathHandler(LinkedList list, MenuBean menuBean){
+		list.addFirst("[" + menuBean.getName() + "]");
+		if(Objects.isNull(menuBean.getParent())){
+			return;
+		}
+		this.getRequestPathHandler(list, menuBean.getParent());
+	}
+
+	private Map<String, Object> getUserInfo(HttpServletRequest request, String uri, Object result){
+		String token = null;
+		boolean isLogin = uri.endsWith("login");
+		if(isLogin){
+			String resultStr = JSON.toJSONString(result);
+			JSONObject jsonObject = JSON.parseObject(resultStr);
+			JSONObject data = jsonObject.getJSONObject("data");
+			token = data.getString("token");
+		}else{
+			token = request.getHeader("token");
+		}
+		Claims claims = JwtUtil.parseJWT(token);
+		Integer userId = (Integer) claims.get("userId");
+		String userName = (String)claims.get("userName");
+		String nickName = (String)claims.get("nickName");
+		Map<String, Object> userInfo = new HashMap<>();
+		userInfo.put("userId", Long.valueOf(userId));
+		userInfo.put("userName", userName);
+		userInfo.put("nickName", nickName);
+		return userInfo;
+	}
+
+	private String getParams(JoinPoint pjp, HttpServletRequest request){
+
+		// 获取参数名称
+		String[] parameterNamesArgs = ((MethodSignature) pjp.getSignature()).getParameterNames();
+		//获取请求参数值
+		Object[] args = pjp.getArgs();
+
+		Map<String, Object> paramMap = new HashMap<>();
+		String contentType = request.getContentType();
+		if(ContentType.JSON.getValue().equals(contentType)){
+			Arrays.stream(args).forEach(arg->paramMap.putAll((Map)arg));
+			return JSON.toJSONString(paramMap);
+		}else{
+			for (int i = 0; i < args.length; i++) {
+				if(args[i] instanceof MultipartFile){
+					paramMap.put(parameterNamesArgs[i], ((MultipartFile) args[i]).getOriginalFilename());
+					continue;
+				}
+				paramMap.put(parameterNamesArgs[i], args[i]);
+			}
+		}
+		return JSON.toJSONString(paramMap);
+	}
+
+	private String getBrowser(HttpServletRequest request){
+		String userAgentStr = request.getHeader("User-Agent");
+		UserAgent userAgent = UserAgentUtil.parse(userAgentStr);
+		String browserType = userAgent.getBrowser().toString();
+		String browserVersion = userAgent.getVersion();
+		String browserFormat =  "%s(版本%s)";
+		return  String.format(browserFormat, browserType, browserVersion);
+	}
+
+}
+

+ 4 - 0
4dkankan-center-manage/src/main/resources/bootstrap-test.yml

@@ -27,6 +27,10 @@ spring:
           - data-id: common-upload-config.yaml
             group: DEFAULT_GROUP
             refresh: true
+
+          - data-id: common-mongodb-config.yaml
+            group: DEFAULT_GROUP
+            refresh: true
       discovery:
         server-addr: 120.24.144.164:8848
         namespace: 4dkankan-test