Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
172151295 opened this issue Jul 3, 2023 · 7 comments

Comments

@172151295
Copy link

No description provided.

@172151295 172151295 changed the title 希望新增菜单管理、角色管理、登陆日志、操作日志功能 [建议]希望新增菜单管理、角色管理、登陆日志、操作日志功能 Jul 3, 2023
@xinzhuxiansheng
Copy link
Contributor

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

@172151295
Copy link
Author

OK

@172151295
Copy link
Author

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

其他的来?

@xinzhuxiansheng
Copy link
Contributor

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,或者我表达的不够详细,我可再补充

@stelin
Copy link
Member

stelin commented Aug 12, 2023

@xinzhuxiansheng nice

@172151295
Copy link
Author

66666666666666

@172151295
Copy link
Author

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,或者我表达的不够详细,我可再补充

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants