This commit is contained in:
2025-04-14 15:28:51 +08:00
parent f100427f8b
commit 371b89ee8d
93 changed files with 3757 additions and 1038 deletions

View File

@@ -87,6 +87,6 @@ func setPostgreSQLDefaults(opts *PostgreSQLOptions) {
opts.MaxConnectionLifeTime = time.Duration(10) * time.Second
}
if opts.Logger == nil {
opts.Logger = logger.Default
opts.Logger = logger.Default.LogMode(logger.Info)
}
}

View File

@@ -3,13 +3,9 @@ package middleware
import (
"context"
"net/http"
"strconv"
"strings"
"time"
db "management/internal/db/sqlc"
"github.com/zhang2092/browser"
systemmodel "management/internal/erpserver/model/system"
)
func (m *middleware) Audit(next http.Handler) http.Handler {
@@ -27,47 +23,11 @@ func (m *middleware) Audit(next http.Handler) http.Handler {
func (m *middleware) writeLog(req *http.Request, start time.Time) {
end := time.Now()
duration := end.Sub(start)
var params string
method := req.Method
if method == "GET" {
params = req.URL.Query().Encode()
} else if method == "POST" {
contentType := req.Header.Get("Content-Type")
if strings.Contains(contentType, "application/json") {
body := make([]byte, req.ContentLength)
req.Body.Read(body)
params = string(body)
} else if strings.Contains(contentType, "application/x-www-form-urlencoded") {
params = req.Form.Encode()
}
}
ctx := req.Context()
au := m.AuthUser(ctx)
arg := &db.CreateSysAuditLogParams{
CreatedAt: time.Now(),
Email: au.Email,
Username: au.Username,
UserUuid: au.Uuid,
StartAt: start,
EndAt: end,
Duration: strconv.FormatInt(duration.Milliseconds(), 10),
Url: req.URL.RequestURI(),
Method: method,
Parameters: params,
RefererUrl: req.Header.Get("Referer"),
Ip: req.RemoteAddr,
Remark: "",
}
br, err := browser.NewBrowser(req.Header.Get("User-Agent"))
if err == nil {
arg.Os = br.Platform().Name()
arg.Browser = br.Name()
}
user := m.AuthUser(req.Context())
al := systemmodel.NewAuditLog(req, user.Email, user.OS, user.Browser, start, end)
c, cancel := context.WithTimeout(context.Background(), time.Second*3)
defer cancel()
_ = m.biz.AuditBiz().Create(c, arg)
_ = m.auditLogsvc.Create(c, al)
}

View File

@@ -42,7 +42,7 @@ func (m *middleware) Authorize(next http.Handler) http.Handler {
return
}
menus, err := m.biz.MenuBiz().MapOwnerMenuByRoleID(ctx, user.RoleID)
menus, err := m.menusvc.ListByRoleIDToMap(ctx, user.RoleID)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -80,3 +80,23 @@ func (m *middleware) AuthUser(ctx context.Context) dto.AuthorizeUser {
}
return user
}
func (m *middleware) IsAuth(ctx context.Context) bool {
var user dto.AuthorizeUser
b := m.session.GetBytes(ctx, know.StoreName)
if err := json.Unmarshal(b, &user); err == nil {
return true
}
return false
}
func (m *middleware) RefreshToken(ctx context.Context) bool {
if err := m.session.RenewToken(ctx); err == nil {
return true
}
return false
}
func (m *middleware) Destroy(ctx context.Context) error {
return m.session.Destroy(ctx)
}

View File

@@ -5,28 +5,33 @@ import (
"net/http"
"management/internal/db/model/dto"
systemv1 "management/internal/erpserver/biz/v1/system"
v1 "management/internal/erpserver/service/v1"
"management/internal/pkg/session"
)
type IMiddleware interface {
type Middleware interface {
Audit(next http.Handler) http.Handler
NoSurf(next http.Handler) http.Handler
LoadSession(next http.Handler) http.Handler
Authorize(next http.Handler) http.Handler
AuthUser(ctx context.Context) dto.AuthorizeUser
IsAuth(ctx context.Context) bool
RefreshToken(ctx context.Context) bool
Destroy(ctx context.Context) error
}
type middleware struct {
biz systemv1.SystemBiz
session session.ISession
session session.Session
menusvc v1.MenuService
auditLogsvc v1.AuditLogService
}
var _ IMiddleware = (*middleware)(nil)
var _ Middleware = (*middleware)(nil)
func New(biz systemv1.SystemBiz, session session.ISession) IMiddleware {
func New(session session.Session, menusvc v1.MenuService, auditLogsvc v1.AuditLogService) Middleware {
return &middleware{
biz: biz,
session: session,
session: session,
menusvc: menusvc,
auditLogsvc: auditLogsvc,
}
}

View File

@@ -15,7 +15,7 @@ import (
var ErrRedisKeyNotFound = errors.New("redis key not found")
type IRedis interface {
type RedisCache interface {
Encode(a any) ([]byte, error)
Set(ctx context.Context, key string, value interface{}, expiration time.Duration) error
Del(ctx context.Context, keys ...string) error
@@ -30,7 +30,7 @@ type redisCache struct {
engine *redis.Client
}
var _ IRedis = (*redisCache)(nil)
var _ RedisCache = (*redisCache)(nil)
func New(conf config.Redis) (*redisCache, error) {
rdb := redis.NewClient(&redis.Options{

View File

@@ -2,15 +2,15 @@ package session
import (
"context"
"database/sql"
"net/http"
"time"
"github.com/alexedwards/scs/pgxstore"
"github.com/alexedwards/scs/postgresstore"
"github.com/alexedwards/scs/v2"
"github.com/jackc/pgx/v5/pgxpool"
)
type ISession interface {
type Session interface {
Destroy(ctx context.Context) error
LoadAndSave(next http.Handler) http.Handler
Put(ctx context.Context, key string, val any)
@@ -23,7 +23,7 @@ type session struct {
sessionManager *scs.SessionManager
}
func New(pool *pgxpool.Pool, prod bool) ISession {
func New(db *sql.DB, prod bool) Session {
sessionManager := scs.New()
sessionManager.Lifetime = 24 * time.Hour
sessionManager.IdleTimeout = 2 * time.Hour
@@ -35,10 +35,10 @@ func New(pool *pgxpool.Pool, prod bool) ISession {
// postgres
// github.com/alexedwards/scs/postgresstore
// sessionManager.Store = postgresstore.New(db)
sessionManager.Store = postgresstore.New(db)
// pgx
// github.com/alexedwards/scs/pgxstore
sessionManager.Store = pgxstore.New(pool)
// sessionManager.Store = pgxstore.New(pool)
// redis
// sessionManager.Store = newRedisStore()

View File

@@ -4,7 +4,7 @@ import (
"html/template"
"net/http"
systemv1 "management/internal/erpserver/biz/v1/system"
v1 "management/internal/erpserver/service/v1"
"management/internal/pkg/session"
)
@@ -17,17 +17,17 @@ type Renderer interface {
}
type render struct {
session session.ISession
session session.Session
config *TemplateConfig
templates map[string]*template.Template
menuBiz systemv1.MenuBiz
menusvc v1.MenuService
}
func New(session session.ISession, menuBiz systemv1.MenuBiz) (Renderer, error) {
func New(session session.Session, menusvc v1.MenuService) (Renderer, error) {
render := &render{
session: session,
menuBiz: menuBiz,
menusvc: menusvc,
config: &TemplateConfig{
Root: ".",
Extension: ".tmpl",

View File

@@ -44,15 +44,14 @@ func (r *render) setDefaultData(req *http.Request, data map[string]any) map[stri
func (r *render) getCurrentPathBtns(ctx context.Context, roleID int32, path string) []*dto.OwnerMenuDto {
var res []*dto.OwnerMenuDto
// 获取当前path的菜单
menu, err := r.menuBiz.GetSysMenuByUrl(ctx, path)
// 获取当前登陆角色的权限
menus, err := r.menusvc.ListByRoleIDToMap(ctx, roleID)
if err != nil {
return res
}
// 获取权限
menus, err := r.menuBiz.ListOwnerMenuByRoleID(ctx, roleID)
if err != nil {
menu, ok := menus[path]
if !ok {
return res
}