package model import ( "bytes" "encoding/base64" "encoding/json" "github.com/loveuer/nfflow/internal/interfaces" "github.com/loveuer/nfflow/internal/sqlType" "github.com/spf13/cast" "github.com/tdewolff/minify/v2" "github.com/tdewolff/minify/v2/html" "html/template" "time" ) var ( FuncMap = template.FuncMap{ "time_format": func(mil any, format string) string { return time.UnixMilli(cast.ToInt64(mil)).Format(format) }, } ) var ( _ interfaces.OpLogger = OpLogType(0) ) type OpLogType uint64 const ( OpLogTypeLogin OpLogType = iota + 1 OpLogTypeLogout OpLogTypeCreateUser OpLogTypeUpdateUser OpLogTypeDeleteUser // todo: 添加自己的操作日志 分类 ) func (o OpLogType) Value() int64 { return int64(o) } func (o OpLogType) Code() string { switch o { case OpLogTypeLogin: return "login" case OpLogTypeLogout: return "logout" case OpLogTypeCreateUser: return "create_user" case OpLogTypeUpdateUser: return "update_user" case OpLogTypeDeleteUser: return "delete_user" default: return "unknown" } } func (o OpLogType) Label() string { switch o { case OpLogTypeLogin: return "登入" case OpLogTypeLogout: return "登出" case OpLogTypeCreateUser: return "创建用户" case OpLogTypeUpdateUser: return "修改用户" case OpLogTypeDeleteUser: return "删除用户" default: return "未知" } } func (o OpLogType) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]any{ "value": o.Value(), "code": o.Code(), "label": o.Label(), }) } func (o OpLogType) All() []interfaces.Enum { return []interfaces.Enum{ OpLogTypeLogin, OpLogTypeLogout, OpLogTypeCreateUser, OpLogTypeUpdateUser, OpLogTypeDeleteUser, } } func _trimHTML(v []byte) string { //if len(v) == 0 { // return "" //} // //bs := make([]byte, 0, len(v)) // //for _, b := range v { // if b == '\t' || b == '\n' { // continue // } // // bs = append(bs, b) //} return base64.StdEncoding.EncodeToString(v) //return string(bs) } var ( _mini = minify.New() ) func init() { _mini.AddFunc("text/html", html.Minify) } func (o OpLogType) Render(content map[string]any) (string, error) { var ( err error render *template.Template buf bytes.Buffer bs []byte ) if render, err = template.New(o.Code()). Funcs(FuncMap). Parse(o.Template()); err != nil { return "", err } if err = render.Execute(&buf, content); err != nil { return "", err } if bs, err = _mini.Bytes("text/html", buf.Bytes()); err != nil { return "", err } //return string(bs), nil return _trimHTML(bs), nil } const ( oplogTemplateLogin = `
用户 {{ .username }} {{ time_format .time "2006-01-02 15:04:05" }} {{ .ip }} 登入 了系统
` oplogTemplateLogout = `
用户 {{ .username }} {{ time_format .time "2006-01-02 15:04:05" }} {{ .ip }} 登出 了系统
` oplogTemplateCreateUser = `
用户 {{ .username }} {{ time_format .time "2006-01-02 15:04:05" }} 创建 了用户 {{ .target_username }}
` oplogTemplateUpdateUser = `
用户 {{ .username }} {{ time_format .time "2006-01-02 15:04:05" }} 编辑 了用户 {{ .target_username }}
` oplogTemplateDeleteUser = `
用户 {{ .username }} {{ time_format .time "2006-01-02 15:04:05" }} 删除 了用户 {{ .target_username }}
` ) func (o OpLogType) Template() string { switch o { case OpLogTypeLogin: return oplogTemplateLogin case OpLogTypeLogout: return oplogTemplateLogout case OpLogTypeCreateUser: return oplogTemplateCreateUser case OpLogTypeUpdateUser: return oplogTemplateUpdateUser case OpLogTypeDeleteUser: return oplogTemplateDeleteUser default: return `
错误的日志类型
` } } type OpLog struct { Id uint64 `json:"id" gorm:"primaryKey;column:id"` CreatedAt int64 `json:"created_at" gorm:"column:created_at;autoCreateTime:milli"` UpdatedAt int64 `json:"updated_at" gorm:"column:updated_at;autoUpdateTime:milli"` DeletedAt int64 `json:"deleted_at" gorm:"index;column:deleted_at;default:0"` UserId uint64 `json:"user_id" gorm:"column:user_id"` Username string `json:"username" gorm:"column:username;varchar(128)"` Type OpLogType `json:"type" gorm:"column:type;type:varchar(128)"` Content sqlType.JSONB `json:"content" gorm:"column:content;type:jsonb"` HTML string `json:"html" gorm:"-"` }