open-job/openjob

[建议]希望新增菜单管理、角色管理、登陆日志、操作日志功能

Opened this issue · 7 comments

[建议]希望新增菜单管理、角色管理、登陆日志、操作日志功能

@stelin hi,“登录日志”,“操作日志” 两个功能,我认领下,后续会贴出设计文档。 :)

OK

@stelin hi,“登录日志”,“操作日志” 两个功能,我认领下,后续会贴出设计文档。 :)

其他的来?

1. 增加一个菜单 “审计日志”

包含2个子菜单:

“登录日志”
“操作日志”

登录日志

表结构login_log 主要包含以下字段
id
user_name
createtime

直接入库即可。

操作日志

表结构 operator_log 主要包含以下字段
id
user_name
createtime
module_type 业务模块 例如 命名空间
operator_type 操作类型 例如 增删改查
bizNo 业务编号
summary 该要: 例如 用户「openjob」新增了新的命名空间「namespace01」

这里并没有使用 AOP,而直接在 Controller 或者server 添加以下方法 完成 写入。

    @PostMapping(value = "/hello")
    public String hello(@RequestBody User user) {
        logger.info("request hello params {} , {}", user.getUserId(), user.getName());

        LogEntry.build()
                .moduleType(ModuleType.NAMESPACE)
                .bizNo("1")
                .user(user)
                .createTime(System.currentTimeMillis())
                .summaryTemplate(NamespaceLogTemplate.CREATE)
                .param("username","yzhou")
                .param("id","1")
                .save();

        return "OK";
    }

整体结构如下
图片

ILogTemplate枚举以及子类,主要通过 summaryTemplate,param 定义 来拼接 summary 字段值, 例如:
图片

summary 拼接 利用 param 传入的参数名,做自动替换

    @Override
    public String format(Map<String, Object> params) {
        String result = template;
        if (isEmpty(params)) {
            return result;
        }
        StringSubstitutor sub = new StringSubstitutor(params, "%(", ")");
        return sub.replace(result);
    }

定义了 LogStrategy 接口,主要通过策略模式,在区分不同子模块的子查询, 例如可能需要根据 不同id 查询后 得到一些值。为了减少 switch使用,导致代码可读性差,所以,单独每个模块 实现自己的save()方法,当然这里也可直接使用 deafult()方法。

若后期开发,针对不同模块 ,仅仅只需定义 xxxxLogTemplate ,xxxxLogStrategy 即可,

LogEntry:

package com.yzhou.logrecord.log03;

import com.yzhou.logrecord.log03.namespace.NamespaceLogStrategy;
import com.yzhou.logrecord.modal.User;
import lombok.Getter;

import java.util.HashMap;
import java.util.Map;

@Getter
public class LogEntry {
    private String bizNo; // 业务ID
    private User user; // 用户信息
    private long createTime; // 创建时间
    private ModuleType moduleType; // 模块
    private ILogTemplate summaryTemplate; // 描述模板
    private LogStrategy logStrategy;
    private Map<String, Object> params = new HashMap<>(); // 模板参数


    public static LogEntry build() {
        return new LogEntry();
    }

    public LogEntry bizNo(String bizNo) {
        this.bizNo = bizNo;
        return this;
    }

    public LogEntry user(User user) {
        this.user = user;
        return this;
    }

    public LogEntry createTime(long createTime) {
        this.createTime = createTime;
        return this;
    }

    public LogEntry summaryTemplate(ILogTemplate summaryTemplate) {
        this.summaryTemplate = summaryTemplate;
        return this;
    }

    public LogEntry param(String key, String value) {
        params.put(key, value);
        return this;
    }


    public LogEntry moduleType(ModuleType moduleType) {
        switch (moduleType.name()) {
            case "NAMESPACE":
                this.logStrategy = new NamespaceLogStrategy();
                break;
            default:
                throw new IllegalArgumentException("Unknown targetType: " + moduleType.name());
        }
        return this;
    }

    public ILogTemplate getSummaryTemplate(){
        return summaryTemplate;
    }
    
    public void save() {
        if (logStrategy == null) {
            System.out.println("aaaa");
        }
        logStrategy.save(this);
    }

}

@stelin 还麻烦看下,是否OK,或者我表达的不够详细,我可再补充

66666666666666

1. 增加一个菜单 “审计日志”

包含2个子菜单:

“登录日志”
“操作日志”

登录日志

表结构login_log 主要包含以下字段
id
user_name
createtime

直接入库即可。

操作日志

表结构 operator_log 主要包含以下字段
id
user_name
createtime
module_type 业务模块 例如 命名空间
operator_type 操作类型 例如 增删改查
bizNo 业务编号
summary 该要: 例如 用户「openjob」新增了新的命名空间「namespace01」

这里并没有使用 AOP,而直接在 Controller 或者server 添加以下方法 完成 写入。

    @PostMapping(value = "/hello")
    public String hello(@RequestBody User user) {
        logger.info("request hello params {} , {}", user.getUserId(), user.getName());

        LogEntry.build()
                .moduleType(ModuleType.NAMESPACE)
                .bizNo("1")
                .user(user)
                .createTime(System.currentTimeMillis())
                .summaryTemplate(NamespaceLogTemplate.CREATE)
                .param("username","yzhou")
                .param("id","1")
                .save();

        return "OK";
    }

整体结构如下
图片

ILogTemplate枚举以及子类,主要通过 summaryTemplate,param 定义 来拼接 summary 字段值, 例如:
图片

summary 拼接 利用 param 传入的参数名,做自动替换

    @Override
    public String format(Map<String, Object> params) {
        String result = template;
        if (isEmpty(params)) {
            return result;
        }
        StringSubstitutor sub = new StringSubstitutor(params, "%(", ")");
        return sub.replace(result);
    }

定义了 LogStrategy 接口,主要通过策略模式,在区分不同子模块的子查询, 例如可能需要根据 不同id 查询后 得到一些值。为了减少 switch使用,导致代码可读性差,所以,单独每个模块 实现自己的save()方法,当然这里也可直接使用 deafult()方法。

若后期开发,针对不同模块 ,仅仅只需定义 xxxxLogTemplate ,xxxxLogStrategy 即可,

LogEntry:

package com.yzhou.logrecord.log03;

import com.yzhou.logrecord.log03.namespace.NamespaceLogStrategy;
import com.yzhou.logrecord.modal.User;
import lombok.Getter;

import java.util.HashMap;
import java.util.Map;

@Getter
public class LogEntry {
    private String bizNo; // 业务ID
    private User user; // 用户信息
    private long createTime; // 创建时间
    private ModuleType moduleType; // 模块
    private ILogTemplate summaryTemplate; // 描述模板
    private LogStrategy logStrategy;
    private Map<String, Object> params = new HashMap<>(); // 模板参数


    public static LogEntry build() {
        return new LogEntry();
    }

    public LogEntry bizNo(String bizNo) {
        this.bizNo = bizNo;
        return this;
    }

    public LogEntry user(User user) {
        this.user = user;
        return this;
    }

    public LogEntry createTime(long createTime) {
        this.createTime = createTime;
        return this;
    }

    public LogEntry summaryTemplate(ILogTemplate summaryTemplate) {
        this.summaryTemplate = summaryTemplate;
        return this;
    }

    public LogEntry param(String key, String value) {
        params.put(key, value);
        return this;
    }


    public LogEntry moduleType(ModuleType moduleType) {
        switch (moduleType.name()) {
            case "NAMESPACE":
                this.logStrategy = new NamespaceLogStrategy();
                break;
            default:
                throw new IllegalArgumentException("Unknown targetType: " + moduleType.name());
        }
        return this;
    }

    public ILogTemplate getSummaryTemplate(){
        return summaryTemplate;
    }
    
    public void save() {
        if (logStrategy == null) {
            System.out.println("aaaa");
        }
        logStrategy.save(this);
    }

}

@stelin 还麻烦看下,是否OK,或者我表达的不够详细,我可再补充

无网络环境无图标问题你能帮忙修复一下吗?