This commit is contained in:
parent
a34133cce5
commit
2a3c55bb53
|
|
@ -13,6 +13,7 @@ import (
|
|||
"kra/internal/data"
|
||||
"kra/internal/server"
|
||||
"kra/internal/service"
|
||||
"kra/internal/worker"
|
||||
|
||||
"github.com/go-kratos/kratos/v3"
|
||||
"github.com/google/wire"
|
||||
|
|
@ -20,5 +21,5 @@ import (
|
|||
|
||||
// wireApp init kratos application.
|
||||
func wireApp(*conf.Server, *conf.Runtime, *slog.Logger) (*kratos.App, func(), error) {
|
||||
panic(wire.Build(server.ProviderSet, data.ProviderSet, biz.ProviderSet, service.ProviderSet, newApp))
|
||||
panic(wire.Build(server.ProviderSet, worker.ProviderSet, data.ProviderSet, biz.ProviderSet, service.ProviderSet, newApp))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ func wireApp(confServer *conf.Server, runtime *conf.Runtime, logger *slog.Logger
|
|||
apiToken := handler.NewAPIToken(tokenService)
|
||||
initializationRepo := data.NewInitializationRepo(dataData)
|
||||
systemConfigUsecase := biz.NewSystemConfigUsecase(initializationRepo, taskRuntime)
|
||||
systemConfigService := service.NewSystemConfigService(systemConfigUsecase, runtime)
|
||||
systemConfigService := service.NewSystemConfigService(systemConfigUsecase, runtimeSettings)
|
||||
securityRepo := data.NewSecurityRepo(dataData)
|
||||
securityUsecase := biz.NewSecurityUsecase(securityRepo, cache, runtimeSettings, tokenUsecase)
|
||||
securityService := service.NewSecurityService(securityUsecase)
|
||||
|
|
@ -130,7 +130,7 @@ func wireApp(confServer *conf.Server, runtime *conf.Runtime, logger *slog.Logger
|
|||
navigation := handler.NewNavigation(userService)
|
||||
session := handler.NewSession(tokenService)
|
||||
set := handler.NewSet(authority, menu, api, permission, organization, announcement, email, task, media, audit, export, version, dictionary, parameter, apiToken, systemConfig, public, user, navigation, session)
|
||||
engine := server.NewGinEngine(runtime, accessControlService, set, securityService, tokenService, auditRecorder, logger)
|
||||
engine := server.NewGinEngine(runtime, accessControlService, set, authService, securityService, auditRecorder, logger)
|
||||
httpServer := server.NewGinServer(confServer, engine)
|
||||
app := newApp(logger, httpServer, taskScheduler)
|
||||
return app, func() {
|
||||
|
|
|
|||
|
|
@ -1,160 +0,0 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type API struct {
|
||||
ID uint
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
Path string
|
||||
Description string
|
||||
APIGroup string
|
||||
Method string
|
||||
OrderKey string
|
||||
Desc bool
|
||||
StrictAll bool
|
||||
}
|
||||
|
||||
type APIRepo interface {
|
||||
CreateAPI(context.Context, *API) error
|
||||
UpdateAPI(context.Context, *API) error
|
||||
DeleteAPIs(context.Context, []uint) error
|
||||
FindAPI(context.Context, uint) (*API, error)
|
||||
ListAPIs(context.Context, int, int, *API) ([]*API, int64, error)
|
||||
APIRoleIDs(context.Context, string, string) ([]uint, error)
|
||||
SetAPIRoles(context.Context, string, string, []uint) error
|
||||
Authorize(context.Context, uint, string, string) (bool, error)
|
||||
PolicyPaths(context.Context, uint) ([]*API, error)
|
||||
SetPolicyPaths(context.Context, uint, []*API) error
|
||||
IgnoredAPIs(context.Context) ([]*API, error)
|
||||
SetAPIIgnored(context.Context, string, string, bool) error
|
||||
ApplyAPISync(context.Context, []*API, []*API) error
|
||||
}
|
||||
|
||||
type AuthorityAccessRepo interface {
|
||||
CreateAuthority(context.Context, *Authority) error
|
||||
CopyAuthority(context.Context, uint, *Authority) error
|
||||
UpdateAuthority(context.Context, *Authority) error
|
||||
DeleteAuthority(context.Context, uint) error
|
||||
ListAuthorities(context.Context) ([]*Authority, error)
|
||||
SetAuthorityUsers(context.Context, uint, []uint) error
|
||||
AuthorityUserIDs(context.Context, uint) ([]uint, error)
|
||||
SetDataScope(context.Context, uint, int, []uint) error
|
||||
DataScopeDepartmentIDs(context.Context, uint) ([]uint, error)
|
||||
ResolveDataScope(context.Context, uint, uint) (DataScope, error)
|
||||
}
|
||||
|
||||
type PermissionRepo interface {
|
||||
Buttons(context.Context, uint) ([]*MenuButton, error)
|
||||
SetAuthorityButtons(context.Context, uint, map[uint][]uint) error
|
||||
AuthorityButtonIDs(context.Context, uint) ([]uint, error)
|
||||
SelectedButtons(context.Context, uint, uint) ([]uint, error)
|
||||
SetSelectedButtons(context.Context, uint, uint, []uint) error
|
||||
CanRemoveButton(context.Context, uint) (bool, error)
|
||||
}
|
||||
|
||||
type AuthorityUsecase struct{ AuthorityAccessRepo }
|
||||
|
||||
func NewAuthorityUsecase(repo AuthorityAccessRepo) *AuthorityUsecase {
|
||||
return &AuthorityUsecase{AuthorityAccessRepo: repo}
|
||||
}
|
||||
|
||||
type APIUsecase struct{ APIRepo }
|
||||
|
||||
func NewAPIUsecase(repo APIRepo) *APIUsecase { return &APIUsecase{APIRepo: repo} }
|
||||
|
||||
type PermissionUsecase struct{ PermissionRepo }
|
||||
|
||||
func NewPermissionUsecase(repo PermissionRepo) *PermissionUsecase {
|
||||
return &PermissionUsecase{PermissionRepo: repo}
|
||||
}
|
||||
|
||||
type AccessControlUsecase struct {
|
||||
authorities AuthorityAccessRepo
|
||||
apis APIRepo
|
||||
}
|
||||
|
||||
func NewAccessControlUsecase(authorities AuthorityAccessRepo, apis APIRepo) *AccessControlUsecase {
|
||||
return &AccessControlUsecase{authorities: authorities, apis: apis}
|
||||
}
|
||||
|
||||
func (uc *AccessControlUsecase) Authorize(ctx context.Context, authorityID uint, path, method string) (bool, error) {
|
||||
if authorityID == 888 {
|
||||
return true, nil
|
||||
}
|
||||
return uc.apis.Authorize(ctx, authorityID, path, method)
|
||||
}
|
||||
|
||||
func (uc *AccessControlUsecase) ResolveDataScope(ctx context.Context, authorityID, userID uint) (DataScope, error) {
|
||||
return uc.authorities.ResolveDataScope(ctx, authorityID, userID)
|
||||
}
|
||||
|
||||
type APISyncDiff struct {
|
||||
Added []*API
|
||||
Deleted []*API
|
||||
Ignored []*API
|
||||
}
|
||||
|
||||
func (uc *APIUsecase) SyncAPIs(ctx context.Context, routes []*API) (*APISyncDiff, error) {
|
||||
stored, _, err := uc.ListAPIs(ctx, 0, 0, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ignored, err := uc.IgnoredAPIs(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key := func(value *API) string { return strings.ToUpper(value.Method) + " " + value.Path }
|
||||
ignoreSet := make(map[string]bool, len(ignored))
|
||||
for _, item := range ignored {
|
||||
ignoreSet[key(item)] = true
|
||||
}
|
||||
routeSet := make(map[string]*API, len(routes))
|
||||
for _, item := range routes {
|
||||
if !ignoreSet[key(item)] {
|
||||
routeSet[key(item)] = item
|
||||
}
|
||||
}
|
||||
storedSet := make(map[string]*API, len(stored))
|
||||
for _, item := range stored {
|
||||
storedSet[key(item)] = item
|
||||
}
|
||||
diff := &APISyncDiff{Ignored: ignored}
|
||||
for routeKey, item := range routeSet {
|
||||
if storedSet[routeKey] == nil {
|
||||
diff.Added = append(diff.Added, item)
|
||||
}
|
||||
}
|
||||
for storedKey, item := range storedSet {
|
||||
if routeSet[storedKey] == nil && !ignoreSet[storedKey] {
|
||||
diff.Deleted = append(diff.Deleted, item)
|
||||
}
|
||||
}
|
||||
return diff, nil
|
||||
}
|
||||
|
||||
func (uc *AuthorityUsecase) AuthorityTree(ctx context.Context) ([]*Authority, error) {
|
||||
items, err := uc.ListAuthorities(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
byID := make(map[uint]*Authority, len(items))
|
||||
for _, item := range items {
|
||||
item.Children = nil
|
||||
byID[item.AuthorityID] = item
|
||||
}
|
||||
roots := make([]*Authority, 0)
|
||||
for _, item := range items {
|
||||
if item.ParentID != nil && *item.ParentID != 0 && byID[*item.ParentID] != nil {
|
||||
parent := byID[*item.ParentID]
|
||||
parent.Children = append(parent.Children, item)
|
||||
} else {
|
||||
roots = append(roots, item)
|
||||
}
|
||||
}
|
||||
return roots, nil
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package biz
|
||||
|
||||
import "context"
|
||||
|
||||
type AccessControlUsecase struct {
|
||||
authorities AuthorityAccessRepo
|
||||
apis APIRepo
|
||||
}
|
||||
|
||||
func NewAccessControlUsecase(authorities AuthorityAccessRepo, apis APIRepo) *AccessControlUsecase {
|
||||
return &AccessControlUsecase{authorities: authorities, apis: apis}
|
||||
}
|
||||
|
||||
func (uc *AccessControlUsecase) Authorize(ctx context.Context, authorityID uint, path, method string) (bool, error) {
|
||||
if authorityID == 888 {
|
||||
return true, nil
|
||||
}
|
||||
return uc.apis.Authorize(ctx, authorityID, path, method)
|
||||
}
|
||||
|
||||
func (uc *AccessControlUsecase) ResolveDataScope(ctx context.Context, authorityID, userID uint) (DataScope, error) {
|
||||
return uc.authorities.ResolveDataScope(ctx, authorityID, userID)
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type API struct {
|
||||
ID uint
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
Path string
|
||||
Description string
|
||||
APIGroup string
|
||||
Method string
|
||||
OrderKey string
|
||||
Desc bool
|
||||
StrictAll bool
|
||||
}
|
||||
|
||||
type APIRepo interface {
|
||||
CreateAPI(context.Context, *API) error
|
||||
UpdateAPI(context.Context, *API) error
|
||||
DeleteAPIs(context.Context, []uint) error
|
||||
FindAPI(context.Context, uint) (*API, error)
|
||||
ListAPIs(context.Context, int, int, *API) ([]*API, int64, error)
|
||||
APIRoleIDs(context.Context, string, string) ([]uint, error)
|
||||
SetAPIRoles(context.Context, string, string, []uint) error
|
||||
Authorize(context.Context, uint, string, string) (bool, error)
|
||||
PolicyPaths(context.Context, uint) ([]*API, error)
|
||||
SetPolicyPaths(context.Context, uint, []*API) error
|
||||
IgnoredAPIs(context.Context) ([]*API, error)
|
||||
SetAPIIgnored(context.Context, string, string, bool) error
|
||||
ApplyAPISync(context.Context, []*API, []*API) error
|
||||
}
|
||||
|
||||
type APIUsecase struct{ APIRepo }
|
||||
|
||||
func NewAPIUsecase(repo APIRepo) *APIUsecase { return &APIUsecase{APIRepo: repo} }
|
||||
|
||||
type APISyncDiff struct {
|
||||
Added []*API
|
||||
Deleted []*API
|
||||
Ignored []*API
|
||||
}
|
||||
|
||||
func (uc *APIUsecase) SyncAPIs(ctx context.Context, routes []*API) (*APISyncDiff, error) {
|
||||
stored, _, err := uc.ListAPIs(ctx, 0, 0, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ignored, err := uc.IgnoredAPIs(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key := func(value *API) string { return strings.ToUpper(value.Method) + " " + value.Path }
|
||||
ignoreSet := make(map[string]bool, len(ignored))
|
||||
for _, item := range ignored {
|
||||
ignoreSet[key(item)] = true
|
||||
}
|
||||
routeSet := make(map[string]*API, len(routes))
|
||||
for _, item := range routes {
|
||||
if !ignoreSet[key(item)] {
|
||||
routeSet[key(item)] = item
|
||||
}
|
||||
}
|
||||
storedSet := make(map[string]*API, len(stored))
|
||||
for _, item := range stored {
|
||||
storedSet[key(item)] = item
|
||||
}
|
||||
diff := &APISyncDiff{Ignored: ignored}
|
||||
for routeKey, item := range routeSet {
|
||||
if storedSet[routeKey] == nil {
|
||||
diff.Added = append(diff.Added, item)
|
||||
}
|
||||
}
|
||||
for storedKey, item := range storedSet {
|
||||
if routeSet[storedKey] == nil && !ignoreSet[storedKey] {
|
||||
diff.Deleted = append(diff.Deleted, item)
|
||||
}
|
||||
}
|
||||
return diff, nil
|
||||
}
|
||||
|
|
@ -27,13 +27,6 @@ type OperationRecord struct {
|
|||
User *User
|
||||
}
|
||||
|
||||
type OperationLogRepo interface {
|
||||
RecordOperation(context.Context, *OperationRecord) error
|
||||
ListOperations(context.Context, int, int, *OperationRecord) ([]*OperationRecord, int64, error)
|
||||
FindOperation(context.Context, uint) (*OperationRecord, error)
|
||||
DeleteOperations(context.Context, []uint) error
|
||||
}
|
||||
|
||||
type LoginLog struct {
|
||||
ID uint
|
||||
CreatedAt time.Time
|
||||
|
|
@ -45,13 +38,6 @@ type LoginLog struct {
|
|||
FilterByStatus bool
|
||||
}
|
||||
|
||||
type LoginLogRepo interface {
|
||||
RecordLogin(context.Context, *LoginLog) error
|
||||
ListLogins(context.Context, int, int, *LoginLog) ([]*LoginLog, int64, error)
|
||||
FindLogin(context.Context, uint) (*LoginLog, error)
|
||||
DeleteLogins(context.Context, []uint) error
|
||||
}
|
||||
|
||||
type DataAccessLog struct {
|
||||
ID uint
|
||||
CreatedAt time.Time
|
||||
|
|
@ -61,12 +47,6 @@ type DataAccessLog struct {
|
|||
RequestID, Method, Path, Detail string
|
||||
}
|
||||
|
||||
type DataAccessLogRepo interface {
|
||||
RecordDataAccess(context.Context, *DataAccessLog) error
|
||||
ListDataAccess(context.Context, int, int, *DataAccessLog) ([]*DataAccessLog, int64, error)
|
||||
DeleteDataAccess(context.Context, []uint) error
|
||||
}
|
||||
|
||||
type LogDate struct {
|
||||
Date string
|
||||
FileCount int
|
||||
|
|
@ -104,14 +84,6 @@ type ErrorRecord struct {
|
|||
CreatedAtRange []time.Time
|
||||
}
|
||||
|
||||
type ErrorRecordRepo interface {
|
||||
CreateError(context.Context, *ErrorRecord) error
|
||||
UpdateError(context.Context, *ErrorRecord) error
|
||||
DeleteErrors(context.Context, []uint) error
|
||||
FindError(context.Context, uint) (*ErrorRecord, error)
|
||||
ListErrors(context.Context, int, int, *ErrorRecord) ([]*ErrorRecord, int64, error)
|
||||
}
|
||||
|
||||
type AuditRecordRepo interface {
|
||||
RecordOperation(context.Context, *OperationRecord) error
|
||||
RecordLogin(context.Context, *LoginLog) error
|
||||
|
|
|
|||
|
|
@ -40,6 +40,11 @@ type AuthenticationResult struct {
|
|||
NeedChangePassword bool
|
||||
}
|
||||
|
||||
type TokenAuthentication struct {
|
||||
Claims *AuthClaims
|
||||
Refreshed *IssuedToken
|
||||
}
|
||||
|
||||
type AuthenticationUsecase struct {
|
||||
users *UserUsecase
|
||||
security *SecurityUsecase
|
||||
|
|
@ -148,3 +153,28 @@ func (uc *AuthenticationUsecase) SwitchAuthority(ctx context.Context, userID, au
|
|||
}
|
||||
return &AuthenticationResult{User: user, Token: issued.Value, ExpiresAt: issued.ExpiresAt, NeedChangePassword: user.MustChangePassword}, nil
|
||||
}
|
||||
|
||||
func (uc *AuthenticationUsecase) AuthenticateToken(ctx context.Context, token string) (*TokenAuthentication, error) {
|
||||
claims, err := uc.issuer.ParseToken(token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
disabled, err := uc.security.tokens.IsTokenDisabled(ctx, token)
|
||||
if err != nil || disabled {
|
||||
return nil, ErrTokenDisabled
|
||||
}
|
||||
result := &TokenAuthentication{Claims: claims}
|
||||
if claims.BufferTime <= 0 || time.Until(claims.ExpiresAt) >= claims.BufferTime {
|
||||
return result, nil
|
||||
}
|
||||
user := &User{ID: claims.ID, UUID: claims.UUID, Username: claims.Username, NickName: claims.NickName, AuthorityID: claims.AuthorityID, MustChangePassword: claims.MustChangePwd}
|
||||
issued, err := uc.issuer.IssueToken(user, claims.AuthorityID, claims.MustChangePwd, 0)
|
||||
if err != nil {
|
||||
return result, nil
|
||||
}
|
||||
if err = uc.security.RotateActiveToken(ctx, claims.Username, token, issued.Value, issued.TTL); err != nil {
|
||||
return result, nil
|
||||
}
|
||||
result.Refreshed = issued
|
||||
return result, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
package biz
|
||||
|
||||
import "context"
|
||||
|
||||
type AuthorityAccessRepo interface {
|
||||
CreateAuthority(context.Context, *Authority) error
|
||||
CopyAuthority(context.Context, uint, *Authority) error
|
||||
UpdateAuthority(context.Context, *Authority) error
|
||||
DeleteAuthority(context.Context, uint) error
|
||||
ListAuthorities(context.Context) ([]*Authority, error)
|
||||
SetAuthorityUsers(context.Context, uint, []uint) error
|
||||
AuthorityUserIDs(context.Context, uint) ([]uint, error)
|
||||
SetDataScope(context.Context, uint, int, []uint) error
|
||||
DataScopeDepartmentIDs(context.Context, uint) ([]uint, error)
|
||||
ResolveDataScope(context.Context, uint, uint) (DataScope, error)
|
||||
}
|
||||
|
||||
type AuthorityUsecase struct{ AuthorityAccessRepo }
|
||||
|
||||
func NewAuthorityUsecase(repo AuthorityAccessRepo) *AuthorityUsecase {
|
||||
return &AuthorityUsecase{AuthorityAccessRepo: repo}
|
||||
}
|
||||
|
||||
func (uc *AuthorityUsecase) AuthorityTree(ctx context.Context) ([]*Authority, error) {
|
||||
items, err := uc.ListAuthorities(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
byID := make(map[uint]*Authority, len(items))
|
||||
for _, item := range items {
|
||||
item.Children = nil
|
||||
byID[item.AuthorityID] = item
|
||||
}
|
||||
roots := make([]*Authority, 0)
|
||||
for _, item := range items {
|
||||
if item.ParentID != nil && *item.ParentID != 0 && byID[*item.ParentID] != nil {
|
||||
parent := byID[*item.ParentID]
|
||||
parent.Children = append(parent.Children, item)
|
||||
} else {
|
||||
roots = append(roots, item)
|
||||
}
|
||||
}
|
||||
return roots, nil
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Department struct {
|
||||
ID uint
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
Name string
|
||||
ParentID uint
|
||||
Ancestors string
|
||||
Sort int
|
||||
LeaderID uint
|
||||
Leader *User
|
||||
Status bool
|
||||
Children []*Department
|
||||
NamePath string
|
||||
}
|
||||
|
||||
type DepartmentRepo interface {
|
||||
CreateDepartment(context.Context, *Department) error
|
||||
UpdateDepartment(context.Context, *Department) error
|
||||
DeleteDepartment(context.Context, uint) error
|
||||
FindDepartment(context.Context, uint) (*Department, error)
|
||||
ListDepartments(context.Context, string) ([]*Department, error)
|
||||
DepartmentUserIDs(context.Context, uint) ([]uint, error)
|
||||
SetDepartmentUsers(context.Context, uint, []uint) error
|
||||
SetUserDepartments(context.Context, uint, []uint, uint) error
|
||||
}
|
||||
|
||||
type DepartmentUsecase struct{ DepartmentRepo }
|
||||
|
||||
func NewDepartmentUsecase(repo DepartmentRepo) *DepartmentUsecase {
|
||||
return &DepartmentUsecase{DepartmentRepo: repo}
|
||||
}
|
||||
|
||||
func (uc *DepartmentUsecase) Departments(ctx context.Context, name string) ([]*Department, error) {
|
||||
return uc.ListDepartments(ctx, name)
|
||||
}
|
||||
|
||||
func (uc *DepartmentUsecase) Department(ctx context.Context, id uint) (*Department, error) {
|
||||
return uc.FindDepartment(ctx, id)
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package biz
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"time"
|
||||
)
|
||||
|
|
@ -68,6 +69,28 @@ type IssuedToken struct {
|
|||
TTL time.Duration
|
||||
}
|
||||
|
||||
type AuthClaims struct {
|
||||
UUID string
|
||||
ID uint
|
||||
Username string
|
||||
NickName string
|
||||
AuthorityID uint
|
||||
BufferTime time.Duration
|
||||
MustChangePwd bool
|
||||
Issuer string
|
||||
ExpiresAt time.Time
|
||||
}
|
||||
|
||||
var (
|
||||
ErrTokenExpired = errors.New("token expired")
|
||||
ErrTokenMalformed = errors.New("token malformed")
|
||||
ErrTokenSignatureInvalid = errors.New("token signature invalid")
|
||||
ErrTokenNotValidYet = errors.New("token not valid yet")
|
||||
ErrTokenInvalid = errors.New("token invalid")
|
||||
ErrTokenDisabled = errors.New("token disabled")
|
||||
)
|
||||
|
||||
type TokenIssuer interface {
|
||||
IssueToken(*User, uint, bool, time.Duration) (*IssuedToken, error)
|
||||
ParseToken(string) (*AuthClaims, error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
package biz
|
||||
|
||||
import "context"
|
||||
|
||||
type PermissionRepo interface {
|
||||
Buttons(context.Context, uint) ([]*MenuButton, error)
|
||||
SetAuthorityButtons(context.Context, uint, map[uint][]uint) error
|
||||
AuthorityButtonIDs(context.Context, uint) ([]uint, error)
|
||||
SelectedButtons(context.Context, uint, uint) ([]uint, error)
|
||||
SetSelectedButtons(context.Context, uint, uint, []uint) error
|
||||
CanRemoveButton(context.Context, uint) (bool, error)
|
||||
}
|
||||
|
||||
type PermissionUsecase struct{ PermissionRepo }
|
||||
|
||||
func NewPermissionUsecase(repo PermissionRepo) *PermissionUsecase {
|
||||
return &PermissionUsecase{PermissionRepo: repo}
|
||||
}
|
||||
|
|
@ -5,45 +5,6 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
type Department struct {
|
||||
ID uint
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
Name string
|
||||
ParentID uint
|
||||
Ancestors string
|
||||
Sort int
|
||||
LeaderID uint
|
||||
Leader *User
|
||||
Status bool
|
||||
Children []*Department
|
||||
NamePath string
|
||||
}
|
||||
|
||||
type DepartmentRepo interface {
|
||||
CreateDepartment(context.Context, *Department) error
|
||||
UpdateDepartment(context.Context, *Department) error
|
||||
DeleteDepartment(context.Context, uint) error
|
||||
FindDepartment(context.Context, uint) (*Department, error)
|
||||
ListDepartments(context.Context, string) ([]*Department, error)
|
||||
DepartmentUserIDs(context.Context, uint) ([]uint, error)
|
||||
SetDepartmentUsers(context.Context, uint, []uint) error
|
||||
SetUserDepartments(context.Context, uint, []uint, uint) error
|
||||
}
|
||||
|
||||
type DepartmentUsecase struct{ DepartmentRepo }
|
||||
|
||||
func NewDepartmentUsecase(repo DepartmentRepo) *DepartmentUsecase {
|
||||
return &DepartmentUsecase{DepartmentRepo: repo}
|
||||
}
|
||||
|
||||
func (uc *DepartmentUsecase) Departments(ctx context.Context, name string) ([]*Department, error) {
|
||||
return uc.ListDepartments(ctx, name)
|
||||
}
|
||||
func (uc *DepartmentUsecase) Department(ctx context.Context, id uint) (*Department, error) {
|
||||
return uc.FindDepartment(ctx, id)
|
||||
}
|
||||
|
||||
type Position struct {
|
||||
ID uint
|
||||
CreatedAt time.Time
|
||||
|
|
@ -81,6 +42,7 @@ func NewPositionUsecase(repo PositionRepo) *PositionUsecase {
|
|||
func (uc *PositionUsecase) Positions(ctx context.Context, page, size int, filter *PositionListFilter) ([]*Position, int64, error) {
|
||||
return uc.ListPositions(ctx, page, size, filter)
|
||||
}
|
||||
|
||||
func (uc *PositionUsecase) Position(ctx context.Context, id uint) (*Position, error) {
|
||||
return uc.FindPosition(ctx, id)
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package biz
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
)
|
||||
|
||||
|
|
@ -24,6 +25,9 @@ type InitializationRepo interface {
|
|||
PersistAdminConfig(context.Context, []byte) error
|
||||
PersistRuntimeConfig(context.Context, []byte, []byte) error
|
||||
ReloadConfig(context.Context) error
|
||||
ConfigurationJSON() (json.RawMessage, error)
|
||||
SaveConfigurationJSON(context.Context, json.RawMessage) error
|
||||
DiskMountPoints() []string
|
||||
}
|
||||
|
||||
type SystemConfigUsecase struct {
|
||||
|
|
@ -68,3 +72,13 @@ func (uc *SystemConfigUsecase) ReloadConfig(ctx context.Context) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (uc *SystemConfigUsecase) ConfigurationJSON() (json.RawMessage, error) {
|
||||
return uc.repo.ConfigurationJSON()
|
||||
}
|
||||
|
||||
func (uc *SystemConfigUsecase) SaveConfigurationJSON(ctx context.Context, value json.RawMessage) error {
|
||||
return uc.repo.SaveConfigurationJSON(ctx, value)
|
||||
}
|
||||
|
||||
func (uc *SystemConfigUsecase) DiskMountPoints() []string { return uc.repo.DiskMountPoints() }
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
package data
|
||||
|
||||
import "kra/internal/biz"
|
||||
|
||||
type authorityAccessRepo struct{ data *Data }
|
||||
type apiRepo struct{ data *Data }
|
||||
type permissionRepo struct{ data *Data }
|
||||
|
||||
func NewAuthorityAccessRepo(data *Data) biz.AuthorityAccessRepo {
|
||||
return &authorityAccessRepo{data: data}
|
||||
}
|
||||
|
||||
func NewAPIRepo(data *Data) biz.APIRepo { return &apiRepo{data: data} }
|
||||
|
||||
func NewPermissionRepo(data *Data) biz.PermissionRepo { return &permissionRepo{data: data} }
|
||||
|
|
@ -14,6 +14,10 @@ import (
|
|||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type apiRepo struct{ data *Data }
|
||||
|
||||
func NewAPIRepo(data *Data) biz.APIRepo { return &apiRepo{data: data} }
|
||||
|
||||
type apiPO struct {
|
||||
ID uint `gorm:"primaryKey"`
|
||||
CreatedAt time.Time
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@ import (
|
|||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type apiTokenRepo struct{ data *Data }
|
||||
|
||||
func NewAPITokenRepo(data *Data) biz.APITokenRepo { return &apiTokenRepo{data: data} }
|
||||
|
||||
type apiTokenPO struct {
|
||||
ID uint `gorm:"primaryKey"`
|
||||
CreatedAt time.Time
|
||||
|
|
@ -45,7 +49,7 @@ func (r *apiTokenRepo) UserHasAuthority(ctx context.Context, userID, authorityID
|
|||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
user, err := (&userRepo{data: r.data}).toBizUser(ctx, &po)
|
||||
user, err := (&userRepo{data: r.data}).loadUser(ctx, &po)
|
||||
return user, count > 0 || po.AuthorityID == authorityID, err
|
||||
}
|
||||
func (r *apiTokenRepo) CreateAPIToken(ctx context.Context, v *biz.APIToken) error {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,12 @@ import (
|
|||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type authorityAccessRepo struct{ data *Data }
|
||||
|
||||
func NewAuthorityAccessRepo(data *Data) biz.AuthorityAccessRepo {
|
||||
return &authorityAccessRepo{data: data}
|
||||
}
|
||||
|
||||
func (r *authorityAccessRepo) strictAuthorityIDs(ctx context.Context, actorID uint) (map[uint]bool, error) {
|
||||
allowed := make(map[uint]bool)
|
||||
if actorID == 0 {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,303 @@
|
|||
package data
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"kra/internal/conf"
|
||||
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
)
|
||||
|
||||
type configurationEnvelope struct {
|
||||
Data json.RawMessage `json:"data"`
|
||||
Admin json.RawMessage `json:"admin"`
|
||||
Email *struct {
|
||||
To string `json:"to"`
|
||||
From string `json:"from"`
|
||||
Host string `json:"host"`
|
||||
Secret string `json:"secret"`
|
||||
Nickname string `json:"nickname"`
|
||||
Port int32 `json:"port"`
|
||||
IsSSL bool `json:"is-ssl"`
|
||||
IsLoginAuth bool `json:"is-loginauth"`
|
||||
} `json:"email"`
|
||||
}
|
||||
|
||||
func (r *initializationRepo) ConfigurationJSON() (json.RawMessage, error) {
|
||||
dataConfig, adminConfig := r.data.runtime.Values()
|
||||
admin := map[string]any{"routerPrefix": ""}
|
||||
email := map[string]any{}
|
||||
if adminConfig != nil {
|
||||
admin["routerPrefix"] = adminConfig.RouterPrefix
|
||||
if adminConfig.System != nil {
|
||||
admin["system"] = map[string]any{"useRedis": adminConfig.System.UseRedis, "useMultipoint": adminConfig.System.UseMultipoint, "useStrictAuth": adminConfig.System.UseStrictAuth, "disableAutoMigrate": adminConfig.System.DisableAutoMigrate, "useMongo": adminConfig.System.UseMongo}
|
||||
}
|
||||
if adminConfig.Jwt != nil {
|
||||
admin["jwt"] = map[string]any{"signingKey": "******", "expiresTime": durationString(adminConfig.Jwt.ExpiresTime), "bufferTime": durationString(adminConfig.Jwt.BufferTime), "issuer": adminConfig.Jwt.Issuer}
|
||||
}
|
||||
if adminConfig.Captcha != nil {
|
||||
admin["captcha"] = map[string]any{"keyLong": adminConfig.Captcha.KeyLong, "imgWidth": adminConfig.Captcha.ImgWidth, "imgHeight": adminConfig.Captcha.ImgHeight, "storeExpiration": durationString(adminConfig.Captcha.StoreExpiration)}
|
||||
}
|
||||
if adminConfig.Local != nil {
|
||||
admin["local"] = map[string]any{"storePath": adminConfig.Local.StorePath, "pathPrefix": adminConfig.Local.PathPrefix}
|
||||
}
|
||||
if adminConfig.Media != nil {
|
||||
admin["media"] = map[string]any{"sessionTtl": adminConfig.Media.SessionTtl, "maxFileSize": adminConfig.Media.MaxFileSize}
|
||||
}
|
||||
if adminConfig.Email != nil {
|
||||
email = map[string]any{"to": adminConfig.Email.To, "from": adminConfig.Email.From, "host": adminConfig.Email.Host, "secret": "******", "nickname": adminConfig.Email.Nickname, "port": adminConfig.Email.Port, "is-ssl": adminConfig.Email.IsSsl, "is-loginauth": adminConfig.Email.IsLoginAuth}
|
||||
}
|
||||
if adminConfig.Storage != nil {
|
||||
storage := proto.Clone(adminConfig.Storage).(*conf.AdminBackend_Storage)
|
||||
maskStorageSecrets(storage)
|
||||
admin["storage"] = storage
|
||||
}
|
||||
if adminConfig.Zap != nil {
|
||||
admin["zap"] = adminConfig.Zap
|
||||
}
|
||||
if adminConfig.Cors != nil {
|
||||
admin["cors"] = adminConfig.Cors
|
||||
}
|
||||
if adminConfig.App != nil {
|
||||
admin["app"] = adminConfig.App
|
||||
}
|
||||
}
|
||||
maskDataSecrets(dataConfig)
|
||||
dataMap := map[string]any{}
|
||||
if dataConfig != nil {
|
||||
raw, err := protojson.MarshalOptions{UseProtoNames: true}.Marshal(dataConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = json.Unmarshal(raw, &dataMap); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return json.Marshal(map[string]any{"config": map[string]any{"admin": admin, "email": email, "data": dataMap}})
|
||||
}
|
||||
|
||||
func (r *initializationRepo) SaveConfigurationJSON(ctx context.Context, raw json.RawMessage) error {
|
||||
currentData, currentAdmin := r.data.runtime.Values()
|
||||
if currentAdmin == nil {
|
||||
return nil
|
||||
}
|
||||
nextData := cloneDataConfig(currentData)
|
||||
nextAdmin := proto.Clone(currentAdmin).(*conf.AdminBackend)
|
||||
var value configurationEnvelope
|
||||
if err := json.Unmarshal(raw, &value); err != nil {
|
||||
return err
|
||||
}
|
||||
options := protojson.UnmarshalOptions{DiscardUnknown: true}
|
||||
if len(value.Data) > 0 && string(value.Data) != "null" {
|
||||
patch := &conf.Data{}
|
||||
if err := options.Unmarshal(value.Data, patch); err != nil {
|
||||
return err
|
||||
}
|
||||
applyDataPatch(nextData, patch)
|
||||
}
|
||||
if len(value.Admin) > 0 && string(value.Admin) != "null" {
|
||||
patch := &conf.AdminBackend{}
|
||||
if err := options.Unmarshal(value.Admin, patch); err != nil {
|
||||
return err
|
||||
}
|
||||
applyAdminPatch(nextAdmin, patch)
|
||||
}
|
||||
preserveDataSecrets(nextData, currentData)
|
||||
preserveAdminSecrets(nextAdmin, currentAdmin)
|
||||
if value.Email != nil {
|
||||
if nextAdmin.Email == nil {
|
||||
nextAdmin.Email = &conf.AdminBackend_Email{}
|
||||
}
|
||||
nextAdmin.Email.To, nextAdmin.Email.From, nextAdmin.Email.Host = value.Email.To, value.Email.From, value.Email.Host
|
||||
nextAdmin.Email.Nickname, nextAdmin.Email.Port = value.Email.Nickname, value.Email.Port
|
||||
nextAdmin.Email.IsSsl, nextAdmin.Email.IsLoginAuth = value.Email.IsSSL, value.Email.IsLoginAuth
|
||||
if value.Email.Secret != "" && value.Email.Secret != "******" {
|
||||
nextAdmin.Email.Secret = value.Email.Secret
|
||||
}
|
||||
}
|
||||
nextAdmin.ConfigPath = currentAdmin.ConfigPath
|
||||
dataRaw, err := protojson.MarshalOptions{UseProtoNames: true}.Marshal(nextData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
adminRaw, err := protojson.MarshalOptions{UseProtoNames: true}.Marshal(nextAdmin)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return r.PersistRuntimeConfig(ctx, dataRaw, adminRaw)
|
||||
}
|
||||
|
||||
func (r *initializationRepo) DiskMountPoints() []string {
|
||||
config := r.data.runtime.Admin()
|
||||
if config == nil {
|
||||
return nil
|
||||
}
|
||||
points := make([]string, 0, len(config.DiskList))
|
||||
for _, item := range config.DiskList {
|
||||
if item != nil && item.MountPoint != "" {
|
||||
points = append(points, item.MountPoint)
|
||||
}
|
||||
}
|
||||
return points
|
||||
}
|
||||
|
||||
func cloneDataConfig(value *conf.Data) *conf.Data {
|
||||
if value == nil {
|
||||
return &conf.Data{}
|
||||
}
|
||||
return proto.Clone(value).(*conf.Data)
|
||||
}
|
||||
|
||||
func durationString(value *durationpb.Duration) string {
|
||||
if value == nil {
|
||||
return "0s"
|
||||
}
|
||||
return value.AsDuration().String()
|
||||
}
|
||||
|
||||
func applyDataPatch(target, patch *conf.Data) {
|
||||
if patch.Database != nil {
|
||||
target.Database = patch.Database
|
||||
}
|
||||
if patch.Redis != nil {
|
||||
target.Redis = patch.Redis
|
||||
}
|
||||
if patch.Mongo != nil {
|
||||
target.Mongo = patch.Mongo
|
||||
}
|
||||
if patch.DatabaseList != nil {
|
||||
target.DatabaseList = patch.DatabaseList
|
||||
}
|
||||
if patch.RedisList != nil {
|
||||
target.RedisList = patch.RedisList
|
||||
}
|
||||
}
|
||||
|
||||
func applyAdminPatch(target, patch *conf.AdminBackend) {
|
||||
target.RouterPrefix = patch.RouterPrefix
|
||||
if patch.System != nil {
|
||||
target.System = patch.System
|
||||
}
|
||||
if patch.Jwt != nil {
|
||||
target.Jwt = patch.Jwt
|
||||
}
|
||||
if patch.Captcha != nil {
|
||||
target.Captcha = patch.Captcha
|
||||
}
|
||||
if patch.Local != nil {
|
||||
target.Local = patch.Local
|
||||
}
|
||||
if patch.Media != nil {
|
||||
target.Media = patch.Media
|
||||
}
|
||||
if patch.Storage != nil {
|
||||
target.Storage = patch.Storage
|
||||
}
|
||||
if patch.Zap != nil {
|
||||
target.Zap = patch.Zap
|
||||
}
|
||||
if patch.Cors != nil {
|
||||
target.Cors = patch.Cors
|
||||
}
|
||||
if patch.App != nil {
|
||||
target.App = patch.App
|
||||
}
|
||||
}
|
||||
|
||||
func maskDataSecrets(value *conf.Data) {
|
||||
if value == nil {
|
||||
return
|
||||
}
|
||||
if value.Database != nil {
|
||||
value.Database.Password = "******"
|
||||
}
|
||||
if value.Redis != nil {
|
||||
value.Redis.Password = "******"
|
||||
}
|
||||
if value.Mongo != nil {
|
||||
value.Mongo.Password = "******"
|
||||
}
|
||||
for _, item := range value.DatabaseList {
|
||||
if item != nil {
|
||||
item.Password = "******"
|
||||
}
|
||||
}
|
||||
for _, item := range value.RedisList {
|
||||
if item != nil {
|
||||
item.Password = "******"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func preserveDataSecrets(next, current *conf.Data) {
|
||||
if next == nil || current == nil {
|
||||
return
|
||||
}
|
||||
if next.Database != nil && current.Database != nil && maskedSecret(next.Database.Password) {
|
||||
next.Database.Password = current.Database.Password
|
||||
}
|
||||
if next.Redis != nil && current.Redis != nil && maskedSecret(next.Redis.Password) {
|
||||
next.Redis.Password = current.Redis.Password
|
||||
}
|
||||
if next.Mongo != nil && current.Mongo != nil && maskedSecret(next.Mongo.Password) {
|
||||
next.Mongo.Password = current.Mongo.Password
|
||||
}
|
||||
for i, item := range next.DatabaseList {
|
||||
if item != nil && i < len(current.DatabaseList) && current.DatabaseList[i] != nil && maskedSecret(item.Password) {
|
||||
item.Password = current.DatabaseList[i].Password
|
||||
}
|
||||
}
|
||||
for i, item := range next.RedisList {
|
||||
if item != nil && i < len(current.RedisList) && current.RedisList[i] != nil && maskedSecret(item.Password) {
|
||||
item.Password = current.RedisList[i].Password
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func preserveAdminSecrets(next, current *conf.AdminBackend) {
|
||||
if next.Jwt != nil && current.Jwt != nil && maskedSecret(next.Jwt.SigningKey) {
|
||||
next.Jwt.SigningKey = current.Jwt.SigningKey
|
||||
}
|
||||
if next.Email != nil && current.Email != nil && maskedSecret(next.Email.Secret) {
|
||||
next.Email.Secret = current.Email.Secret
|
||||
}
|
||||
preserveStorageSecrets(next.Storage, current.Storage)
|
||||
}
|
||||
|
||||
func maskedSecret(value string) bool { return value == "" || value == "******" }
|
||||
|
||||
func objectStores(storage *conf.AdminBackend_Storage) []*conf.AdminBackend_ObjectStore {
|
||||
if storage == nil {
|
||||
return nil
|
||||
}
|
||||
return []*conf.AdminBackend_ObjectStore{storage.AliyunOss, storage.HuaweiObs, storage.TencentCos, storage.AwsS3, storage.CloudflareR2, storage.Minio}
|
||||
}
|
||||
|
||||
func maskStorageSecrets(storage *conf.AdminBackend_Storage) {
|
||||
if storage.Qiniu != nil {
|
||||
storage.Qiniu.SecretKey = "******"
|
||||
}
|
||||
for _, item := range objectStores(storage) {
|
||||
if item != nil {
|
||||
item.SecretKey = "******"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func preserveStorageSecrets(next, current *conf.AdminBackend_Storage) {
|
||||
if next == nil || current == nil {
|
||||
return
|
||||
}
|
||||
if next.Qiniu != nil && current.Qiniu != nil && maskedSecret(next.Qiniu.SecretKey) {
|
||||
next.Qiniu.SecretKey = current.Qiniu.SecretKey
|
||||
}
|
||||
nextItems, currentItems := objectStores(next), objectStores(current)
|
||||
for i := range nextItems {
|
||||
if nextItems[i] != nil && currentItems[i] != nil && maskedSecret(nextItems[i].SecretKey) {
|
||||
nextItems[i].SecretKey = currentItems[i].SecretKey
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,6 +12,10 @@ import (
|
|||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type departmentRepo struct{ data *Data }
|
||||
|
||||
func NewDepartmentRepo(data *Data) biz.DepartmentRepo { return &departmentRepo{data: data} }
|
||||
|
||||
type departmentPO struct {
|
||||
ID uint `gorm:"primaryKey"`
|
||||
CreatedAt time.Time
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@ import (
|
|||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type dictionaryRepo struct{ data *Data }
|
||||
|
||||
func NewDictionaryRepo(data *Data) biz.DictionaryRepo { return &dictionaryRepo{data: data} }
|
||||
|
||||
type dictionaryPO struct {
|
||||
ID uint `gorm:"primaryKey"`
|
||||
CreatedAt time.Time
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
package data
|
||||
|
||||
import "kra/internal/biz"
|
||||
|
||||
type departmentRepo struct{ data *Data }
|
||||
type positionRepo struct{ data *Data }
|
||||
|
||||
func NewDepartmentRepo(data *Data) biz.DepartmentRepo { return &departmentRepo{data: data} }
|
||||
|
||||
func NewPositionRepo(data *Data) biz.PositionRepo { return &positionRepo{data: data} }
|
||||
|
|
@ -10,6 +10,10 @@ import (
|
|||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
type parameterRepo struct{ data *Data }
|
||||
|
||||
func NewParameterRepo(data *Data) biz.ParameterRepo { return ¶meterRepo{data: data} }
|
||||
|
||||
type parameterPO struct {
|
||||
ID uint `gorm:"primaryKey"`
|
||||
CreatedAt time.Time
|
||||
|
|
|
|||
|
|
@ -8,6 +8,10 @@ import (
|
|||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type permissionRepo struct{ data *Data }
|
||||
|
||||
func NewPermissionRepo(data *Data) biz.PermissionRepo { return &permissionRepo{data: data} }
|
||||
|
||||
type menuButtonPO struct {
|
||||
ID uint `gorm:"primaryKey"`
|
||||
Name string
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@ import (
|
|||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type positionRepo struct{ data *Data }
|
||||
|
||||
func NewPositionRepo(data *Data) biz.PositionRepo { return &positionRepo{data: data} }
|
||||
|
||||
type positionPO struct {
|
||||
ID uint `gorm:"primaryKey"`
|
||||
CreatedAt time.Time
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package data
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"kra/internal/biz"
|
||||
|
|
@ -92,3 +93,22 @@ func (i *tokenIssuer) IssueToken(user *biz.User, authorityID uint, mustChangePas
|
|||
}
|
||||
return &biz.IssuedToken{Value: token, ExpiresAt: claims.ExpiresAt.Time, TTL: expires}, nil
|
||||
}
|
||||
|
||||
func (i *tokenIssuer) ParseToken(token string) (*biz.AuthClaims, error) {
|
||||
claims, err := adminauth.Parse(token, i.settings.JWTSettings().SigningKey)
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, adminauth.ErrTokenExpired):
|
||||
return nil, biz.ErrTokenExpired
|
||||
case errors.Is(err, adminauth.ErrTokenMalformed):
|
||||
return nil, biz.ErrTokenMalformed
|
||||
case errors.Is(err, adminauth.ErrTokenSignatureInvalid):
|
||||
return nil, biz.ErrTokenSignatureInvalid
|
||||
case errors.Is(err, adminauth.ErrTokenNotValidYet):
|
||||
return nil, biz.ErrTokenNotValidYet
|
||||
default:
|
||||
return nil, biz.ErrTokenInvalid
|
||||
}
|
||||
}
|
||||
return &biz.AuthClaims{UUID: claims.UUID, ID: claims.ID, Username: claims.Username, NickName: claims.NickName, AuthorityID: claims.AuthorityID, BufferTime: time.Duration(claims.BufferTime) * time.Second, MustChangePwd: claims.MustChangePwd, Issuer: claims.Issuer, ExpiresAt: claims.ExpiresAt.Time}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@ import (
|
|||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type securityRepo struct{ data *Data }
|
||||
|
||||
func NewSecurityRepo(data *Data) biz.SecurityRepo { return &securityRepo{data: data} }
|
||||
|
||||
type securityConfigPO struct {
|
||||
ID uint `gorm:"primaryKey"`
|
||||
CaptchaOpen int
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
package data
|
||||
|
||||
import "kra/internal/biz"
|
||||
|
||||
type dictionaryRepo struct{ data *Data }
|
||||
type parameterRepo struct{ data *Data }
|
||||
type apiTokenRepo struct{ data *Data }
|
||||
type securityRepo struct{ data *Data }
|
||||
|
||||
func NewDictionaryRepo(data *Data) biz.DictionaryRepo { return &dictionaryRepo{data: data} }
|
||||
|
||||
func NewParameterRepo(data *Data) biz.ParameterRepo { return ¶meterRepo{data: data} }
|
||||
|
||||
func NewAPITokenRepo(data *Data) biz.APITokenRepo { return &apiTokenRepo{data: data} }
|
||||
|
||||
func NewSecurityRepo(data *Data) biz.SecurityRepo { return &securityRepo{data: data} }
|
||||
|
|
@ -22,7 +22,7 @@ func (r *userRepo) FindUserByUsername(ctx context.Context, username string) (*bi
|
|||
}
|
||||
return nil, err
|
||||
}
|
||||
return r.toBizUser(ctx, &po)
|
||||
return r.loadUser(ctx, &po)
|
||||
}
|
||||
|
||||
func (r *userRepo) FindUserByID(ctx context.Context, id uint) (*biz.User, error) {
|
||||
|
|
@ -33,10 +33,10 @@ func (r *userRepo) FindUserByID(ctx context.Context, id uint) (*biz.User, error)
|
|||
}
|
||||
return nil, err
|
||||
}
|
||||
return r.toBizUser(ctx, &po)
|
||||
return r.loadUser(ctx, &po)
|
||||
}
|
||||
|
||||
func (r *userRepo) toBizUser(ctx context.Context, po *userPO) (*biz.User, error) {
|
||||
func (r *userRepo) loadUser(ctx context.Context, po *userPO) (*biz.User, error) {
|
||||
var authority authorityPO
|
||||
if err := r.data.gormDB.WithContext(ctx).First(&authority, "authority_id = ?", po.AuthorityID).Error; err != nil {
|
||||
return nil, err
|
||||
|
|
@ -90,7 +90,7 @@ func baseBizUser(po *userPO) *biz.User {
|
|||
return &biz.User{ID: po.ID, CreatedAt: po.CreatedAt, UpdatedAt: po.UpdatedAt, UUID: po.UUID, Username: po.Username, Password: po.Password, NickName: po.NickName, HeaderImg: po.HeaderImg, AuthorityID: po.AuthorityID, DeptID: po.DeptID, Phone: po.Phone, Email: po.Email, Enable: po.Enable, OriginSetting: setting, MustChangePassword: po.MustChangePassword, PasswordUpdatedAt: po.PasswordUpdatedAt}
|
||||
}
|
||||
|
||||
func (r *userRepo) toBizUsers(ctx context.Context, pos []userPO) ([]*biz.User, error) {
|
||||
func (r *userRepo) loadUsers(ctx context.Context, pos []userPO) ([]*biz.User, error) {
|
||||
if len(pos) == 0 {
|
||||
return []*biz.User{}, nil
|
||||
}
|
||||
|
|
@ -275,7 +275,7 @@ func (r *userRepo) ListUsers(ctx context.Context, page, pageSize int, filter *bi
|
|||
if err := applyPagination(db.Order(order), page, pageSize, 100).Find(&pos).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
users, err := r.toBizUsers(ctx, pos)
|
||||
users, err := r.loadUsers(ctx, pos)
|
||||
return users, total, err
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import (
|
|||
kratoshttp "github.com/go-kratos/kratos/v3/transport/http"
|
||||
)
|
||||
|
||||
func NewGinEngine(runtime *conf.Runtime, access *service.AccessControlService, handlers *handler.Set, security *service.SecurityService, tokens *service.TokenService, audit *service.AuditRecorder, logger *slog.Logger) *gin.Engine {
|
||||
func NewGinEngine(runtime *conf.Runtime, access *service.AccessControlService, handlers *handler.Set, auth *service.AuthService, security *service.SecurityService, audit *service.AuditRecorder, logger *slog.Logger) *gin.Engine {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
engine := gin.New()
|
||||
engine.Use(servermiddleware.RequestMeta(), servermiddleware.Recovery(audit, logger), servermiddleware.AccessLog(runtime, logger), servermiddleware.ErrorAudit(audit), servermiddleware.SecurityRateLimit(security), servermiddleware.OperationAudit(runtime, audit))
|
||||
|
|
@ -35,7 +35,7 @@ func NewGinEngine(runtime *conf.Runtime, access *service.AccessControlService, h
|
|||
serverrouter.RegisterPublic(public, engine, handlers.Public)
|
||||
|
||||
private := engine.Group(prefix)
|
||||
private.Use(servermiddleware.Auth(runtime, security, tokens), servermiddleware.MustChangePassword(), servermiddleware.AccessControl(runtime, access, audit))
|
||||
private.Use(servermiddleware.Auth(auth), servermiddleware.MustChangePassword(), servermiddleware.AccessControl(runtime, access, audit))
|
||||
serverrouter.RegisterUser(private, handlers.User)
|
||||
serverrouter.RegisterNavigation(private, handlers.Navigation)
|
||||
serverrouter.RegisterSession(private, handlers.Session)
|
||||
|
|
|
|||
|
|
@ -92,17 +92,6 @@ func (h *Dictionary) Export(c *gin.Context) {
|
|||
httpx.Fail(c, "导出失败")
|
||||
return
|
||||
}
|
||||
delete(item, "ID")
|
||||
delete(item, "CreatedAt")
|
||||
delete(item, "UpdatedAt")
|
||||
delete(item, "DeletedAt")
|
||||
if details, ok := item["sysDictionaryDetails"].([]map[string]any); ok {
|
||||
for _, detail := range details {
|
||||
for _, key := range []string{"ID", "CreatedAt", "UpdatedAt", "DeletedAt", "sysDictionaryID", "parentID", "disabled", "children"} {
|
||||
delete(detail, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, item, "导出成功")
|
||||
}
|
||||
func (h *Dictionary) Import(c *gin.Context) {
|
||||
|
|
@ -258,5 +247,5 @@ func (h *Dictionary) Path(c *gin.Context) {
|
|||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"path": item["path"]}, "获取成功")
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"path": item.Path}, "获取成功")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,12 @@ func (h *SystemConfig) SetSecurity(c *gin.Context) {
|
|||
}
|
||||
|
||||
func (h *SystemConfig) Get(c *gin.Context) {
|
||||
httpx.Write(c, httpx.CodeSuccess, h.system.SystemConfig(), "获取成功")
|
||||
value, err := h.system.SystemConfig()
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, value, "获取成功")
|
||||
}
|
||||
|
||||
func (h *SystemConfig) Set(c *gin.Context) {
|
||||
|
|
|
|||
|
|
@ -5,12 +5,10 @@ import (
|
|||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"kra/internal/conf"
|
||||
"kra/internal/biz"
|
||||
"kra/internal/server/httpx"
|
||||
"kra/internal/service"
|
||||
"kra/pkg/adminauth"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"golang.org/x/sync/singleflight"
|
||||
|
|
@ -20,12 +18,7 @@ const claimsKey = "admin_claims"
|
|||
|
||||
var refreshTokens singleflight.Group
|
||||
|
||||
type refreshedToken struct {
|
||||
token string
|
||||
expiresAt int64
|
||||
}
|
||||
|
||||
func Auth(runtime *conf.Runtime, security *service.SecurityService, tokens *service.TokenService) gin.HandlerFunc {
|
||||
func Auth(auth *service.AuthService) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
token := c.GetHeader("x-token")
|
||||
if token == "" {
|
||||
|
|
@ -35,73 +28,41 @@ func Auth(runtime *conf.Runtime, security *service.SecurityService, tokens *serv
|
|||
httpx.NoAuth(c, "未登录或非法访问,请登录")
|
||||
return
|
||||
}
|
||||
secret := ""
|
||||
config := runtime.Admin()
|
||||
if config != nil && config.Jwt != nil {
|
||||
secret = config.Jwt.SigningKey
|
||||
}
|
||||
claims, err := adminauth.Parse(token, secret)
|
||||
value, err, _ := refreshTokens.Do(token, func() (any, error) {
|
||||
return auth.AuthenticateToken(c.Request.Context(), token)
|
||||
})
|
||||
if err != nil {
|
||||
message := "无法处理此token"
|
||||
switch {
|
||||
case errors.Is(err, adminauth.ErrTokenExpired):
|
||||
case errors.Is(err, biz.ErrTokenExpired):
|
||||
message = "登录已过期,请重新登录"
|
||||
case errors.Is(err, adminauth.ErrTokenMalformed):
|
||||
case errors.Is(err, biz.ErrTokenMalformed):
|
||||
message = "这不是一个token"
|
||||
case errors.Is(err, adminauth.ErrTokenSignatureInvalid):
|
||||
case errors.Is(err, biz.ErrTokenSignatureInvalid):
|
||||
message = "无效签名"
|
||||
case errors.Is(err, adminauth.ErrTokenNotValidYet):
|
||||
case errors.Is(err, biz.ErrTokenNotValidYet):
|
||||
message = "token尚未激活"
|
||||
case errors.Is(err, biz.ErrTokenDisabled):
|
||||
message = "您的帐户异地登陆或令牌失效"
|
||||
}
|
||||
httpx.SetTokenCookie(c, "", -1)
|
||||
httpx.NoAuth(c, message)
|
||||
return
|
||||
}
|
||||
if disabled, checkErr := tokens.IsTokenDisabled(c.Request.Context(), token); checkErr != nil || disabled {
|
||||
httpx.SetTokenCookie(c, "", -1)
|
||||
httpx.NoAuth(c, "您的帐户异地登陆或令牌失效")
|
||||
return
|
||||
authentication := value.(*biz.TokenAuthentication)
|
||||
if authentication.Refreshed != nil {
|
||||
c.Header("new-token", authentication.Refreshed.Value)
|
||||
c.Header("new-expires-at", strconv.FormatInt(authentication.Refreshed.ExpiresAt.Unix(), 10))
|
||||
httpx.SetTokenCookie(c, authentication.Refreshed.Value, int(authentication.Refreshed.TTL.Seconds()))
|
||||
}
|
||||
if claims.ExpiresAt != nil && claims.BufferTime > 0 && time.Until(claims.ExpiresAt.Time) < time.Duration(claims.BufferTime)*time.Second {
|
||||
expires, buffer := 7*24*time.Hour, time.Duration(claims.BufferTime)*time.Second
|
||||
issuer := claims.Issuer
|
||||
config = runtime.Admin()
|
||||
if config != nil && config.Jwt != nil {
|
||||
if config.Jwt.ExpiresTime != nil {
|
||||
expires = config.Jwt.ExpiresTime.AsDuration()
|
||||
}
|
||||
if config.Jwt.BufferTime != nil {
|
||||
buffer = config.Jwt.BufferTime.AsDuration()
|
||||
}
|
||||
if config.Jwt.Issuer != "" {
|
||||
issuer = config.Jwt.Issuer
|
||||
}
|
||||
}
|
||||
value, refreshErr, _ := refreshTokens.Do(token, func() (any, error) {
|
||||
newToken, newClaims, generateErr := adminauth.Generate(secret, issuer, expires, buffer, claims.ID, claims.AuthorityID, claims.UUID, claims.Username, claims.NickName, claims.MustChangePwd)
|
||||
if generateErr != nil {
|
||||
return nil, generateErr
|
||||
}
|
||||
if rotateErr := security.RotateActiveToken(c.Request.Context(), claims.Username, token, newToken, expires); rotateErr != nil {
|
||||
return nil, rotateErr
|
||||
}
|
||||
return refreshedToken{token: newToken, expiresAt: newClaims.ExpiresAt.Unix()}, nil
|
||||
})
|
||||
if refreshErr == nil {
|
||||
refreshed := value.(refreshedToken)
|
||||
c.Header("new-token", refreshed.token)
|
||||
c.Header("new-expires-at", strconv.FormatInt(refreshed.expiresAt, 10))
|
||||
httpx.SetTokenCookie(c, refreshed.token, int(expires.Seconds()))
|
||||
}
|
||||
}
|
||||
c.Set(claimsKey, claims)
|
||||
c.Set(claimsKey, authentication.Claims)
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func Claims(c *gin.Context) *adminauth.Claims {
|
||||
func Claims(c *gin.Context) *biz.AuthClaims {
|
||||
value, _ := c.Get(claimsKey)
|
||||
claims, _ := value.(*adminauth.Claims)
|
||||
claims, _ := value.(*biz.AuthClaims)
|
||||
return claims
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,10 +2,9 @@ package server
|
|||
|
||||
import (
|
||||
"kra/internal/server/handler"
|
||||
"kra/internal/worker"
|
||||
|
||||
"github.com/google/wire"
|
||||
)
|
||||
|
||||
// ProviderSet is server providers.
|
||||
var ProviderSet = wire.NewSet(NewGinEngine, NewGinServer, handler.NewAuthority, handler.NewMenu, handler.NewAPI, handler.NewPermission, handler.NewOrganization, handler.NewAnnouncement, handler.NewEmail, handler.NewTask, handler.NewMedia, handler.NewAudit, handler.NewExport, handler.NewVersion, handler.NewDictionary, handler.NewParameter, handler.NewAPIToken, handler.NewSystemConfig, handler.NewPublic, handler.NewUser, handler.NewNavigation, handler.NewSession, handler.NewSet, worker.NewTaskExecutor, worker.NewTaskScheduler, worker.NewTaskRuntime)
|
||||
var ProviderSet = wire.NewSet(NewGinEngine, NewGinServer, handler.NewAuthority, handler.NewMenu, handler.NewAPI, handler.NewPermission, handler.NewOrganization, handler.NewAnnouncement, handler.NewEmail, handler.NewTask, handler.NewMedia, handler.NewAudit, handler.NewExport, handler.NewVersion, handler.NewDictionary, handler.NewParameter, handler.NewAPIToken, handler.NewSystemConfig, handler.NewPublic, handler.NewUser, handler.NewNavigation, handler.NewSession, handler.NewSet)
|
||||
|
|
|
|||
|
|
@ -1,122 +0,0 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type AuthorityService struct{ uc *biz.AuthorityUsecase }
|
||||
|
||||
func NewAuthorityService(uc *biz.AuthorityUsecase) *AuthorityService {
|
||||
return &AuthorityService{uc: uc}
|
||||
}
|
||||
|
||||
type PermissionService struct{ uc *biz.PermissionUsecase }
|
||||
|
||||
func NewPermissionService(uc *biz.PermissionUsecase) *PermissionService {
|
||||
return &PermissionService{uc: uc}
|
||||
}
|
||||
|
||||
type AccessControlService struct{ uc *biz.AccessControlUsecase }
|
||||
|
||||
func NewAccessControlService(uc *biz.AccessControlUsecase) *AccessControlService {
|
||||
return &AccessControlService{uc: uc}
|
||||
}
|
||||
|
||||
func (s *AccessControlService) Authorize(ctx context.Context, aid uint, path, method string) (bool, error) {
|
||||
return s.uc.Authorize(ctx, aid, path, method)
|
||||
}
|
||||
|
||||
func authorityDTO(v *biz.Authority) map[string]any {
|
||||
out := convertAuthority(*v)
|
||||
children := make([]map[string]any, 0, len(v.Children))
|
||||
for _, child := range v.Children {
|
||||
children = append(children, authorityDTO(child))
|
||||
}
|
||||
out["children"] = children
|
||||
return out
|
||||
}
|
||||
func (s *AuthorityService) Authorities(ctx context.Context) ([]map[string]any, error) {
|
||||
items, err := s.uc.AuthorityTree(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
roots := make([]map[string]any, 0, len(items))
|
||||
for _, v := range items {
|
||||
roots = append(roots, authorityDTO(v))
|
||||
}
|
||||
return roots, nil
|
||||
}
|
||||
func (s *AuthorityService) CreateAuthority(ctx context.Context, v *biz.Authority) error {
|
||||
return s.uc.CreateAuthority(ctx, v)
|
||||
}
|
||||
func (s *AuthorityService) CopyAuthority(ctx context.Context, sourceID uint, v *biz.Authority) error {
|
||||
return s.uc.CopyAuthority(ctx, sourceID, v)
|
||||
}
|
||||
func (s *AuthorityService) UpdateAuthority(ctx context.Context, v *biz.Authority) error {
|
||||
return s.uc.UpdateAuthority(ctx, v)
|
||||
}
|
||||
func (s *AuthorityService) DeleteAuthority(ctx context.Context, id uint) error {
|
||||
return s.uc.DeleteAuthority(ctx, id)
|
||||
}
|
||||
func authorityDomain(req *dto.AuthorityRequest) *biz.Authority {
|
||||
return &biz.Authority{AuthorityID: req.AuthorityID, AuthorityName: req.AuthorityName, ParentID: req.ParentID, DataScope: req.DataScope, DefaultRouter: req.DefaultRouter}
|
||||
}
|
||||
func authorityResponse(value *biz.Authority) *dto.AuthorityResponse {
|
||||
return &dto.AuthorityResponse{AuthorityID: value.AuthorityID, AuthorityName: value.AuthorityName, ParentID: value.ParentID, DataScope: value.DataScope, DefaultRouter: value.DefaultRouter}
|
||||
}
|
||||
func (s *AuthorityService) CreateAuthorityRequest(ctx context.Context, req *dto.AuthorityRequest) (*dto.AuthorityResponse, error) {
|
||||
value := authorityDomain(req)
|
||||
if err := s.CreateAuthority(ctx, value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return authorityResponse(value), nil
|
||||
}
|
||||
func (s *AuthorityService) CopyAuthorityRequest(ctx context.Context, req *dto.CopyAuthorityRequest) (*dto.AuthorityResponse, error) {
|
||||
value := authorityDomain(&req.Authority)
|
||||
if err := s.CopyAuthority(ctx, req.OldAuthorityID, value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return authorityResponse(value), nil
|
||||
}
|
||||
func (s *AuthorityService) UpdateAuthorityRequest(ctx context.Context, req *dto.AuthorityRequest) (*dto.AuthorityResponse, error) {
|
||||
value := authorityDomain(req)
|
||||
if err := s.UpdateAuthority(ctx, value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return authorityResponse(value), nil
|
||||
}
|
||||
func (s *AuthorityService) SetAuthorityUsers(ctx context.Context, id uint, ids []uint) error {
|
||||
return s.uc.SetAuthorityUsers(ctx, id, ids)
|
||||
}
|
||||
func (s *AuthorityService) AuthorityUserIDs(ctx context.Context, id uint) ([]uint, error) {
|
||||
return s.uc.AuthorityUserIDs(ctx, id)
|
||||
}
|
||||
func (s *AuthorityService) SetDataScope(ctx context.Context, id uint, scope int, ids []uint) error {
|
||||
return s.uc.SetDataScope(ctx, id, scope, ids)
|
||||
}
|
||||
func (s *AuthorityService) DataScopeDepartmentIDs(ctx context.Context, id uint) ([]uint, error) {
|
||||
return s.uc.DataScopeDepartmentIDs(ctx, id)
|
||||
}
|
||||
func (s *AccessControlService) ResolveDataScope(ctx context.Context, authorityID, userID uint) (biz.DataScope, error) {
|
||||
return s.uc.ResolveDataScope(ctx, authorityID, userID)
|
||||
}
|
||||
func (s *AccessControlService) ContextWithDataScope(ctx context.Context, authorityID, userID uint) (context.Context, error) {
|
||||
scope, err := s.ResolveDataScope(ctx, authorityID, userID)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
return biz.NewDataScopeContext(ctx, scope), nil
|
||||
}
|
||||
|
||||
func (s *PermissionService) SelectedButtons(ctx context.Context, aid, menuID uint) ([]uint, error) {
|
||||
return s.uc.SelectedButtons(ctx, aid, menuID)
|
||||
}
|
||||
func (s *PermissionService) SetSelectedButtons(ctx context.Context, aid, menuID uint, ids []uint) error {
|
||||
return s.uc.SetSelectedButtons(ctx, aid, menuID, ids)
|
||||
}
|
||||
func (s *PermissionService) CanRemoveButton(ctx context.Context, id uint) (bool, error) {
|
||||
return s.uc.CanRemoveButton(ctx, id)
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"kra/internal/biz"
|
||||
)
|
||||
|
||||
type AccessControlService struct{ uc *biz.AccessControlUsecase }
|
||||
|
||||
func NewAccessControlService(uc *biz.AccessControlUsecase) *AccessControlService {
|
||||
return &AccessControlService{uc: uc}
|
||||
}
|
||||
|
||||
func (s *AccessControlService) Authorize(ctx context.Context, authorityID uint, path, method string) (bool, error) {
|
||||
return s.uc.Authorize(ctx, authorityID, path, method)
|
||||
}
|
||||
|
||||
func (s *AccessControlService) ResolveDataScope(ctx context.Context, authorityID, userID uint) (biz.DataScope, error) {
|
||||
return s.uc.ResolveDataScope(ctx, authorityID, userID)
|
||||
}
|
||||
|
||||
func (s *AccessControlService) ContextWithDataScope(ctx context.Context, authorityID, userID uint) (context.Context, error) {
|
||||
scope, err := s.ResolveDataScope(ctx, authorityID, userID)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
return biz.NewDataScopeContext(ctx, scope), nil
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"time"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type AnnouncementInput struct {
|
||||
|
|
@ -22,15 +23,12 @@ func NewAnnouncementService(uc *biz.AnnouncementUsecase) *AnnouncementService {
|
|||
return &AnnouncementService{uc: uc}
|
||||
}
|
||||
|
||||
func announcementDTO(item *biz.Announcement) map[string]any {
|
||||
func announcementDTO(item *biz.Announcement) *dto.AnnouncementResponse {
|
||||
attachments := any([]any{})
|
||||
if len(item.Attachments) > 0 {
|
||||
_ = json.Unmarshal(item.Attachments, &attachments)
|
||||
}
|
||||
return map[string]any{
|
||||
"ID": item.ID, "CreatedAt": item.CreatedAt, "UpdatedAt": item.UpdatedAt, "DeletedAt": nil,
|
||||
"title": item.Title, "content": item.Content, "userID": item.UserID, "attachments": attachments,
|
||||
}
|
||||
return &dto.AnnouncementResponse{ID: item.ID, CreatedAt: item.CreatedAt, UpdatedAt: item.UpdatedAt, DeletedAt: nil, Title: item.Title, Content: item.Content, UserID: item.UserID, Attachments: attachments}
|
||||
}
|
||||
|
||||
func announcementDO(in AnnouncementInput) *biz.Announcement {
|
||||
|
|
@ -53,7 +51,7 @@ func (s *AnnouncementService) DeleteByIDs(ctx context.Context, ids []uint) error
|
|||
return s.uc.DeleteByIDs(ctx, ids)
|
||||
}
|
||||
|
||||
func (s *AnnouncementService) Find(ctx context.Context, id uint) (map[string]any, error) {
|
||||
func (s *AnnouncementService) Find(ctx context.Context, id uint) (*dto.AnnouncementResponse, error) {
|
||||
item, err := s.uc.Find(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -61,26 +59,26 @@ func (s *AnnouncementService) Find(ctx context.Context, id uint) (map[string]any
|
|||
return announcementDTO(item), nil
|
||||
}
|
||||
|
||||
func (s *AnnouncementService) List(ctx context.Context, page, pageSize int, start, end *time.Time) ([]map[string]any, int64, error) {
|
||||
func (s *AnnouncementService) List(ctx context.Context, page, pageSize int, start, end *time.Time) ([]*dto.AnnouncementResponse, int64, error) {
|
||||
items, total, err := s.uc.List(ctx, biz.AnnouncementFilter{Page: page, PageSize: pageSize, StartCreatedAt: start, EndCreatedAt: end})
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
result := make([]map[string]any, 0, len(items))
|
||||
result := make([]*dto.AnnouncementResponse, 0, len(items))
|
||||
for _, item := range items {
|
||||
result = append(result, announcementDTO(item))
|
||||
}
|
||||
return result, total, nil
|
||||
}
|
||||
|
||||
func (s *AnnouncementService) UserOptions(ctx context.Context) ([]map[string]any, error) {
|
||||
func (s *AnnouncementService) UserOptions(ctx context.Context) ([]*dto.SelectOptionResponse, error) {
|
||||
items, err := s.uc.UserOptions(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := make([]map[string]any, 0, len(items))
|
||||
result := make([]*dto.SelectOptionResponse, 0, len(items))
|
||||
for _, item := range items {
|
||||
result = append(result, map[string]any{"label": item.Label, "value": item.Value})
|
||||
result = append(result, &dto.SelectOptionResponse{Label: item.Label, Value: item.Value})
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,9 +147,6 @@ func (s *APIService) SyncAPIResponses(ctx context.Context, routes []dto.APIReque
|
|||
return s.SyncAPIs(ctx, items)
|
||||
}
|
||||
|
||||
func apiDTO(v *biz.API) map[string]any {
|
||||
return map[string]any{"ID": v.ID, "CreatedAt": v.CreatedAt, "UpdatedAt": v.UpdatedAt, "DeletedAt": nil, "path": v.Path, "description": v.Description, "apiGroup": v.APIGroup, "method": v.Method}
|
||||
}
|
||||
func (s *APIService) DeleteAPIs(ctx context.Context, ids []uint) error {
|
||||
return s.uc.DeleteAPIs(ctx, ids)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"time"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type TokenService struct {
|
||||
|
|
@ -16,12 +17,12 @@ func NewTokenService(uc *biz.TokenUsecase, issuer biz.TokenIssuer) *TokenService
|
|||
return &TokenService{uc: uc, issuer: issuer}
|
||||
}
|
||||
|
||||
func tokenDTO(v *biz.APIToken) map[string]any {
|
||||
var user any = nil
|
||||
func tokenDTO(v *biz.APIToken) *dto.APITokenResponse {
|
||||
var user *dto.UserResponse
|
||||
if v.User != nil {
|
||||
user = convertUser(v.User)
|
||||
}
|
||||
return map[string]any{"ID": v.ID, "CreatedAt": v.CreatedAt, "UpdatedAt": v.UpdatedAt, "DeletedAt": nil, "userId": v.UserID, "authorityId": v.AuthorityID, "token": v.Token, "status": v.Status, "expiresAt": v.ExpiresAt, "remark": v.Remark, "user": user}
|
||||
return &dto.APITokenResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, UserID: v.UserID, AuthorityID: v.AuthorityID, Token: v.Token, Status: v.Status, ExpiresAt: v.ExpiresAt, Remark: v.Remark, User: user}
|
||||
}
|
||||
|
||||
func (s *TokenService) CreateAPIToken(ctx context.Context, userID, authorityID uint, days int, remark string) (string, error) {
|
||||
|
|
@ -39,12 +40,12 @@ func (s *TokenService) CreateAPIToken(ctx context.Context, userID, authorityID u
|
|||
}
|
||||
return issued.Value, nil
|
||||
}
|
||||
func (s *TokenService) APITokens(ctx context.Context, page, size int, userID uint, status *bool) ([]map[string]any, int64, error) {
|
||||
func (s *TokenService) APITokens(ctx context.Context, page, size int, userID uint, status *bool) ([]*dto.APITokenResponse, int64, error) {
|
||||
items, total, err := s.uc.ListAPITokens(ctx, page, size, userID, status)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]map[string]any, 0, len(items))
|
||||
out := make([]*dto.APITokenResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, tokenDTO(v))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,28 +21,28 @@ func (s *AuditRecorder) RecordOperation(ctx context.Context, v *biz.OperationRec
|
|||
func (s *AuditRecorder) RecordOperationRequest(ctx context.Context, value *dto.OperationRecordRequest) error {
|
||||
return s.RecordOperation(ctx, &biz.OperationRecord{IP: value.IP, Method: value.Method, Path: value.Path, Status: value.Status, LatencyMS: value.LatencyMS, Agent: value.Agent, ErrorMessage: value.ErrorMessage, Body: value.Body, Response: value.Response, UserID: value.UserID, RequestID: value.RequestID, TraceID: value.TraceID, DeviceID: value.DeviceID})
|
||||
}
|
||||
func (s *AuditService) OperationsFilter(ctx context.Context, page, size int, path, method string, status int) ([]map[string]any, int64, error) {
|
||||
func (s *AuditService) OperationsFilter(ctx context.Context, page, size int, path, method string, status int) ([]*dto.OperationRecordResponse, int64, error) {
|
||||
return s.Operations(ctx, page, size, &biz.OperationRecord{Path: path, Method: method, Status: status})
|
||||
}
|
||||
func opDTO(v *biz.OperationRecord) map[string]any {
|
||||
user := map[string]any{}
|
||||
func opDTO(v *biz.OperationRecord) *dto.OperationRecordResponse {
|
||||
var user any = map[string]any{}
|
||||
if v.User != nil {
|
||||
user = convertUser(v.User)
|
||||
}
|
||||
return map[string]any{"ID": v.ID, "CreatedAt": v.CreatedAt, "DeletedAt": nil, "ip": v.IP, "method": v.Method, "path": v.Path, "status": v.Status, "latency_ms": v.LatencyMS, "agent": v.Agent, "error_message": v.ErrorMessage, "body": v.Body, "resp": v.Response, "user_id": v.UserID, "request_id": v.RequestID, "trace_id": v.TraceID, "device_id": v.DeviceID, "user": user}
|
||||
return &dto.OperationRecordResponse{ID: v.ID, CreatedAt: v.CreatedAt, DeletedAt: nil, IP: v.IP, Method: v.Method, Path: v.Path, Status: v.Status, LatencyMS: v.LatencyMS, Agent: v.Agent, ErrorMessage: v.ErrorMessage, Body: v.Body, Response: v.Response, UserID: v.UserID, RequestID: v.RequestID, TraceID: v.TraceID, DeviceID: v.DeviceID, User: user}
|
||||
}
|
||||
func (s *AuditService) Operations(ctx context.Context, page, size int, q *biz.OperationRecord) ([]map[string]any, int64, error) {
|
||||
func (s *AuditService) Operations(ctx context.Context, page, size int, q *biz.OperationRecord) ([]*dto.OperationRecordResponse, int64, error) {
|
||||
items, total, err := s.uc.ListOperations(ctx, page, size, q)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]map[string]any, 0, len(items))
|
||||
out := make([]*dto.OperationRecordResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, opDTO(v))
|
||||
}
|
||||
return out, total, nil
|
||||
}
|
||||
func (s *AuditService) Operation(ctx context.Context, id uint) (map[string]any, error) {
|
||||
func (s *AuditService) Operation(ctx context.Context, id uint) (*dto.OperationRecordResponse, error) {
|
||||
v, err := s.uc.FindOperation(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -59,28 +59,28 @@ func (s *AuditRecorder) RecordLogin(ctx context.Context, v *biz.LoginLog) error
|
|||
func (s *AuditRecorder) RecordLoginRequest(ctx context.Context, value *dto.LoginLogRequest) error {
|
||||
return s.RecordLogin(ctx, &biz.LoginLog{Username: value.Username, IP: value.IP, Status: value.Status, ErrorMessage: value.ErrorMessage, Agent: value.Agent, UserID: value.UserID})
|
||||
}
|
||||
func (s *AuditService) LoginsFilter(ctx context.Context, page, size int, username string, status bool) ([]map[string]any, int64, error) {
|
||||
func (s *AuditService) LoginsFilter(ctx context.Context, page, size int, username string, status bool) ([]*dto.LoginLogResponse, int64, error) {
|
||||
return s.Logins(ctx, page, size, &biz.LoginLog{Username: username, Status: status, FilterByStatus: status})
|
||||
}
|
||||
func loginDTO(v *biz.LoginLog) map[string]any {
|
||||
user := map[string]any{}
|
||||
func loginDTO(v *biz.LoginLog) *dto.LoginLogResponse {
|
||||
var user any = map[string]any{}
|
||||
if v.User != nil {
|
||||
user = convertUser(v.User)
|
||||
}
|
||||
return map[string]any{"ID": v.ID, "CreatedAt": v.CreatedAt, "DeletedAt": nil, "username": v.Username, "ip": v.IP, "status": v.Status, "errorMessage": v.ErrorMessage, "agent": v.Agent, "userId": v.UserID, "user": user}
|
||||
return &dto.LoginLogResponse{ID: v.ID, CreatedAt: v.CreatedAt, DeletedAt: nil, Username: v.Username, IP: v.IP, Status: v.Status, ErrorMessage: v.ErrorMessage, Agent: v.Agent, UserID: v.UserID, User: user}
|
||||
}
|
||||
func (s *AuditService) Logins(ctx context.Context, page, size int, q *biz.LoginLog) ([]map[string]any, int64, error) {
|
||||
func (s *AuditService) Logins(ctx context.Context, page, size int, q *biz.LoginLog) ([]*dto.LoginLogResponse, int64, error) {
|
||||
items, total, err := s.uc.ListLogins(ctx, page, size, q)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]map[string]any, 0, len(items))
|
||||
out := make([]*dto.LoginLogResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, loginDTO(v))
|
||||
}
|
||||
return out, total, nil
|
||||
}
|
||||
func (s *AuditService) Login(ctx context.Context, id uint) (map[string]any, error) {
|
||||
func (s *AuditService) Login(ctx context.Context, id uint) (*dto.LoginLogResponse, error) {
|
||||
v, err := s.uc.FindLogin(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -97,18 +97,18 @@ func (s *AuditRecorder) RecordDataAccess(ctx context.Context, v *biz.DataAccessL
|
|||
func (s *AuditRecorder) RecordDataAccessRequest(ctx context.Context, value *dto.DataAccessRecordRequest) error {
|
||||
return s.RecordDataAccess(ctx, &biz.DataAccessLog{EventType: value.EventType, Operation: value.Operation, UserID: value.UserID, AuthorityID: value.AuthorityID, RequestID: value.RequestID, Method: value.Method, Path: value.Path, Detail: value.Detail})
|
||||
}
|
||||
func (s *AuditService) DataAccessRequest(ctx context.Context, req *dto.DataAccessListRequest) ([]map[string]any, int64, error) {
|
||||
func (s *AuditService) DataAccessRequest(ctx context.Context, req *dto.DataAccessListRequest) ([]*dto.DataAccessLogResponse, int64, error) {
|
||||
return s.DataAccess(ctx, req.Page, req.PageSize, &biz.DataAccessLog{EventType: req.EventType, TargetTable: req.TargetTable, UserID: req.UserID})
|
||||
}
|
||||
func dataAccessDTO(v *biz.DataAccessLog) map[string]any {
|
||||
return map[string]any{"ID": v.ID, "CreatedAt": v.CreatedAt, "DeletedAt": nil, "eventType": v.EventType, "targetTable": v.TargetTable, "operation": v.Operation, "userId": v.UserID, "authorityId": v.AuthorityID, "scope": v.Scope, "requestId": v.RequestID, "method": v.Method, "path": v.Path, "detail": v.Detail}
|
||||
func dataAccessDTO(v *biz.DataAccessLog) *dto.DataAccessLogResponse {
|
||||
return &dto.DataAccessLogResponse{ID: v.ID, CreatedAt: v.CreatedAt, DeletedAt: nil, EventType: v.EventType, TargetTable: v.TargetTable, Operation: v.Operation, UserID: v.UserID, AuthorityID: v.AuthorityID, Scope: v.Scope, RequestID: v.RequestID, Method: v.Method, Path: v.Path, Detail: v.Detail}
|
||||
}
|
||||
func (s *AuditService) DataAccess(ctx context.Context, page, size int, q *biz.DataAccessLog) ([]map[string]any, int64, error) {
|
||||
func (s *AuditService) DataAccess(ctx context.Context, page, size int, q *biz.DataAccessLog) ([]*dto.DataAccessLogResponse, int64, error) {
|
||||
items, total, err := s.uc.ListDataAccess(ctx, page, size, q)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]map[string]any, 0, len(items))
|
||||
out := make([]*dto.DataAccessLogResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, dataAccessDTO(v))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import (
|
|||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
func errorDTO(v *biz.ErrorRecord) map[string]any {
|
||||
return map[string]any{"ID": v.ID, "CreatedAt": v.CreatedAt, "DeletedAt": nil, "form": v.Form, "info": v.Info, "level": v.Level, "request_id": v.RequestID, "trace_id": v.TraceID, "solution": v.Solution, "status": v.Status}
|
||||
func errorDTO(v *biz.ErrorRecord) *dto.ErrorRecordResponse {
|
||||
return &dto.ErrorRecordResponse{ID: v.ID, CreatedAt: v.CreatedAt, DeletedAt: nil, Form: v.Form, Info: v.Info, Level: v.Level, RequestID: v.RequestID, TraceID: v.TraceID, Solution: v.Solution, Status: v.Status}
|
||||
}
|
||||
func (s *AuditRecorder) CreateError(ctx context.Context, v *biz.ErrorRecord) error {
|
||||
return s.uc.CreateError(ctx, v)
|
||||
|
|
@ -23,7 +23,7 @@ func (s *AuditRecorder) CreateErrorRequest(ctx context.Context, req *dto.ErrorRe
|
|||
func (s *AuditService) UpdateErrorRequest(ctx context.Context, req *dto.ErrorRecordRequest) error {
|
||||
return s.UpdateError(ctx, errorDomain(req))
|
||||
}
|
||||
func (s *AuditService) ErrorsFilter(ctx context.Context, page, size int, form, info string, createdAtRange []time.Time) ([]map[string]any, int64, error) {
|
||||
func (s *AuditService) ErrorsFilter(ctx context.Context, page, size int, form, info string, createdAtRange []time.Time) ([]*dto.ErrorRecordResponse, int64, error) {
|
||||
return s.Errors(ctx, page, size, &biz.ErrorRecord{Form: form, Info: info, CreatedAtRange: createdAtRange})
|
||||
}
|
||||
func (s *AuditService) UpdateError(ctx context.Context, v *biz.ErrorRecord) error {
|
||||
|
|
@ -32,19 +32,19 @@ func (s *AuditService) UpdateError(ctx context.Context, v *biz.ErrorRecord) erro
|
|||
func (s *AuditService) DeleteErrors(ctx context.Context, ids []uint) error {
|
||||
return s.uc.DeleteErrors(ctx, ids)
|
||||
}
|
||||
func (s *AuditService) Error(ctx context.Context, id uint) (map[string]any, error) {
|
||||
func (s *AuditService) Error(ctx context.Context, id uint) (*dto.ErrorRecordResponse, error) {
|
||||
v, err := s.uc.FindError(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return errorDTO(v), nil
|
||||
}
|
||||
func (s *AuditService) Errors(ctx context.Context, page, size int, q *biz.ErrorRecord) ([]map[string]any, int64, error) {
|
||||
func (s *AuditService) Errors(ctx context.Context, page, size int, q *biz.ErrorRecord) ([]*dto.ErrorRecordResponse, int64, error) {
|
||||
items, total, err := s.uc.ListErrors(ctx, page, size, q)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]map[string]any, 0, len(items))
|
||||
out := make([]*dto.ErrorRecordResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, errorDTO(v))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type LogViewerService struct{ uc *biz.LogViewerUsecase }
|
||||
|
|
@ -12,32 +13,32 @@ func NewLogViewerService(uc *biz.LogViewerUsecase) *LogViewerService {
|
|||
return &LogViewerService{uc: uc}
|
||||
}
|
||||
|
||||
func (s *LogViewerService) LogDates(ctx context.Context, month string) (map[string]any, error) {
|
||||
func (s *LogViewerService) LogDates(ctx context.Context, month string) (*dto.LogDatesResponse, error) {
|
||||
items, err := s.uc.LogDates(ctx, month)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make([]map[string]any, 0, len(items))
|
||||
out := make([]*dto.LogDateResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, map[string]any{"date": v.Date, "fileCount": v.FileCount})
|
||||
out = append(out, &dto.LogDateResponse{Date: v.Date, FileCount: v.FileCount})
|
||||
}
|
||||
return map[string]any{"month": month, "dates": out}, nil
|
||||
return &dto.LogDatesResponse{Month: month, Dates: out}, nil
|
||||
}
|
||||
func (s *LogViewerService) LogFiles(ctx context.Context, date string) (map[string]any, error) {
|
||||
func (s *LogViewerService) LogFiles(ctx context.Context, date string) (*dto.LogFilesResponse, error) {
|
||||
items, err := s.uc.LogFiles(ctx, date)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make([]map[string]any, 0, len(items))
|
||||
out := make([]*dto.LogFileResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, map[string]any{"path": v.Path, "name": v.Name, "size": v.Size, "modifiedAt": v.ModifiedAt})
|
||||
out = append(out, &dto.LogFileResponse{Path: v.Path, Name: v.Name, Size: v.Size, ModifiedAt: v.ModifiedAt})
|
||||
}
|
||||
return map[string]any{"date": date, "files": out}, nil
|
||||
return &dto.LogFilesResponse{Date: date, Files: out}, nil
|
||||
}
|
||||
func (s *LogViewerService) LogContent(ctx context.Context, date, path string, cursor *int64) (map[string]any, error) {
|
||||
func (s *LogViewerService) LogContent(ctx context.Context, date, path string, cursor *int64) (*dto.LogContentResponse, error) {
|
||||
v, err := s.uc.LogContent(ctx, date, path, cursor)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return map[string]any{"date": v.Date, "path": v.Path, "content": v.Content, "lineCount": v.LineCount, "nextCursor": v.NextCursor, "hasMore": v.HasMore, "limitedByBytes": v.LimitedByBytes, "size": v.Size, "modifiedAt": v.ModifiedAt}, nil
|
||||
return &dto.LogContentResponse{Date: v.Date, Path: v.Path, Content: v.Content, LineCount: v.LineCount, NextCursor: v.NextCursor, HasMore: v.HasMore, LimitedByBytes: v.LimitedByBytes, Size: v.Size, ModifiedAt: v.ModifiedAt}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ import (
|
|||
)
|
||||
|
||||
type LoginResult struct {
|
||||
User map[string]any `json:"user"`
|
||||
Token string `json:"token"`
|
||||
ExpiresAt int64 `json:"expiresAt"`
|
||||
NeedChangePassword bool `json:"needChangePassword"`
|
||||
User *dto.UserResponse `json:"user"`
|
||||
Token string `json:"token"`
|
||||
ExpiresAt int64 `json:"expiresAt"`
|
||||
NeedChangePassword bool `json:"needChangePassword"`
|
||||
}
|
||||
|
||||
type AuthService struct {
|
||||
|
|
@ -41,3 +41,7 @@ func (s *AuthService) SwitchAuthority(ctx context.Context, id, authorityID uint)
|
|||
}
|
||||
return loginResult(value), nil
|
||||
}
|
||||
|
||||
func (s *AuthService) AuthenticateToken(ctx context.Context, token string) (*biz.TokenAuthentication, error) {
|
||||
return s.uc.AuthenticateToken(ctx, token)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,88 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type AuthorityService struct{ uc *biz.AuthorityUsecase }
|
||||
|
||||
func NewAuthorityService(uc *biz.AuthorityUsecase) *AuthorityService {
|
||||
return &AuthorityService{uc: uc}
|
||||
}
|
||||
|
||||
func authorityDTO(value *biz.Authority) *dto.AuthorityResponse {
|
||||
out := convertAuthority(*value)
|
||||
children := make([]*dto.AuthorityResponse, 0, len(value.Children))
|
||||
for _, child := range value.Children {
|
||||
children = append(children, authorityDTO(child))
|
||||
}
|
||||
out.Children = children
|
||||
return out
|
||||
}
|
||||
|
||||
func authorityDomain(req *dto.AuthorityRequest) *biz.Authority {
|
||||
return &biz.Authority{AuthorityID: req.AuthorityID, AuthorityName: req.AuthorityName, ParentID: req.ParentID, DataScope: req.DataScope, DefaultRouter: req.DefaultRouter}
|
||||
}
|
||||
|
||||
func authorityResponse(value *biz.Authority) *dto.AuthorityResponse {
|
||||
return &dto.AuthorityResponse{AuthorityID: value.AuthorityID, AuthorityName: value.AuthorityName, ParentID: value.ParentID, DataScope: value.DataScope, DefaultRouter: value.DefaultRouter}
|
||||
}
|
||||
|
||||
func (s *AuthorityService) Authorities(ctx context.Context) ([]*dto.AuthorityResponse, error) {
|
||||
items, err := s.uc.AuthorityTree(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
roots := make([]*dto.AuthorityResponse, 0, len(items))
|
||||
for _, value := range items {
|
||||
roots = append(roots, authorityDTO(value))
|
||||
}
|
||||
return roots, nil
|
||||
}
|
||||
|
||||
func (s *AuthorityService) CreateAuthorityRequest(ctx context.Context, req *dto.AuthorityRequest) (*dto.AuthorityResponse, error) {
|
||||
value := authorityDomain(req)
|
||||
if err := s.uc.CreateAuthority(ctx, value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return authorityResponse(value), nil
|
||||
}
|
||||
|
||||
func (s *AuthorityService) CopyAuthorityRequest(ctx context.Context, req *dto.CopyAuthorityRequest) (*dto.AuthorityResponse, error) {
|
||||
value := authorityDomain(&req.Authority)
|
||||
if err := s.uc.CopyAuthority(ctx, req.OldAuthorityID, value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return authorityResponse(value), nil
|
||||
}
|
||||
|
||||
func (s *AuthorityService) UpdateAuthorityRequest(ctx context.Context, req *dto.AuthorityRequest) (*dto.AuthorityResponse, error) {
|
||||
value := authorityDomain(req)
|
||||
if err := s.uc.UpdateAuthority(ctx, value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return authorityResponse(value), nil
|
||||
}
|
||||
|
||||
func (s *AuthorityService) DeleteAuthority(ctx context.Context, id uint) error {
|
||||
return s.uc.DeleteAuthority(ctx, id)
|
||||
}
|
||||
|
||||
func (s *AuthorityService) SetAuthorityUsers(ctx context.Context, id uint, ids []uint) error {
|
||||
return s.uc.SetAuthorityUsers(ctx, id, ids)
|
||||
}
|
||||
|
||||
func (s *AuthorityService) AuthorityUserIDs(ctx context.Context, id uint) ([]uint, error) {
|
||||
return s.uc.AuthorityUserIDs(ctx, id)
|
||||
}
|
||||
|
||||
func (s *AuthorityService) SetDataScope(ctx context.Context, id uint, scope int, ids []uint) error {
|
||||
return s.uc.SetDataScope(ctx, id, scope, ids)
|
||||
}
|
||||
|
||||
func (s *AuthorityService) DataScopeDepartmentIDs(ctx context.Context, id uint) ([]uint, error) {
|
||||
return s.uc.DataScopeDepartmentIDs(ctx, id)
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ func dictionaryDomain(value *dto.DictionaryRequest) *biz.Dictionary {
|
|||
}
|
||||
return &biz.Dictionary{ID: value.ID, Name: value.Name, Type: value.Type, Status: status, Desc: value.Description, ParentID: value.ParentID}
|
||||
}
|
||||
func (s *DictionaryService) CreateDictionaryRequest(ctx context.Context, req *dto.DictionaryRequest) (map[string]any, error) {
|
||||
func (s *DictionaryService) CreateDictionaryRequest(ctx context.Context, req *dto.DictionaryRequest) (*dto.DictionaryResponse, error) {
|
||||
value := dictionaryDomain(req)
|
||||
if err := s.CreateDictionary(ctx, value); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -30,41 +30,51 @@ func (s *DictionaryService) CreateDictionaryRequest(ctx context.Context, req *dt
|
|||
func (s *DictionaryService) UpdateDictionaryRequest(ctx context.Context, req *dto.DictionaryRequest) error {
|
||||
return s.UpdateDictionary(ctx, dictionaryDomain(req))
|
||||
}
|
||||
func dictionaryDTO(v *biz.Dictionary) map[string]any {
|
||||
children := make([]map[string]any, 0, len(v.Children))
|
||||
func dictionaryDTO(v *biz.Dictionary) *dto.DictionaryResponse {
|
||||
children := make([]*dto.DictionaryResponse, 0, len(v.Children))
|
||||
for _, x := range v.Children {
|
||||
children = append(children, dictionaryDTO(x))
|
||||
}
|
||||
details := make([]map[string]any, 0, len(v.Details))
|
||||
details := make([]*dto.DictionaryDetailResponse, 0, len(v.Details))
|
||||
for _, x := range v.Details {
|
||||
details = append(details, detailDTO(x))
|
||||
}
|
||||
return map[string]any{"ID": v.ID, "CreatedAt": v.CreatedAt, "UpdatedAt": v.UpdatedAt, "DeletedAt": nil, "name": v.Name, "type": v.Type, "status": v.Status, "desc": v.Desc, "parentID": v.ParentID, "children": children, "sysDictionaryDetails": details}
|
||||
return &dto.DictionaryResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, Name: v.Name, Type: v.Type, Status: v.Status, Desc: v.Desc, ParentID: v.ParentID, Children: children, SysDictionaryDetails: details}
|
||||
}
|
||||
func (s *DictionaryService) Dictionaries(ctx context.Context, page, size int, name, typ string, details bool) ([]map[string]any, int64, error) {
|
||||
func (s *DictionaryService) Dictionaries(ctx context.Context, page, size int, name, typ string, details bool) ([]*dto.DictionaryResponse, int64, error) {
|
||||
items, total, err := s.uc.ListDictionaries(ctx, page, size, name, typ, details)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]map[string]any, 0, len(items))
|
||||
out := make([]*dto.DictionaryResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, dictionaryDTO(v))
|
||||
}
|
||||
return out, total, nil
|
||||
}
|
||||
func (s *DictionaryService) Dictionary(ctx context.Context, id uint, typ string, status *bool, details bool) (map[string]any, error) {
|
||||
func (s *DictionaryService) Dictionary(ctx context.Context, id uint, typ string, status *bool, details bool) (*dto.DictionaryResponse, error) {
|
||||
v, err := s.uc.FindDictionary(ctx, id, typ, status, details)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dictionaryDTO(v), nil
|
||||
}
|
||||
func (s *DictionaryService) ExportDictionary(ctx context.Context, id uint) (map[string]any, error) {
|
||||
func (s *DictionaryService) ExportDictionary(ctx context.Context, id uint) (*dto.DictionaryExportResponse, error) {
|
||||
v, err := s.uc.ExportDictionary(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dictionaryDTO(v), nil
|
||||
details := make([]*dto.DictionaryDetailExportResponse, 0, len(v.Details))
|
||||
for _, detail := range v.Details {
|
||||
details = append(details, &dto.DictionaryDetailExportResponse{
|
||||
Label: detail.Label, Value: detail.Value, Extend: detail.Extend,
|
||||
Status: detail.Status, Sort: detail.Sort, Level: detail.Level, Path: detail.Path,
|
||||
})
|
||||
}
|
||||
return &dto.DictionaryExportResponse{
|
||||
Name: v.Name, Type: v.Type, Status: v.Status, Desc: v.Desc,
|
||||
SysDictionaryDetails: details,
|
||||
}, nil
|
||||
}
|
||||
func (s *DictionaryService) CreateDictionary(ctx context.Context, v *biz.Dictionary) error {
|
||||
return s.uc.CreateDictionary(ctx, v)
|
||||
|
|
@ -89,37 +99,37 @@ func (s *DictionaryService) CreateDictionaryDetailRequest(ctx context.Context, r
|
|||
func (s *DictionaryService) UpdateDictionaryDetailRequest(ctx context.Context, req *dto.DictionaryDetailRequest) error {
|
||||
return s.UpdateDictionaryDetail(ctx, detailDomain(req))
|
||||
}
|
||||
func detailDTO(v *biz.DictionaryDetail) map[string]any {
|
||||
children := make([]map[string]any, 0, len(v.Children))
|
||||
func detailDTO(v *biz.DictionaryDetail) *dto.DictionaryDetailResponse {
|
||||
children := make([]*dto.DictionaryDetailResponse, 0, len(v.Children))
|
||||
for _, x := range v.Children {
|
||||
children = append(children, detailDTO(x))
|
||||
}
|
||||
return map[string]any{"ID": v.ID, "CreatedAt": v.CreatedAt, "UpdatedAt": v.UpdatedAt, "DeletedAt": nil, "label": v.Label, "value": v.Value, "extend": v.Extend, "status": v.Status, "sort": v.Sort, "sysDictionaryID": v.DictionaryID, "parentID": v.ParentID, "level": v.Level, "path": v.Path, "disabled": !v.Status, "children": children}
|
||||
return &dto.DictionaryDetailResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, Label: v.Label, Value: v.Value, Extend: v.Extend, Status: v.Status, Sort: v.Sort, DictionaryID: v.DictionaryID, ParentID: v.ParentID, Level: v.Level, Path: v.Path, Disabled: !v.Status, Children: children}
|
||||
}
|
||||
func (s *DictionaryService) DictionaryDetails(ctx context.Context, page, size int, filter biz.DictionaryDetailFilter) ([]map[string]any, int64, error) {
|
||||
func (s *DictionaryService) DictionaryDetails(ctx context.Context, page, size int, filter biz.DictionaryDetailFilter) ([]*dto.DictionaryDetailResponse, int64, error) {
|
||||
items, total, err := s.uc.ListDictionaryDetails(ctx, page, size, filter)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]map[string]any, 0, len(items))
|
||||
out := make([]*dto.DictionaryDetailResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, detailDTO(v))
|
||||
}
|
||||
return out, total, nil
|
||||
}
|
||||
func (s *DictionaryService) DictionaryDetail(ctx context.Context, id uint) (map[string]any, error) {
|
||||
func (s *DictionaryService) DictionaryDetail(ctx context.Context, id uint) (*dto.DictionaryDetailResponse, error) {
|
||||
v, err := s.uc.FindDictionaryDetail(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return detailDTO(v), nil
|
||||
}
|
||||
func (s *DictionaryService) DictionaryTree(ctx context.Context, id uint, typ string) ([]map[string]any, error) {
|
||||
func (s *DictionaryService) DictionaryTree(ctx context.Context, id uint, typ string) ([]*dto.DictionaryDetailResponse, error) {
|
||||
items, err := s.uc.DictionaryDetailTree(ctx, id, typ)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make([]map[string]any, 0, len(items))
|
||||
out := make([]*dto.DictionaryDetailResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, detailDTO(v))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,12 +27,12 @@ func (s *DictionaryService) ImportDictionaryJSON(ctx context.Context, raw string
|
|||
}
|
||||
return s.uc.ImportDictionary(ctx, dictionary, details)
|
||||
}
|
||||
func (s *DictionaryService) DictionaryDetailsByParent(ctx context.Context, dictionaryID uint, parentID *uint, includeChildren bool) ([]map[string]any, error) {
|
||||
func (s *DictionaryService) DictionaryDetailsByParent(ctx context.Context, dictionaryID uint, parentID *uint, includeChildren bool) ([]*dto.DictionaryDetailResponse, error) {
|
||||
items, err := s.uc.DictionaryDetailsByParent(ctx, dictionaryID, parentID, includeChildren)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make([]map[string]any, 0, len(items))
|
||||
out := make([]*dto.DictionaryDetailResponse, 0, len(items))
|
||||
for _, item := range items {
|
||||
out = append(out, detailDTO(item))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
package dto
|
||||
|
||||
import "encoding/json"
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
type AnnouncementRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
|
|
@ -9,3 +12,19 @@ type AnnouncementRequest struct {
|
|||
UserID *uint `json:"userID"`
|
||||
Attachments json.RawMessage `json:"attachments"`
|
||||
}
|
||||
|
||||
type AnnouncementResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"DeletedAt"`
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
UserID *uint `json:"userID"`
|
||||
Attachments any `json:"attachments"`
|
||||
}
|
||||
|
||||
type SelectOptionResponse struct {
|
||||
Label string `json:"label"`
|
||||
Value uint `json:"value"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package dto
|
||||
|
||||
import "time"
|
||||
|
||||
type OperationRecordRequest struct {
|
||||
IP string
|
||||
Method string
|
||||
|
|
@ -44,3 +46,99 @@ type ErrorRecordRequest struct {
|
|||
Solution string `json:"solution"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type OperationRecordResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
DeletedAt any `json:"DeletedAt"`
|
||||
IP string `json:"ip"`
|
||||
Method string `json:"method"`
|
||||
Path string `json:"path"`
|
||||
Status int `json:"status"`
|
||||
LatencyMS int64 `json:"latency_ms"`
|
||||
Agent string `json:"agent"`
|
||||
ErrorMessage string `json:"error_message"`
|
||||
Body string `json:"body"`
|
||||
Response string `json:"resp"`
|
||||
UserID uint `json:"user_id"`
|
||||
RequestID string `json:"request_id"`
|
||||
TraceID string `json:"trace_id"`
|
||||
DeviceID string `json:"device_id"`
|
||||
User any `json:"user"`
|
||||
}
|
||||
|
||||
type LoginLogResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
DeletedAt any `json:"DeletedAt"`
|
||||
Username string `json:"username"`
|
||||
IP string `json:"ip"`
|
||||
Status bool `json:"status"`
|
||||
ErrorMessage string `json:"errorMessage"`
|
||||
Agent string `json:"agent"`
|
||||
UserID uint `json:"userId"`
|
||||
User any `json:"user"`
|
||||
}
|
||||
|
||||
type DataAccessLogResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
DeletedAt any `json:"DeletedAt"`
|
||||
EventType string `json:"eventType"`
|
||||
TargetTable string `json:"targetTable"`
|
||||
Operation string `json:"operation"`
|
||||
UserID uint `json:"userId"`
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
Scope int `json:"scope"`
|
||||
RequestID string `json:"requestId"`
|
||||
Method string `json:"method"`
|
||||
Path string `json:"path"`
|
||||
Detail string `json:"detail"`
|
||||
}
|
||||
|
||||
type ErrorRecordResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
DeletedAt any `json:"DeletedAt"`
|
||||
Form string `json:"form"`
|
||||
Info string `json:"info"`
|
||||
Level string `json:"level"`
|
||||
RequestID string `json:"request_id"`
|
||||
TraceID string `json:"trace_id"`
|
||||
Solution string `json:"solution"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type LogDateResponse struct {
|
||||
Date string `json:"date"`
|
||||
FileCount int `json:"fileCount"`
|
||||
}
|
||||
|
||||
type LogDatesResponse struct {
|
||||
Month string `json:"month"`
|
||||
Dates []*LogDateResponse `json:"dates"`
|
||||
}
|
||||
|
||||
type LogFileResponse struct {
|
||||
Path string `json:"path"`
|
||||
Name string `json:"name"`
|
||||
Size int64 `json:"size"`
|
||||
ModifiedAt time.Time `json:"modifiedAt"`
|
||||
}
|
||||
|
||||
type LogFilesResponse struct {
|
||||
Date string `json:"date"`
|
||||
Files []*LogFileResponse `json:"files"`
|
||||
}
|
||||
|
||||
type LogContentResponse struct {
|
||||
Date string `json:"date"`
|
||||
Path string `json:"path"`
|
||||
Content string `json:"content"`
|
||||
LineCount int `json:"lineCount"`
|
||||
NextCursor int64 `json:"nextCursor"`
|
||||
HasMore bool `json:"hasMore"`
|
||||
LimitedByBytes bool `json:"limitedByBytes"`
|
||||
Size int64 `json:"size"`
|
||||
ModifiedAt time.Time `json:"modifiedAt"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,9 +27,11 @@ type SetDataScopeRequest struct {
|
|||
}
|
||||
|
||||
type AuthorityResponse struct {
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
AuthorityName string `json:"authorityName"`
|
||||
ParentID *uint `json:"parentId"`
|
||||
DataScope int `json:"dataScope"`
|
||||
DefaultRouter string `json:"defaultRouter"`
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
AuthorityName string `json:"authorityName"`
|
||||
ParentID *uint `json:"parentId"`
|
||||
Children []*AuthorityResponse `json:"children"`
|
||||
Menus []any `json:"menus"`
|
||||
DataScope int `json:"dataScope"`
|
||||
DefaultRouter string `json:"defaultRouter"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package dto
|
||||
|
||||
import "time"
|
||||
|
||||
type ExportConditionRequest struct {
|
||||
From string `json:"from"`
|
||||
Column string `json:"column"`
|
||||
|
|
@ -24,3 +26,33 @@ type ExportTemplateRequest struct {
|
|||
Conditions []ExportConditionRequest `json:"conditions"`
|
||||
Joins []ExportJoinRequest `json:"joinTemplate"`
|
||||
}
|
||||
|
||||
type ExportConditionResponse struct {
|
||||
From string `json:"from"`
|
||||
Column string `json:"column"`
|
||||
Operator string `json:"operator"`
|
||||
}
|
||||
|
||||
type ExportJoinResponse struct {
|
||||
Join string `json:"joins"`
|
||||
Table string `json:"table"`
|
||||
On string `json:"on"`
|
||||
}
|
||||
|
||||
type ExportTemplateResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"DeletedAt"`
|
||||
DBName string `json:"dbName"`
|
||||
Name string `json:"name"`
|
||||
TableName string `json:"tableName"`
|
||||
TemplateID string `json:"templateID"`
|
||||
TemplateInfo string `json:"templateInfo"`
|
||||
SQL string `json:"sql"`
|
||||
ImportSQL string `json:"importSql"`
|
||||
Limit *int `json:"limit"`
|
||||
Order string `json:"order"`
|
||||
Conditions []ExportConditionResponse `json:"conditions"`
|
||||
Joins []ExportJoinResponse `json:"joinTemplate"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,46 @@ package dto
|
|||
|
||||
import "time"
|
||||
|
||||
type MediaResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"DeletedAt"`
|
||||
Name string `json:"name"`
|
||||
ClassID int `json:"classId"`
|
||||
URL string `json:"url"`
|
||||
Tag string `json:"tag"`
|
||||
Key string `json:"key"`
|
||||
Size int64 `json:"size"`
|
||||
Mime string `json:"mime"`
|
||||
MD5 string `json:"md5"`
|
||||
UserID uint `json:"userId"`
|
||||
}
|
||||
|
||||
type MediaCategoryResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"DeletedAt"`
|
||||
Name string `json:"name"`
|
||||
PID uint `json:"pid"`
|
||||
Children []*MediaCategoryResponse `json:"children"`
|
||||
}
|
||||
|
||||
type StorageObjectResponse struct {
|
||||
Name string `json:"name"`
|
||||
Key string `json:"key"`
|
||||
URL string `json:"url"`
|
||||
Size int64 `json:"size"`
|
||||
}
|
||||
|
||||
type InitUploadResponse struct {
|
||||
Instant bool `json:"instant"`
|
||||
UploadID uint `json:"uploadId,omitempty"`
|
||||
UploadedChunks []int `json:"uploadedChunks"`
|
||||
Media *MediaResponse `json:"media"`
|
||||
}
|
||||
|
||||
type MediaListRequest struct {
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package dto
|
||||
|
||||
import "time"
|
||||
|
||||
type DictionaryRequest struct {
|
||||
ID uint `json:"ID" form:"ID"`
|
||||
Name string `json:"name" form:"name"`
|
||||
|
|
@ -47,3 +49,101 @@ type APITokenListRequest struct {
|
|||
UserID uint `json:"userId"`
|
||||
Status *bool `json:"status"`
|
||||
}
|
||||
|
||||
type APITokenResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"DeletedAt"`
|
||||
UserID uint `json:"userId"`
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
Token string `json:"token"`
|
||||
Status bool `json:"status"`
|
||||
ExpiresAt time.Time `json:"expiresAt"`
|
||||
Remark string `json:"remark"`
|
||||
User *UserResponse `json:"user"`
|
||||
}
|
||||
|
||||
type SecurityConfigResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CaptchaOpen int `json:"captchaOpen"`
|
||||
CaptchaTimeout int `json:"captchaTimeout"`
|
||||
KeyLong int `json:"keyLong"`
|
||||
ImgWidth int `json:"imgWidth"`
|
||||
ImgHeight int `json:"imgHeight"`
|
||||
PwdMinLength int `json:"pwdMinLength"`
|
||||
PwdRequireUpper bool `json:"pwdRequireUpper"`
|
||||
PwdRequireLower bool `json:"pwdRequireLower"`
|
||||
PwdRequireDigit bool `json:"pwdRequireDigit"`
|
||||
PwdRequireSpecial bool `json:"pwdRequireSpecial"`
|
||||
LimitEnable bool `json:"limitEnable"`
|
||||
LimitWindow int `json:"limitWindow"`
|
||||
LimitCount int `json:"limitCount"`
|
||||
LockEnable bool `json:"lockEnable"`
|
||||
LockThreshold int `json:"lockThreshold"`
|
||||
LockDuration int `json:"lockDuration"`
|
||||
PwdExpireEnable bool `json:"pwdExpireEnable"`
|
||||
PwdExpireDays int `json:"pwdExpireDays"`
|
||||
ForceNewUserChangePassword bool `json:"forceNewUserChangePassword"`
|
||||
}
|
||||
|
||||
type SystemParameterResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"DeletedAt"`
|
||||
Name string `json:"name"`
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
Desc string `json:"desc"`
|
||||
}
|
||||
|
||||
type DictionaryResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"DeletedAt"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Status bool `json:"status"`
|
||||
Desc string `json:"desc"`
|
||||
ParentID *uint `json:"parentID"`
|
||||
Children []*DictionaryResponse `json:"children"`
|
||||
SysDictionaryDetails []*DictionaryDetailResponse `json:"sysDictionaryDetails"`
|
||||
}
|
||||
|
||||
type DictionaryDetailResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"DeletedAt"`
|
||||
Label string `json:"label"`
|
||||
Value string `json:"value"`
|
||||
Extend string `json:"extend"`
|
||||
Status bool `json:"status"`
|
||||
Sort int `json:"sort"`
|
||||
DictionaryID uint `json:"sysDictionaryID"`
|
||||
ParentID *uint `json:"parentID"`
|
||||
Level int `json:"level"`
|
||||
Path string `json:"path"`
|
||||
Disabled bool `json:"disabled"`
|
||||
Children []*DictionaryDetailResponse `json:"children"`
|
||||
}
|
||||
|
||||
type DictionaryExportResponse struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Status bool `json:"status"`
|
||||
Desc string `json:"desc"`
|
||||
SysDictionaryDetails []*DictionaryDetailExportResponse `json:"sysDictionaryDetails"`
|
||||
}
|
||||
|
||||
type DictionaryDetailExportResponse struct {
|
||||
Label string `json:"label"`
|
||||
Value string `json:"value"`
|
||||
Extend string `json:"extend"`
|
||||
Status bool `json:"status"`
|
||||
Sort int `json:"sort"`
|
||||
Level int `json:"level"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package dto
|
||||
|
||||
import "time"
|
||||
|
||||
type LoginRequest struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
|
|
@ -71,3 +73,60 @@ type LoginLogRequest struct {
|
|||
Agent string
|
||||
UserID uint
|
||||
}
|
||||
|
||||
type UserResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"DeletedAt"`
|
||||
UUID string `json:"uuid"`
|
||||
Username string `json:"userName"`
|
||||
NickName string `json:"nickName"`
|
||||
HeaderImg string `json:"headerImg"`
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
Authority *AuthorityResponse `json:"authority"`
|
||||
Authorities []*AuthorityResponse `json:"authorities"`
|
||||
DeptID uint `json:"deptId"`
|
||||
Department any `json:"dept"`
|
||||
Departments []*DepartmentResponse `json:"departments"`
|
||||
Positions []*PositionResponse `json:"positions"`
|
||||
Phone string `json:"phone"`
|
||||
Email string `json:"email"`
|
||||
Enable int `json:"enable"`
|
||||
OriginSetting map[string]any `json:"originSetting"`
|
||||
}
|
||||
|
||||
type ServerInfoResponse struct {
|
||||
OS ServerOSResponse `json:"os"`
|
||||
CPU ServerCPUResponse `json:"cpu"`
|
||||
RAM ServerRAMResponse `json:"ram"`
|
||||
Disk []ServerDiskResponse `json:"disk"`
|
||||
}
|
||||
|
||||
type ServerOSResponse struct {
|
||||
GOOS string `json:"goos"`
|
||||
NumCPU int `json:"numCpu"`
|
||||
Compiler string `json:"compiler"`
|
||||
GoVersion string `json:"goVersion"`
|
||||
NumGoroutine int `json:"numGoroutine"`
|
||||
}
|
||||
|
||||
type ServerCPUResponse struct {
|
||||
CPUs []float64 `json:"cpus"`
|
||||
Cores int `json:"cores"`
|
||||
}
|
||||
|
||||
type ServerRAMResponse struct {
|
||||
UsedMB uint64 `json:"usedMb"`
|
||||
TotalMB uint64 `json:"totalMb"`
|
||||
UsedPercent int `json:"usedPercent"`
|
||||
}
|
||||
|
||||
type ServerDiskResponse struct {
|
||||
MountPoint string `json:"mountPoint"`
|
||||
UsedMB uint64 `json:"usedMb"`
|
||||
UsedGB uint64 `json:"usedGb"`
|
||||
TotalMB uint64 `json:"totalMb"`
|
||||
TotalGB uint64 `json:"totalGb"`
|
||||
UsedPercent int `json:"usedPercent"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package dto
|
||||
|
||||
import "kra/internal/conf"
|
||||
import "encoding/json"
|
||||
|
||||
type SecurityConfigRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
|
|
@ -26,84 +26,5 @@ type SecurityConfigRequest struct {
|
|||
}
|
||||
|
||||
type SetSystemConfigRequest struct {
|
||||
Config struct {
|
||||
Data *struct {
|
||||
Database *struct {
|
||||
Driver string `json:"driver"`
|
||||
Source string `json:"source"`
|
||||
Host string `json:"host"`
|
||||
Port string `json:"port"`
|
||||
User string `json:"user"`
|
||||
Password string `json:"password"`
|
||||
Name string `json:"name"`
|
||||
Config string `json:"config"`
|
||||
Path string `json:"path"`
|
||||
Prefix string `json:"prefix"`
|
||||
Engine string `json:"engine"`
|
||||
LogMode string `json:"log_mode"`
|
||||
MaxIdleConns int32 `json:"max_idle_conns"`
|
||||
MaxOpenConns int32 `json:"max_open_conns"`
|
||||
ConnMaxLifetime int32 `json:"conn_max_lifetime"`
|
||||
Singular bool `json:"singular"`
|
||||
} `json:"database"`
|
||||
Redis *struct {
|
||||
Network string `json:"network"`
|
||||
Addr string `json:"addr"`
|
||||
ReadTimeout string `json:"read_timeout"`
|
||||
WriteTimeout string `json:"write_timeout"`
|
||||
Name string `json:"name"`
|
||||
Password string `json:"password"`
|
||||
DB int32 `json:"db"`
|
||||
UseCluster bool `json:"use_cluster"`
|
||||
ClusterAddrs []string `json:"cluster_addrs"`
|
||||
} `json:"redis"`
|
||||
DatabaseList []*conf.Data_Database `json:"database_list"`
|
||||
RedisList []*conf.Data_Redis `json:"redis_list"`
|
||||
Mongo *conf.Data_Mongo `json:"mongo"`
|
||||
} `json:"data"`
|
||||
Admin struct {
|
||||
RouterPrefix string `json:"routerPrefix"`
|
||||
System struct {
|
||||
UseRedis bool `json:"useRedis"`
|
||||
UseMultipoint bool `json:"useMultipoint"`
|
||||
UseStrictAuth bool `json:"useStrictAuth"`
|
||||
DisableAutoMigrate bool `json:"disableAutoMigrate"`
|
||||
UseMongo bool `json:"useMongo"`
|
||||
} `json:"system"`
|
||||
JWT struct {
|
||||
SigningKey string `json:"signingKey"`
|
||||
ExpiresTime string `json:"expiresTime"`
|
||||
BufferTime string `json:"bufferTime"`
|
||||
Issuer string `json:"issuer"`
|
||||
} `json:"jwt"`
|
||||
Captcha struct {
|
||||
KeyLong int32 `json:"keyLong"`
|
||||
ImgWidth int32 `json:"imgWidth"`
|
||||
ImgHeight int32 `json:"imgHeight"`
|
||||
StoreExpiration string `json:"storeExpiration"`
|
||||
} `json:"captcha"`
|
||||
Local struct {
|
||||
StorePath string `json:"storePath"`
|
||||
PathPrefix string `json:"pathPrefix"`
|
||||
} `json:"local"`
|
||||
Media struct {
|
||||
SessionTTL int32 `json:"sessionTtl"`
|
||||
MaxFileSize int64 `json:"maxFileSize"`
|
||||
} `json:"media"`
|
||||
Storage *conf.AdminBackend_Storage `json:"storage"`
|
||||
Zap *conf.AdminBackend_Zap `json:"zap"`
|
||||
Cors *conf.AdminBackend_CORS `json:"cors"`
|
||||
App *conf.AdminBackend_App `json:"app"`
|
||||
} `json:"admin"`
|
||||
Email *struct {
|
||||
To string `json:"to"`
|
||||
From string `json:"from"`
|
||||
Host string `json:"host"`
|
||||
Secret string `json:"secret"`
|
||||
Nickname string `json:"nickname"`
|
||||
Port int32 `json:"port"`
|
||||
IsSSL bool `json:"is-ssl"`
|
||||
IsLoginAuth bool `json:"is-loginauth"`
|
||||
} `json:"email"`
|
||||
} `json:"config"`
|
||||
Config json.RawMessage `json:"config"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
package dto
|
||||
|
||||
import "encoding/json"
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
type TaskRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
|
|
@ -26,3 +29,44 @@ type ToggleTaskRequest struct {
|
|||
ID uint `json:"ID"`
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
type TaskResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"DeletedAt"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Spec string `json:"spec"`
|
||||
WithSeconds bool `json:"withSeconds"`
|
||||
ExecutorType string `json:"executorType"`
|
||||
MethodName string `json:"methodName"`
|
||||
Params json.RawMessage `json:"params"`
|
||||
HTTPURL string `json:"httpUrl"`
|
||||
HTTPMethod string `json:"httpMethod"`
|
||||
HTTPHeader json.RawMessage `json:"httpHeader"`
|
||||
HTTPBody string `json:"httpBody"`
|
||||
HTTPAllowPrivate bool `json:"httpAllowPrivate"`
|
||||
Enabled bool `json:"enabled"`
|
||||
NextRunAt *time.Time `json:"nextRunAt"`
|
||||
}
|
||||
|
||||
type TaskLogResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
DeletedAt any `json:"DeletedAt"`
|
||||
TaskID uint `json:"taskId"`
|
||||
TaskName string `json:"taskName"`
|
||||
TriggerType string `json:"triggerType"`
|
||||
StartedAt time.Time `json:"startedAt"`
|
||||
FinishedAt time.Time `json:"finishedAt"`
|
||||
DurationMS int64 `json:"durationMs"`
|
||||
Status string `json:"status"`
|
||||
ErrorMsg string `json:"errorMsg"`
|
||||
Output string `json:"output"`
|
||||
}
|
||||
|
||||
type TaskMethodResponse struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,18 @@
|
|||
package dto
|
||||
|
||||
import "time"
|
||||
|
||||
type VersionResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"DeletedAt"`
|
||||
VersionName string `json:"versionName"`
|
||||
VersionCode string `json:"versionCode"`
|
||||
Description string `json:"description"`
|
||||
VersionData string `json:"versionData"`
|
||||
}
|
||||
|
||||
type VersionMenuMetaRequest struct {
|
||||
ActiveName string `json:"activeName"`
|
||||
KeepAlive bool `json:"keepAlive"`
|
||||
|
|
|
|||
|
|
@ -83,19 +83,19 @@ func (s *ExportService) CreateRequest(ctx context.Context, req *dto.ExportTempla
|
|||
func (s *ExportService) UpdateRequest(ctx context.Context, req *dto.ExportTemplateRequest) error {
|
||||
return s.Update(ctx, exportTemplateDomain(req))
|
||||
}
|
||||
func (s *ExportService) TemplatesFilter(ctx context.Context, page, size int, name, tableName, templateID string, start, end *time.Time) ([]map[string]any, int64, error) {
|
||||
func (s *ExportService) TemplatesFilter(ctx context.Context, page, size int, name, tableName, templateID string, start, end *time.Time) ([]*dto.ExportTemplateResponse, int64, error) {
|
||||
return s.Templates(ctx, page, size, &biz.ExportTemplate{Name: name, TableName: tableName, TemplateID: templateID, StartCreatedAt: start, EndCreatedAt: end})
|
||||
}
|
||||
func exportDTO(v *biz.ExportTemplate) map[string]any {
|
||||
conditions := make([]map[string]any, 0, len(v.Conditions))
|
||||
func exportDTO(v *biz.ExportTemplate) *dto.ExportTemplateResponse {
|
||||
conditions := make([]dto.ExportConditionResponse, 0, len(v.Conditions))
|
||||
for _, x := range v.Conditions {
|
||||
conditions = append(conditions, map[string]any{"from": x.From, "column": x.Column, "operator": x.Operator})
|
||||
conditions = append(conditions, dto.ExportConditionResponse{From: x.From, Column: x.Column, Operator: x.Operator})
|
||||
}
|
||||
joins := make([]map[string]any, 0, len(v.Joins))
|
||||
joins := make([]dto.ExportJoinResponse, 0, len(v.Joins))
|
||||
for _, x := range v.Joins {
|
||||
joins = append(joins, map[string]any{"joins": x.Join, "table": x.Table, "on": x.On})
|
||||
joins = append(joins, dto.ExportJoinResponse{Join: x.Join, Table: x.Table, On: x.On})
|
||||
}
|
||||
return map[string]any{"ID": v.ID, "CreatedAt": v.CreatedAt, "UpdatedAt": v.UpdatedAt, "DeletedAt": nil, "dbName": v.DBName, "name": v.Name, "tableName": v.TableName, "templateID": v.TemplateID, "templateInfo": v.TemplateInfo, "sql": v.SQL, "importSql": v.ImportSQL, "limit": v.Limit, "order": v.Order, "conditions": conditions, "joinTemplate": joins}
|
||||
return &dto.ExportTemplateResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, DBName: v.DBName, Name: v.Name, TableName: v.TableName, TemplateID: v.TemplateID, TemplateInfo: v.TemplateInfo, SQL: v.SQL, ImportSQL: v.ImportSQL, Limit: v.Limit, Order: v.Order, Conditions: conditions, Joins: joins}
|
||||
}
|
||||
func (s *ExportService) Create(ctx context.Context, v *biz.ExportTemplate) error {
|
||||
return s.uc.CreateExportTemplate(ctx, v)
|
||||
|
|
@ -106,19 +106,19 @@ func (s *ExportService) Update(ctx context.Context, v *biz.ExportTemplate) error
|
|||
func (s *ExportService) Delete(ctx context.Context, ids []uint) error {
|
||||
return s.uc.DeleteExportTemplates(ctx, ids)
|
||||
}
|
||||
func (s *ExportService) Template(ctx context.Context, id uint, tid string) (map[string]any, error) {
|
||||
func (s *ExportService) Template(ctx context.Context, id uint, tid string) (*dto.ExportTemplateResponse, error) {
|
||||
v, err := s.uc.FindExportTemplate(ctx, id, tid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return exportDTO(v), nil
|
||||
}
|
||||
func (s *ExportService) Templates(ctx context.Context, page, size int, q *biz.ExportTemplate) ([]map[string]any, int64, error) {
|
||||
func (s *ExportService) Templates(ctx context.Context, page, size int, q *biz.ExportTemplate) ([]*dto.ExportTemplateResponse, int64, error) {
|
||||
items, total, err := s.uc.ListExportTemplates(ctx, page, size, q)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]map[string]any, 0, len(items))
|
||||
out := make([]*dto.ExportTemplateResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, exportDTO(v))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,36 +19,36 @@ func NewMediaService(uc *biz.MediaUsecase, settings biz.RuntimeSettings) *MediaS
|
|||
func (s *MediaService) MediaConfig() biz.MediaSettings {
|
||||
return s.settings.MediaSettings()
|
||||
}
|
||||
func mediaDTO(v *biz.MediaFile) map[string]any {
|
||||
return map[string]any{"ID": v.ID, "CreatedAt": v.CreatedAt, "UpdatedAt": v.UpdatedAt, "DeletedAt": nil, "name": v.Name, "classId": v.CategoryID, "url": v.URL, "tag": v.Tag, "key": v.Key, "size": v.Size, "mime": v.Mime, "md5": v.MD5, "userId": v.UserID}
|
||||
func mediaDTO(v *biz.MediaFile) *dto.MediaResponse {
|
||||
return &dto.MediaResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, Name: v.Name, ClassID: v.CategoryID, URL: v.URL, Tag: v.Tag, Key: v.Key, Size: v.Size, Mime: v.Mime, MD5: v.MD5, UserID: v.UserID}
|
||||
}
|
||||
func categoryDTO(v *biz.AttachmentCategory) map[string]any {
|
||||
children := make([]map[string]any, 0, len(v.Children))
|
||||
func categoryDTO(v *biz.AttachmentCategory) *dto.MediaCategoryResponse {
|
||||
children := make([]*dto.MediaCategoryResponse, 0, len(v.Children))
|
||||
for _, x := range v.Children {
|
||||
children = append(children, categoryDTO(x))
|
||||
}
|
||||
return map[string]any{"ID": v.ID, "CreatedAt": v.CreatedAt, "UpdatedAt": v.UpdatedAt, "DeletedAt": nil, "name": v.Name, "pid": v.ParentID, "children": children}
|
||||
return &dto.MediaCategoryResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, Name: v.Name, PID: v.ParentID, Children: children}
|
||||
}
|
||||
func (s *MediaService) Upload(ctx context.Context, userID uint, name, mime string, categoryID int, reader io.Reader, save bool) (map[string]any, error) {
|
||||
func (s *MediaService) Upload(ctx context.Context, userID uint, name, mime string, categoryID int, reader io.Reader, save bool) (*dto.MediaResponse, error) {
|
||||
v, err := s.uc.Upload(ctx, userID, name, mime, categoryID, reader, save)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return mediaDTO(v), nil
|
||||
}
|
||||
func (s *MediaService) Media(ctx context.Context, id uint) (map[string]any, error) {
|
||||
func (s *MediaService) Media(ctx context.Context, id uint) (*dto.MediaResponse, error) {
|
||||
v, err := s.uc.FindMedia(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return mediaDTO(v), nil
|
||||
}
|
||||
func (s *MediaService) MediaList(ctx context.Context, filter biz.MediaFilter) ([]map[string]any, int64, error) {
|
||||
func (s *MediaService) MediaList(ctx context.Context, filter biz.MediaFilter) ([]*dto.MediaResponse, int64, error) {
|
||||
items, total, err := s.uc.ListMedia(ctx, filter)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]map[string]any, 0, len(items))
|
||||
out := make([]*dto.MediaResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, mediaDTO(v))
|
||||
}
|
||||
|
|
@ -68,23 +68,23 @@ func (s *MediaService) ImportURLRequests(ctx context.Context, values []dto.Impor
|
|||
}
|
||||
return s.ImportURLs(ctx, items)
|
||||
}
|
||||
func (s *MediaService) Storage(ctx context.Context, prefix, cursor string, limit int) ([]map[string]any, string, bool, error) {
|
||||
func (s *MediaService) Storage(ctx context.Context, prefix, cursor string, limit int) ([]*dto.StorageObjectResponse, string, bool, error) {
|
||||
items, next, more, err := s.uc.ListStorage(ctx, prefix, cursor, limit)
|
||||
if err != nil {
|
||||
return nil, "", false, err
|
||||
}
|
||||
out := make([]map[string]any, 0, len(items))
|
||||
out := make([]*dto.StorageObjectResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, map[string]any{"name": v.Name, "key": v.Path, "url": v.URL, "size": v.Size})
|
||||
out = append(out, &dto.StorageObjectResponse{Name: v.Name, Key: v.Path, URL: v.URL, Size: v.Size})
|
||||
}
|
||||
return out, next, more, nil
|
||||
}
|
||||
func (s *MediaService) Categories(ctx context.Context) ([]map[string]any, error) {
|
||||
func (s *MediaService) Categories(ctx context.Context) ([]*dto.MediaCategoryResponse, error) {
|
||||
items, err := s.uc.ListCategories(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make([]map[string]any, 0, len(items))
|
||||
out := make([]*dto.MediaCategoryResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, categoryDTO(v))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,22 +3,24 @@ package service
|
|||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
func (s *MediaService) InitUpload(ctx context.Context, userID uint, name, hash string, size, chunkSize int64, total int) (map[string]any, error) {
|
||||
func (s *MediaService) InitUpload(ctx context.Context, userID uint, name, hash string, size, chunkSize int64, total int) (*dto.InitUploadResponse, error) {
|
||||
session, media, chunks, err := s.uc.InitUpload(ctx, userID, name, hash, size, chunkSize, total)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if media != nil {
|
||||
return map[string]any{"instant": true, "media": mediaDTO(media), "uploadedChunks": []int{}}, nil
|
||||
return &dto.InitUploadResponse{Instant: true, Media: mediaDTO(media), UploadedChunks: []int{}}, nil
|
||||
}
|
||||
return map[string]any{"instant": false, "uploadId": session.ID, "uploadedChunks": chunks, "media": nil}, nil
|
||||
return &dto.InitUploadResponse{Instant: false, UploadID: session.ID, UploadedChunks: chunks, Media: nil}, nil
|
||||
}
|
||||
func (s *MediaService) SaveChunk(ctx context.Context, userID, uploadID uint, index int, hash string, reader io.Reader) error {
|
||||
return s.uc.SaveChunk(ctx, userID, uploadID, index, hash, reader)
|
||||
}
|
||||
func (s *MediaService) CompleteUpload(ctx context.Context, userID, uploadID uint) (map[string]any, error) {
|
||||
func (s *MediaService) CompleteUpload(ctx context.Context, userID, uploadID uint) (*dto.MediaResponse, error) {
|
||||
v, err := s.uc.CompleteUpload(ctx, userID, uploadID, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -23,24 +23,24 @@ func (s *ParameterService) CreateParameterRequest(ctx context.Context, req *dto.
|
|||
func (s *ParameterService) UpdateParameterRequest(ctx context.Context, req *dto.SystemParameterRequest) error {
|
||||
return s.UpdateParameter(ctx, parameterDomain(req))
|
||||
}
|
||||
func (s *ParameterService) ParametersFilter(ctx context.Context, page, size int, name, key string, start, end *time.Time) ([]map[string]any, int64, error) {
|
||||
func (s *ParameterService) ParametersFilter(ctx context.Context, page, size int, name, key string, start, end *time.Time) ([]*dto.SystemParameterResponse, int64, error) {
|
||||
return s.Parameters(ctx, page, size, &biz.SystemParameter{Name: name, Key: key, StartCreatedAt: start, EndCreatedAt: end})
|
||||
}
|
||||
func parameterDTO(v *biz.SystemParameter) map[string]any {
|
||||
return map[string]any{"ID": v.ID, "CreatedAt": v.CreatedAt, "UpdatedAt": v.UpdatedAt, "DeletedAt": nil, "name": v.Name, "key": v.Key, "value": v.Value, "desc": v.Desc}
|
||||
func parameterDTO(v *biz.SystemParameter) *dto.SystemParameterResponse {
|
||||
return &dto.SystemParameterResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, Name: v.Name, Key: v.Key, Value: v.Value, Desc: v.Desc}
|
||||
}
|
||||
func (s *ParameterService) Parameters(ctx context.Context, page, size int, q *biz.SystemParameter) ([]map[string]any, int64, error) {
|
||||
func (s *ParameterService) Parameters(ctx context.Context, page, size int, q *biz.SystemParameter) ([]*dto.SystemParameterResponse, int64, error) {
|
||||
items, total, err := s.uc.ListParameters(ctx, page, size, q)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]map[string]any, 0, len(items))
|
||||
out := make([]*dto.SystemParameterResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, parameterDTO(v))
|
||||
}
|
||||
return out, total, nil
|
||||
}
|
||||
func (s *ParameterService) Parameter(ctx context.Context, id uint, key string) (map[string]any, error) {
|
||||
func (s *ParameterService) Parameter(ctx context.Context, id uint, key string) (*dto.SystemParameterResponse, error) {
|
||||
v, err := s.uc.FindParameter(ctx, id, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"kra/internal/biz"
|
||||
)
|
||||
|
||||
type PermissionService struct{ uc *biz.PermissionUsecase }
|
||||
|
||||
func NewPermissionService(uc *biz.PermissionUsecase) *PermissionService {
|
||||
return &PermissionService{uc: uc}
|
||||
}
|
||||
|
||||
func (s *PermissionService) SelectedButtons(ctx context.Context, authorityID, menuID uint) ([]uint, error) {
|
||||
return s.uc.SelectedButtons(ctx, authorityID, menuID)
|
||||
}
|
||||
|
||||
func (s *PermissionService) SetSelectedButtons(ctx context.Context, authorityID, menuID uint, ids []uint) error {
|
||||
return s.uc.SetSelectedButtons(ctx, authorityID, menuID, ids)
|
||||
}
|
||||
|
||||
func (s *PermissionService) CanRemoveButton(ctx context.Context, id uint) (bool, error) {
|
||||
return s.uc.CanRemoveButton(ctx, id)
|
||||
}
|
||||
|
|
@ -7,26 +7,26 @@ import (
|
|||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
func securityDTO(v *biz.SecurityConfig) map[string]any {
|
||||
return map[string]any{"ID": v.ID, "captchaOpen": v.CaptchaOpen, "captchaTimeout": v.CaptchaTimeout, "keyLong": v.KeyLong, "imgWidth": v.ImgWidth, "imgHeight": v.ImgHeight, "pwdMinLength": v.PwdMinLength, "pwdRequireUpper": v.PwdRequireUpper, "pwdRequireLower": v.PwdRequireLower, "pwdRequireDigit": v.PwdRequireDigit, "pwdRequireSpecial": v.PwdRequireSpecial, "limitEnable": v.LimitEnable, "limitWindow": v.LimitWindow, "limitCount": v.LimitCount, "lockEnable": v.LockEnable, "lockThreshold": v.LockThreshold, "lockDuration": v.LockDuration, "pwdExpireEnable": v.PwdExpireEnable, "pwdExpireDays": v.PwdExpireDays, "forceNewUserChangePassword": v.ForceNewUserChangePassword}
|
||||
func securityDTO(v *biz.SecurityConfig) *dto.SecurityConfigResponse {
|
||||
return &dto.SecurityConfigResponse{ID: v.ID, CaptchaOpen: v.CaptchaOpen, CaptchaTimeout: v.CaptchaTimeout, KeyLong: v.KeyLong, ImgWidth: v.ImgWidth, ImgHeight: v.ImgHeight, PwdMinLength: v.PwdMinLength, PwdRequireUpper: v.PwdRequireUpper, PwdRequireLower: v.PwdRequireLower, PwdRequireDigit: v.PwdRequireDigit, PwdRequireSpecial: v.PwdRequireSpecial, LimitEnable: v.LimitEnable, LimitWindow: v.LimitWindow, LimitCount: v.LimitCount, LockEnable: v.LockEnable, LockThreshold: v.LockThreshold, LockDuration: v.LockDuration, PwdExpireEnable: v.PwdExpireEnable, PwdExpireDays: v.PwdExpireDays, ForceNewUserChangePassword: v.ForceNewUserChangePassword}
|
||||
}
|
||||
func (s *SecurityService) CurrentSecurity(ctx context.Context) (*biz.SecurityConfig, error) {
|
||||
return s.uc.Current(ctx)
|
||||
}
|
||||
func (s *SecurityService) Security(ctx context.Context) (map[string]any, error) {
|
||||
func (s *SecurityService) Security(ctx context.Context) (*dto.SecurityConfigResponse, error) {
|
||||
value, err := s.CurrentSecurity(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return securityDTO(value), nil
|
||||
}
|
||||
func (s *SecurityService) SaveSecurity(ctx context.Context, value *biz.SecurityConfig) (map[string]any, error) {
|
||||
func (s *SecurityService) SaveSecurity(ctx context.Context, value *biz.SecurityConfig) (*dto.SecurityConfigResponse, error) {
|
||||
if err := s.uc.UpdateSecurity(ctx, value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return securityDTO(value), nil
|
||||
}
|
||||
func (s *SecurityService) SaveSecurityRequest(ctx context.Context, value *dto.SecurityConfigRequest) (map[string]any, error) {
|
||||
func (s *SecurityService) SaveSecurityRequest(ctx context.Context, value *dto.SecurityConfigRequest) (*dto.SecurityConfigResponse, error) {
|
||||
return s.SaveSecurity(ctx, &biz.SecurityConfig{
|
||||
ID: value.ID, CaptchaOpen: value.CaptchaOpen, CaptchaTimeout: value.CaptchaTimeout,
|
||||
KeyLong: value.KeyLong, ImgWidth: value.ImgWidth, ImgHeight: value.ImgHeight,
|
||||
|
|
|
|||
|
|
@ -4,16 +4,15 @@ import (
|
|||
"context"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/conf"
|
||||
)
|
||||
|
||||
type SystemConfigService struct {
|
||||
uc *biz.SystemConfigUsecase
|
||||
runtime *conf.Runtime
|
||||
uc *biz.SystemConfigUsecase
|
||||
settings biz.RuntimeSettings
|
||||
}
|
||||
|
||||
func NewSystemConfigService(uc *biz.SystemConfigUsecase, runtime *conf.Runtime) *SystemConfigService {
|
||||
return &SystemConfigService{uc: uc, runtime: runtime}
|
||||
func NewSystemConfigService(uc *biz.SystemConfigUsecase, settings biz.RuntimeSettings) *SystemConfigService {
|
||||
return &SystemConfigService{uc: uc, settings: settings}
|
||||
}
|
||||
|
||||
func (s *SystemConfigService) IsInitialized(ctx context.Context) (bool, error) {
|
||||
|
|
|
|||
|
|
@ -4,125 +4,23 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"kra/internal/conf"
|
||||
"kra/internal/service/dto"
|
||||
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func (s *SystemConfigService) PersistConfig(ctx context.Context) error {
|
||||
return s.uc.PersistConfig(ctx)
|
||||
}
|
||||
|
||||
func (s *SystemConfigService) PersistAdminConfig(ctx context.Context, value *conf.AdminBackend) error {
|
||||
raw, err := protojson.MarshalOptions{UseProtoNames: true}.Marshal(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return s.uc.PersistAdminConfig(ctx, raw)
|
||||
func (s *SystemConfigService) ReloadConfig(ctx context.Context) error {
|
||||
return s.uc.ReloadConfig(ctx)
|
||||
}
|
||||
|
||||
func (s *SystemConfigService) ReloadConfig(ctx context.Context) error { return s.uc.ReloadConfig(ctx) }
|
||||
func (s *SystemConfigService) DiskMountPoints() []string { return s.uc.DiskMountPoints() }
|
||||
|
||||
func (s *SystemConfigService) DiskMountPoints() []string {
|
||||
config := s.runtime.Admin()
|
||||
if config == nil {
|
||||
return nil
|
||||
}
|
||||
points := make([]string, 0, len(config.DiskList))
|
||||
for _, item := range config.DiskList {
|
||||
if item != nil && item.MountPoint != "" {
|
||||
points = append(points, item.MountPoint)
|
||||
}
|
||||
}
|
||||
return points
|
||||
}
|
||||
|
||||
func (s *SystemConfigService) SystemConfig() map[string]any {
|
||||
admin := map[string]any{"routerPrefix": ""}
|
||||
email := map[string]any{}
|
||||
config := s.runtime.Admin()
|
||||
if config == nil {
|
||||
return map[string]any{"config": map[string]any{"admin": admin, "email": email, "data": map[string]any{}}}
|
||||
}
|
||||
admin["routerPrefix"] = config.RouterPrefix
|
||||
if config.System != nil {
|
||||
admin["system"] = map[string]any{"useRedis": config.System.UseRedis, "useMultipoint": config.System.UseMultipoint, "useStrictAuth": config.System.UseStrictAuth, "disableAutoMigrate": config.System.DisableAutoMigrate, "useMongo": config.System.UseMongo}
|
||||
}
|
||||
if config.Jwt != nil {
|
||||
admin["jwt"] = map[string]any{"signingKey": "******", "expiresTime": config.Jwt.ExpiresTime.AsDuration().String(), "bufferTime": config.Jwt.BufferTime.AsDuration().String(), "issuer": config.Jwt.Issuer}
|
||||
}
|
||||
if config.Captcha != nil {
|
||||
admin["captcha"] = map[string]any{"keyLong": config.Captcha.KeyLong, "imgWidth": config.Captcha.ImgWidth, "imgHeight": config.Captcha.ImgHeight, "storeExpiration": config.Captcha.StoreExpiration.AsDuration().String()}
|
||||
}
|
||||
if config.Local != nil {
|
||||
admin["local"] = map[string]any{"storePath": config.Local.StorePath, "pathPrefix": config.Local.PathPrefix}
|
||||
}
|
||||
if config.Media != nil {
|
||||
admin["media"] = map[string]any{"sessionTtl": config.Media.SessionTtl, "maxFileSize": config.Media.MaxFileSize}
|
||||
}
|
||||
if config.Email != nil {
|
||||
email = map[string]any{"to": config.Email.To, "from": config.Email.From, "host": config.Email.Host, "secret": "******", "nickname": config.Email.Nickname, "port": config.Email.Port, "is-ssl": config.Email.IsSsl, "is-loginauth": config.Email.IsLoginAuth}
|
||||
}
|
||||
if config.Storage != nil {
|
||||
storage := proto.Clone(config.Storage).(*conf.AdminBackend_Storage)
|
||||
maskStorageSecrets(storage)
|
||||
admin["storage"] = storage
|
||||
}
|
||||
if config.Zap != nil {
|
||||
admin["zap"] = config.Zap
|
||||
}
|
||||
if config.Cors != nil {
|
||||
admin["cors"] = config.Cors
|
||||
}
|
||||
if config.App != nil {
|
||||
admin["app"] = config.App
|
||||
}
|
||||
data := s.runtime.Data()
|
||||
if data != nil {
|
||||
if data.Database != nil {
|
||||
data.Database.Password = "******"
|
||||
}
|
||||
if data.Redis != nil {
|
||||
data.Redis.Password = "******"
|
||||
}
|
||||
if data.Mongo != nil {
|
||||
data.Mongo.Password = "******"
|
||||
}
|
||||
for _, database := range data.DatabaseList {
|
||||
if database != nil {
|
||||
database.Password = "******"
|
||||
}
|
||||
}
|
||||
for _, redis := range data.RedisList {
|
||||
if redis != nil {
|
||||
redis.Password = "******"
|
||||
}
|
||||
}
|
||||
}
|
||||
dataMap := map[string]any{}
|
||||
if raw, err := (protojson.MarshalOptions{UseProtoNames: true}).Marshal(data); err == nil {
|
||||
_ = json.Unmarshal(raw, &dataMap)
|
||||
}
|
||||
return map[string]any{"config": map[string]any{"admin": admin, "email": email, "data": dataMap}}
|
||||
func (s *SystemConfigService) SystemConfig() (json.RawMessage, error) {
|
||||
return s.uc.ConfigurationJSON()
|
||||
}
|
||||
|
||||
func (s *SystemConfigService) SaveSystemConfig(ctx context.Context, req *dto.SetSystemConfigRequest) error {
|
||||
config := s.runtime.Admin()
|
||||
if config == nil {
|
||||
return nil
|
||||
}
|
||||
next := proto.Clone(config).(*conf.AdminBackend)
|
||||
applyAdminConfig(next, req)
|
||||
data := applyDataConfig(s.runtime.Data(), req)
|
||||
dataRaw, err := protojson.MarshalOptions{UseProtoNames: true}.Marshal(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
adminRaw, err := protojson.MarshalOptions{UseProtoNames: true}.Marshal(next)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return s.uc.PersistRuntimeConfig(ctx, dataRaw, adminRaw)
|
||||
return s.uc.SaveConfigurationJSON(ctx, req.Config)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,197 +0,0 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"kra/internal/conf"
|
||||
"kra/internal/service/dto"
|
||||
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
)
|
||||
|
||||
func applyAdminConfig(next *conf.AdminBackend, req *dto.SetSystemConfigRequest) {
|
||||
next.RouterPrefix = req.Config.Admin.RouterPrefix
|
||||
if next.System == nil {
|
||||
next.System = &conf.AdminBackend_System{}
|
||||
}
|
||||
next.System.UseRedis = req.Config.Admin.System.UseRedis
|
||||
next.System.UseMultipoint = req.Config.Admin.System.UseMultipoint
|
||||
next.System.UseStrictAuth = req.Config.Admin.System.UseStrictAuth
|
||||
next.System.DisableAutoMigrate = req.Config.Admin.System.DisableAutoMigrate
|
||||
next.System.UseMongo = req.Config.Admin.System.UseMongo
|
||||
if req.Config.Admin.Zap != nil {
|
||||
next.Zap = req.Config.Admin.Zap
|
||||
}
|
||||
if req.Config.Admin.Cors != nil {
|
||||
next.Cors = req.Config.Admin.Cors
|
||||
}
|
||||
if req.Config.Admin.App != nil {
|
||||
next.App = req.Config.Admin.App
|
||||
}
|
||||
applyJWTConfig(next, req)
|
||||
applyCaptchaConfig(next, req)
|
||||
applyMediaConfig(next, req)
|
||||
if req.Config.Admin.Storage != nil {
|
||||
preserveStorageSecrets(req.Config.Admin.Storage, next.Storage)
|
||||
next.Storage = req.Config.Admin.Storage
|
||||
}
|
||||
if next.Email != nil && req.Config.Email != nil {
|
||||
next.Email.To, next.Email.From, next.Email.Host = req.Config.Email.To, req.Config.Email.From, req.Config.Email.Host
|
||||
next.Email.Nickname, next.Email.Port = req.Config.Email.Nickname, req.Config.Email.Port
|
||||
next.Email.IsSsl, next.Email.IsLoginAuth = req.Config.Email.IsSSL, req.Config.Email.IsLoginAuth
|
||||
if req.Config.Email.Secret != "" && req.Config.Email.Secret != "******" {
|
||||
next.Email.Secret = req.Config.Email.Secret
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func applyJWTConfig(next *conf.AdminBackend, req *dto.SetSystemConfigRequest) {
|
||||
if next.Jwt == nil {
|
||||
return
|
||||
}
|
||||
if req.Config.Admin.JWT.SigningKey != "" && req.Config.Admin.JWT.SigningKey != "******" {
|
||||
next.Jwt.SigningKey = req.Config.Admin.JWT.SigningKey
|
||||
}
|
||||
if req.Config.Admin.JWT.Issuer != "" {
|
||||
next.Jwt.Issuer = req.Config.Admin.JWT.Issuer
|
||||
}
|
||||
if value, err := time.ParseDuration(req.Config.Admin.JWT.ExpiresTime); err == nil && value > 0 {
|
||||
next.Jwt.ExpiresTime = durationpb.New(value)
|
||||
}
|
||||
if value, err := time.ParseDuration(req.Config.Admin.JWT.BufferTime); err == nil && value >= 0 {
|
||||
next.Jwt.BufferTime = durationpb.New(value)
|
||||
}
|
||||
}
|
||||
|
||||
func applyCaptchaConfig(next *conf.AdminBackend, req *dto.SetSystemConfigRequest) {
|
||||
if next.Captcha != nil {
|
||||
if req.Config.Admin.Captcha.KeyLong > 0 {
|
||||
next.Captcha.KeyLong = req.Config.Admin.Captcha.KeyLong
|
||||
}
|
||||
if req.Config.Admin.Captcha.ImgWidth > 0 {
|
||||
next.Captcha.ImgWidth = req.Config.Admin.Captcha.ImgWidth
|
||||
}
|
||||
if req.Config.Admin.Captcha.ImgHeight > 0 {
|
||||
next.Captcha.ImgHeight = req.Config.Admin.Captcha.ImgHeight
|
||||
}
|
||||
if value, err := time.ParseDuration(req.Config.Admin.Captcha.StoreExpiration); err == nil && value > 0 {
|
||||
next.Captcha.StoreExpiration = durationpb.New(value)
|
||||
}
|
||||
}
|
||||
if next.Local != nil {
|
||||
if req.Config.Admin.Local.StorePath != "" {
|
||||
next.Local.StorePath = req.Config.Admin.Local.StorePath
|
||||
}
|
||||
if req.Config.Admin.Local.PathPrefix != "" {
|
||||
next.Local.PathPrefix = req.Config.Admin.Local.PathPrefix
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func applyMediaConfig(next *conf.AdminBackend, req *dto.SetSystemConfigRequest) {
|
||||
if next.Media == nil {
|
||||
return
|
||||
}
|
||||
if req.Config.Admin.Media.SessionTTL > 0 {
|
||||
next.Media.SessionTtl = req.Config.Admin.Media.SessionTTL
|
||||
}
|
||||
next.Media.MaxFileSize = req.Config.Admin.Media.MaxFileSize
|
||||
}
|
||||
|
||||
func applyDataConfig(data *conf.Data, req *dto.SetSystemConfigRequest) *conf.Data {
|
||||
if req.Config.Data == nil {
|
||||
return data
|
||||
}
|
||||
if data == nil {
|
||||
data = &conf.Data{}
|
||||
}
|
||||
applyDatabaseConfig(data, req)
|
||||
applyRedisConfig(data, req)
|
||||
if req.Config.Data.DatabaseList != nil {
|
||||
for i, item := range req.Config.Data.DatabaseList {
|
||||
if item != nil && (item.Password == "" || item.Password == "******") && i < len(data.DatabaseList) && data.DatabaseList[i] != nil {
|
||||
item.Password = data.DatabaseList[i].Password
|
||||
}
|
||||
}
|
||||
data.DatabaseList = req.Config.Data.DatabaseList
|
||||
}
|
||||
if req.Config.Data.RedisList != nil {
|
||||
for i, item := range req.Config.Data.RedisList {
|
||||
if item != nil && (item.Password == "" || item.Password == "******") && i < len(data.RedisList) && data.RedisList[i] != nil {
|
||||
item.Password = data.RedisList[i].Password
|
||||
}
|
||||
}
|
||||
data.RedisList = req.Config.Data.RedisList
|
||||
}
|
||||
if req.Config.Data.Mongo != nil {
|
||||
if data.Mongo != nil && (req.Config.Data.Mongo.Password == "" || req.Config.Data.Mongo.Password == "******") {
|
||||
req.Config.Data.Mongo.Password = data.Mongo.Password
|
||||
}
|
||||
data.Mongo = req.Config.Data.Mongo
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func applyDatabaseConfig(data *conf.Data, req *dto.SetSystemConfigRequest) {
|
||||
value := req.Config.Data.Database
|
||||
if value == nil {
|
||||
return
|
||||
}
|
||||
password := value.Password
|
||||
if data.Database != nil && (password == "" || password == "******") {
|
||||
password = data.Database.Password
|
||||
}
|
||||
data.Database = &conf.Data_Database{Driver: value.Driver, Source: value.Source, Host: value.Host, Port: value.Port, User: value.User, Password: password, Name: value.Name, Config: value.Config, Path: value.Path, Prefix: value.Prefix, Engine: value.Engine, LogMode: value.LogMode, MaxIdleConns: value.MaxIdleConns, MaxOpenConns: value.MaxOpenConns, ConnMaxLifetime: value.ConnMaxLifetime, Singular: value.Singular}
|
||||
}
|
||||
|
||||
func applyRedisConfig(data *conf.Data, req *dto.SetSystemConfigRequest) {
|
||||
value := req.Config.Data.Redis
|
||||
if value == nil {
|
||||
return
|
||||
}
|
||||
password := value.Password
|
||||
if data.Redis != nil && (password == "" || password == "******") {
|
||||
password = data.Redis.Password
|
||||
}
|
||||
redis := &conf.Data_Redis{Network: value.Network, Addr: value.Addr, Name: value.Name, Password: password, Db: value.DB, UseCluster: value.UseCluster, ClusterAddrs: value.ClusterAddrs}
|
||||
if duration, err := time.ParseDuration(value.ReadTimeout); err == nil && duration >= 0 {
|
||||
redis.ReadTimeout = durationpb.New(duration)
|
||||
}
|
||||
if duration, err := time.ParseDuration(value.WriteTimeout); err == nil && duration >= 0 {
|
||||
redis.WriteTimeout = durationpb.New(duration)
|
||||
}
|
||||
data.Redis = redis
|
||||
}
|
||||
|
||||
func objectStores(storage *conf.AdminBackend_Storage) []*conf.AdminBackend_ObjectStore {
|
||||
if storage == nil {
|
||||
return nil
|
||||
}
|
||||
return []*conf.AdminBackend_ObjectStore{storage.AliyunOss, storage.HuaweiObs, storage.TencentCos, storage.AwsS3, storage.CloudflareR2, storage.Minio}
|
||||
}
|
||||
|
||||
func maskStorageSecrets(storage *conf.AdminBackend_Storage) {
|
||||
if storage.Qiniu != nil {
|
||||
storage.Qiniu.SecretKey = "******"
|
||||
}
|
||||
for _, item := range objectStores(storage) {
|
||||
if item != nil {
|
||||
item.SecretKey = "******"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func preserveStorageSecrets(next, current *conf.AdminBackend_Storage) {
|
||||
if next == nil || current == nil {
|
||||
return
|
||||
}
|
||||
if next.Qiniu != nil && current.Qiniu != nil && (next.Qiniu.SecretKey == "" || next.Qiniu.SecretKey == "******") {
|
||||
next.Qiniu.SecretKey = current.Qiniu.SecretKey
|
||||
}
|
||||
nextItems, currentItems := objectStores(next), objectStores(current)
|
||||
for i := range nextItems {
|
||||
if nextItems[i] != nil && currentItems[i] != nil && (nextItems[i].SecretKey == "" || nextItems[i].SecretKey == "******") {
|
||||
nextItems[i].SecretKey = currentItems[i].SecretKey
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,12 +4,14 @@ import (
|
|||
"runtime"
|
||||
"time"
|
||||
|
||||
"kra/internal/service/dto"
|
||||
|
||||
"github.com/shirou/gopsutil/v4/cpu"
|
||||
"github.com/shirou/gopsutil/v4/disk"
|
||||
"github.com/shirou/gopsutil/v4/mem"
|
||||
)
|
||||
|
||||
func (s *SystemConfigService) ServerInfo() (map[string]any, error) {
|
||||
func (s *SystemConfigService) ServerInfo() (*dto.ServerInfoResponse, error) {
|
||||
physicalCores, err := cpu.Counts(false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -22,19 +24,19 @@ func (s *SystemConfigService) ServerInfo() (map[string]any, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
diskInfo := make([]map[string]any, 0)
|
||||
diskInfo := make([]dto.ServerDiskResponse, 0)
|
||||
for _, mountPoint := range s.DiskMountPoints() {
|
||||
usage, usageErr := disk.Usage(mountPoint)
|
||||
if usageErr != nil {
|
||||
return nil, usageErr
|
||||
}
|
||||
diskInfo = append(diskInfo, map[string]any{"mountPoint": mountPoint, "usedMb": usage.Used / 1024 / 1024, "usedGb": usage.Used / 1024 / 1024 / 1024, "totalMb": usage.Total / 1024 / 1024, "totalGb": usage.Total / 1024 / 1024 / 1024, "usedPercent": int(usage.UsedPercent)})
|
||||
diskInfo = append(diskInfo, dto.ServerDiskResponse{MountPoint: mountPoint, UsedMB: usage.Used / 1024 / 1024, UsedGB: usage.Used / 1024 / 1024 / 1024, TotalMB: usage.Total / 1024 / 1024, TotalGB: usage.Total / 1024 / 1024 / 1024, UsedPercent: int(usage.UsedPercent)})
|
||||
}
|
||||
usedMB, totalMB := memory.Used/1024/1024, memory.Total/1024/1024
|
||||
return map[string]any{
|
||||
"os": map[string]any{"goos": runtime.GOOS, "numCpu": runtime.NumCPU(), "compiler": runtime.Compiler, "goVersion": runtime.Version(), "numGoroutine": runtime.NumGoroutine()},
|
||||
"cpu": map[string]any{"cpus": cpuPercent, "cores": physicalCores},
|
||||
"ram": map[string]any{"usedMb": usedMB, "totalMb": totalMB, "usedPercent": int(memory.UsedPercent)},
|
||||
"disk": diskInfo,
|
||||
return &dto.ServerInfoResponse{
|
||||
OS: dto.ServerOSResponse{GOOS: runtime.GOOS, NumCPU: runtime.NumCPU(), Compiler: runtime.Compiler, GoVersion: runtime.Version(), NumGoroutine: runtime.NumGoroutine()},
|
||||
CPU: dto.ServerCPUResponse{CPUs: cpuPercent, Cores: physicalCores},
|
||||
RAM: dto.ServerRAMResponse{UsedMB: usedMB, TotalMB: totalMB, UsedPercent: int(memory.UsedPercent)},
|
||||
Disk: diskInfo,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ func (s *SystemConfigService) InitializeRoutes(ctx context.Context, input *Datab
|
|||
apis := make([]*biz.API, 0, len(routes))
|
||||
for _, route := range routes {
|
||||
path := route.Path
|
||||
if config := s.runtime.Admin(); config != nil && config.RouterPrefix != "" {
|
||||
path = strings.TrimPrefix(path, strings.TrimSuffix(config.RouterPrefix, "/"))
|
||||
if routerPrefix := s.settings.RouterPrefix(); routerPrefix != "" {
|
||||
path = strings.TrimPrefix(path, strings.TrimSuffix(routerPrefix, "/"))
|
||||
if path == "" {
|
||||
path = "/"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ func (s *TaskService) CreateRequest(ctx context.Context, req *dto.TaskRequest) (
|
|||
func (s *TaskService) UpdateRequest(ctx context.Context, req *dto.TaskRequest) error {
|
||||
return s.Update(ctx, taskDomain(req))
|
||||
}
|
||||
func (s *TaskService) ListRequest(ctx context.Context, page, size int, name, executorType string, enabled *bool) ([]map[string]any, int64, error) {
|
||||
func (s *TaskService) ListRequest(ctx context.Context, page, size int, name, executorType string, enabled *bool) ([]*dto.TaskResponse, int64, error) {
|
||||
return s.Tasks(ctx, page, size, &biz.TimedTask{Name: name, ExecutorType: executorType, EnabledFilter: enabled})
|
||||
}
|
||||
func (s *TaskService) Create(ctx context.Context, v *biz.TimedTask) error {
|
||||
|
|
@ -44,15 +44,15 @@ func (s *TaskService) Delete(ctx context.Context, id uint) error {
|
|||
func (s *TaskService) Toggle(ctx context.Context, id uint, enabled bool) error {
|
||||
return s.uc.Toggle(ctx, id, enabled)
|
||||
}
|
||||
func taskDTO(v *biz.TimedTask, next *time.Time) map[string]any {
|
||||
return map[string]any{"ID": v.ID, "CreatedAt": v.CreatedAt, "UpdatedAt": v.UpdatedAt, "DeletedAt": nil, "name": v.Name, "description": v.Description, "spec": v.Spec, "withSeconds": v.WithSeconds, "executorType": v.ExecutorType, "methodName": v.MethodName, "params": json.RawMessage(v.Params), "httpUrl": v.HTTPURL, "httpMethod": v.HTTPMethod, "httpHeader": json.RawMessage(v.HTTPHeader), "httpBody": v.HTTPBody, "httpAllowPrivate": v.HTTPAllowPrivate, "enabled": v.Enabled, "nextRunAt": next}
|
||||
func taskDTO(v *biz.TimedTask, next *time.Time) *dto.TaskResponse {
|
||||
return &dto.TaskResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, Name: v.Name, Description: v.Description, Spec: v.Spec, WithSeconds: v.WithSeconds, ExecutorType: v.ExecutorType, MethodName: v.MethodName, Params: json.RawMessage(v.Params), HTTPURL: v.HTTPURL, HTTPMethod: v.HTTPMethod, HTTPHeader: json.RawMessage(v.HTTPHeader), HTTPBody: v.HTTPBody, HTTPAllowPrivate: v.HTTPAllowPrivate, Enabled: v.Enabled, NextRunAt: next}
|
||||
}
|
||||
func (s *TaskService) Tasks(ctx context.Context, page, size int, q *biz.TimedTask) ([]map[string]any, int64, error) {
|
||||
func (s *TaskService) Tasks(ctx context.Context, page, size int, q *biz.TimedTask) ([]*dto.TaskResponse, int64, error) {
|
||||
items, total, next, err := s.uc.List(ctx, page, size, q)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]map[string]any, 0, len(items))
|
||||
out := make([]*dto.TaskResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
var ptr *time.Time
|
||||
if value, ok := next[v.ID]; ok {
|
||||
|
|
@ -64,14 +64,14 @@ func (s *TaskService) Tasks(ctx context.Context, page, size int, q *biz.TimedTas
|
|||
return out, total, nil
|
||||
}
|
||||
|
||||
func (s *TaskService) Logs(ctx context.Context, page, size int, taskID uint, status string) ([]map[string]any, int64, error) {
|
||||
func (s *TaskService) Logs(ctx context.Context, page, size int, taskID uint, status string) ([]*dto.TaskLogResponse, int64, error) {
|
||||
items, total, err := s.uc.Logs(ctx, page, size, taskID, status)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]map[string]any, 0, len(items))
|
||||
out := make([]*dto.TaskLogResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, map[string]any{"ID": v.ID, "CreatedAt": v.CreatedAt, "DeletedAt": nil, "taskId": v.TaskID, "taskName": v.TaskName, "triggerType": v.TriggerType, "startedAt": v.StartedAt, "finishedAt": v.FinishedAt, "durationMs": v.DurationMS, "status": v.Status, "errorMsg": v.ErrorMsg, "output": v.Output})
|
||||
out = append(out, &dto.TaskLogResponse{ID: v.ID, CreatedAt: v.CreatedAt, DeletedAt: nil, TaskID: v.TaskID, TaskName: v.TaskName, TriggerType: v.TriggerType, StartedAt: v.StartedAt, FinishedAt: v.FinishedAt, DurationMS: v.DurationMS, Status: v.Status, ErrorMsg: v.ErrorMsg, Output: v.Output})
|
||||
}
|
||||
return out, total, nil
|
||||
}
|
||||
|
|
@ -81,11 +81,11 @@ func (s *TaskService) Reload(ctx context.Context) error { return s.uc.
|
|||
func (s *TaskService) Subscribe() chan []byte { return s.uc.Subscribe() }
|
||||
func (s *TaskService) Unsubscribe(events chan []byte) { s.uc.Unsubscribe(events) }
|
||||
|
||||
func (s *TaskService) RegisteredMethods() []map[string]any {
|
||||
func (s *TaskService) RegisteredMethods() []*dto.TaskMethodResponse {
|
||||
methods := biz.RegisteredTaskMethods()
|
||||
out := make([]map[string]any, 0, len(methods))
|
||||
out := make([]*dto.TaskMethodResponse, 0, len(methods))
|
||||
for _, method := range methods {
|
||||
out = append(out, map[string]any{"name": method.Name, "description": method.Description})
|
||||
out = append(out, &dto.TaskMethodResponse{Name: method.Name, Description: method.Description})
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,17 +27,17 @@ func NewUserService(uc *biz.UserUsecase, settings *SecurityService) *UserService
|
|||
func userInput(value *dto.UserRequest) UserInput {
|
||||
return UserInput{ID: value.ID, Username: value.Username, Password: value.Password, NickName: value.NickName, HeaderImg: value.HeaderImg, AuthorityID: value.AuthorityID, AuthorityIDs: value.AuthorityIDs, Enable: value.Enable, Phone: value.Phone, Email: value.Email}
|
||||
}
|
||||
func (s *UserService) ListUsersRequest(ctx context.Context, value *dto.UserListRequest) ([]map[string]any, int64, error) {
|
||||
func (s *UserService) ListUsersRequest(ctx context.Context, value *dto.UserListRequest) ([]*dto.UserResponse, int64, error) {
|
||||
return s.ListUsers(ctx, value.Page, value.PageSize, &biz.UserListFilter{Username: value.Username, NickName: value.NickName, Phone: value.Phone, Email: value.Email, OrderKey: value.OrderKey, Desc: value.Desc})
|
||||
}
|
||||
func (s *UserService) CreateUserRequest(ctx context.Context, value *dto.UserRequest) (map[string]any, error) {
|
||||
func (s *UserService) CreateUserRequest(ctx context.Context, value *dto.UserRequest) (*dto.UserResponse, error) {
|
||||
return s.CreateUser(ctx, userInput(value))
|
||||
}
|
||||
func (s *UserService) UpdateUserRequest(ctx context.Context, value *dto.UserRequest) error {
|
||||
return s.UpdateUser(ctx, userInput(value))
|
||||
}
|
||||
|
||||
func (s *UserService) User(ctx context.Context, id uint) (map[string]any, error) {
|
||||
func (s *UserService) User(ctx context.Context, id uint) (*dto.UserResponse, error) {
|
||||
value, err := s.uc.User(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -45,43 +45,39 @@ func (s *UserService) User(ctx context.Context, id uint) (map[string]any, error)
|
|||
return convertUser(value), nil
|
||||
}
|
||||
|
||||
func (s *UserService) Menus(ctx context.Context, authorityID uint) ([]map[string]any, error) {
|
||||
func (s *UserService) Menus(ctx context.Context, authorityID uint) ([]*dto.MenuResponse, error) {
|
||||
menus, err := s.uc.Menus(ctx, authorityID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := make([]map[string]any, 0, len(menus))
|
||||
for _, menu := range menus {
|
||||
result = append(result, convertMenu(menu))
|
||||
}
|
||||
return result, nil
|
||||
return menuResponses(menus), nil
|
||||
}
|
||||
|
||||
func (s *UserService) ListUsers(ctx context.Context, page, pageSize int, filter *biz.UserListFilter) ([]map[string]any, int64, error) {
|
||||
func (s *UserService) ListUsers(ctx context.Context, page, pageSize int, filter *biz.UserListFilter) ([]*dto.UserResponse, int64, error) {
|
||||
users, total, err := s.uc.ListUsers(ctx, page, pageSize, filter)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
result := make([]map[string]any, 0, len(users))
|
||||
result := make([]*dto.UserResponse, 0, len(users))
|
||||
for _, user := range users {
|
||||
result = append(result, convertUser(user))
|
||||
}
|
||||
return result, total, nil
|
||||
}
|
||||
|
||||
func (s *UserService) Authorities(ctx context.Context) ([]map[string]any, error) {
|
||||
func (s *UserService) Authorities(ctx context.Context) ([]*dto.AuthorityResponse, error) {
|
||||
values, err := s.uc.Authorities(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := make([]map[string]any, 0, len(values))
|
||||
result := make([]*dto.AuthorityResponse, 0, len(values))
|
||||
for _, value := range values {
|
||||
result = append(result, convertAuthority(*value))
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *UserService) CreateUser(ctx context.Context, input UserInput) (map[string]any, error) {
|
||||
func (s *UserService) CreateUser(ctx context.Context, input UserInput) (*dto.UserResponse, error) {
|
||||
if err := s.settings.ValidatePassword(ctx, input.Password); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,56 +1,29 @@
|
|||
package service
|
||||
|
||||
import "kra/internal/biz"
|
||||
import (
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
func departmentDTO(v *biz.Department) map[string]any {
|
||||
children := make([]map[string]any, 0, len(v.Children))
|
||||
for _, c := range v.Children {
|
||||
children = append(children, departmentDTO(c))
|
||||
}
|
||||
return map[string]any{"ID": v.ID, "CreatedAt": v.CreatedAt, "UpdatedAt": v.UpdatedAt, "DeletedAt": nil, "name": v.Name, "parentId": v.ParentID, "ancestors": v.Ancestors, "sort": v.Sort, "leaderId": v.LeaderID, "leader": nil, "status": v.Status, "children": children, "namePath": v.NamePath}
|
||||
func convertAuthority(value biz.Authority) *dto.AuthorityResponse {
|
||||
return &dto.AuthorityResponse{AuthorityID: value.AuthorityID, AuthorityName: value.AuthorityName, ParentID: value.ParentID, Children: []*dto.AuthorityResponse{}, Menus: []any{}, DataScope: value.DataScope, DefaultRouter: value.DefaultRouter}
|
||||
}
|
||||
func positionDTO(v *biz.Position) map[string]any {
|
||||
return map[string]any{"ID": v.ID, "CreatedAt": v.CreatedAt, "UpdatedAt": v.UpdatedAt, "DeletedAt": nil, "name": v.Name, "code": v.Code, "sort": v.Sort, "status": v.Status, "remark": v.Remark}
|
||||
}
|
||||
|
||||
func convertAuthority(value biz.Authority) map[string]any {
|
||||
return map[string]any{"authorityId": value.AuthorityID, "authorityName": value.AuthorityName, "parentId": value.ParentID, "children": []map[string]any{}, "menus": []any{}, "dataScope": value.DataScope, "defaultRouter": value.DefaultRouter}
|
||||
}
|
||||
func convertUser(user *biz.User) map[string]any {
|
||||
authorities := make([]map[string]any, 0, len(user.Authorities))
|
||||
func convertUser(user *biz.User) *dto.UserResponse {
|
||||
authorities := make([]*dto.AuthorityResponse, 0, len(user.Authorities))
|
||||
for _, value := range user.Authorities {
|
||||
authorities = append(authorities, convertAuthority(value))
|
||||
}
|
||||
departments := make([]map[string]any, 0, len(user.Departments))
|
||||
departments := make([]*dto.DepartmentResponse, 0, len(user.Departments))
|
||||
for i := range user.Departments {
|
||||
departments = append(departments, departmentDTO(&user.Departments[i]))
|
||||
departments = append(departments, departmentResponse(&user.Departments[i]))
|
||||
}
|
||||
positions := make([]map[string]any, 0, len(user.Positions))
|
||||
positions := make([]*dto.PositionResponse, 0, len(user.Positions))
|
||||
for i := range user.Positions {
|
||||
positions = append(positions, positionDTO(&user.Positions[i]))
|
||||
positions = append(positions, positionResponse(&user.Positions[i]))
|
||||
}
|
||||
department := map[string]any{}
|
||||
var department any = map[string]any{}
|
||||
if user.Department != nil {
|
||||
department = departmentDTO(user.Department)
|
||||
department = departmentResponse(user.Department)
|
||||
}
|
||||
return map[string]any{"ID": user.ID, "CreatedAt": user.CreatedAt, "UpdatedAt": user.UpdatedAt, "DeletedAt": nil, "uuid": user.UUID, "userName": user.Username, "nickName": user.NickName, "headerImg": user.HeaderImg, "authorityId": user.AuthorityID, "authority": convertAuthority(user.Authority), "authorities": authorities, "deptId": user.DeptID, "dept": department, "departments": departments, "positions": positions, "phone": user.Phone, "email": user.Email, "enable": user.Enable, "originSetting": user.OriginSetting}
|
||||
}
|
||||
func convertMenu(menu *biz.Menu) map[string]any {
|
||||
children := make([]map[string]any, 0, len(menu.Children))
|
||||
for _, child := range menu.Children {
|
||||
children = append(children, convertMenu(child))
|
||||
}
|
||||
buttons := make([]map[string]any, 0, len(menu.Buttons))
|
||||
buttonAuthorities := make(map[string]uint, len(menu.Buttons))
|
||||
for _, button := range menu.Buttons {
|
||||
buttons = append(buttons, map[string]any{"ID": button.ID, "name": button.Name, "desc": button.Description, "sysBaseMenuID": button.MenuID})
|
||||
if button.AuthorityID != 0 {
|
||||
buttonAuthorities[button.Name] = button.AuthorityID
|
||||
}
|
||||
}
|
||||
parameters := make([]map[string]any, 0, len(menu.Parameters))
|
||||
for _, parameter := range menu.Parameters {
|
||||
parameters = append(parameters, map[string]any{"ID": parameter.ID, "SysBaseMenuID": parameter.MenuID, "type": parameter.Type, "key": parameter.Key, "value": parameter.Value})
|
||||
}
|
||||
return map[string]any{"ID": menu.ID, "parentId": menu.ParentID, "path": menu.Path, "name": menu.Name, "hidden": menu.Hidden, "component": menu.Component, "sort": menu.Sort, "meta": map[string]any{"activeName": menu.ActiveName, "keepAlive": menu.KeepAlive, "defaultMenu": menu.DefaultMenu, "title": menu.Title, "icon": menu.Icon, "closeTab": menu.CloseTab, "transitionType": menu.TransitionType}, "children": children, "parameters": parameters, "menuBtn": buttons, "btns": buttonAuthorities}
|
||||
return &dto.UserResponse{ID: user.ID, CreatedAt: user.CreatedAt, UpdatedAt: user.UpdatedAt, DeletedAt: nil, UUID: user.UUID, Username: user.Username, NickName: user.NickName, HeaderImg: user.HeaderImg, AuthorityID: user.AuthorityID, Authority: convertAuthority(user.Authority), Authorities: authorities, DeptID: user.DeptID, Department: department, Departments: departments, Positions: positions, Phone: user.Phone, Email: user.Email, Enable: user.Enable, OriginSetting: user.OriginSetting}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,21 +12,21 @@ import (
|
|||
type VersionService struct{ uc *biz.VersionUsecase }
|
||||
|
||||
func NewVersionService(uc *biz.VersionUsecase) *VersionService { return &VersionService{uc: uc} }
|
||||
func versionDTO(v *biz.Version) map[string]any {
|
||||
return map[string]any{"ID": v.ID, "CreatedAt": v.CreatedAt, "UpdatedAt": v.UpdatedAt, "DeletedAt": nil, "versionName": v.Name, "versionCode": v.Code, "description": v.Description, "versionData": v.Data}
|
||||
func versionDTO(v *biz.Version) *dto.VersionResponse {
|
||||
return &dto.VersionResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, VersionName: v.Name, VersionCode: v.Code, Description: v.Description, VersionData: v.Data}
|
||||
}
|
||||
func (s *VersionService) Versions(ctx context.Context, page, size int, name, code string, createdAtRange []*time.Time) ([]map[string]any, int64, error) {
|
||||
func (s *VersionService) Versions(ctx context.Context, page, size int, name, code string, createdAtRange []*time.Time) ([]*dto.VersionResponse, int64, error) {
|
||||
items, total, err := s.uc.ListVersions(ctx, page, size, name, code, createdAtRange)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]map[string]any, 0, len(items))
|
||||
out := make([]*dto.VersionResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, versionDTO(v))
|
||||
}
|
||||
return out, total, nil
|
||||
}
|
||||
func (s *VersionService) Version(ctx context.Context, id uint) (map[string]any, error) {
|
||||
func (s *VersionService) Version(ctx context.Context, id uint) (*dto.VersionResponse, error) {
|
||||
v, err := s.uc.FindVersion(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -53,15 +53,15 @@ func (s *VersionService) Export(ctx context.Context, name, code, description str
|
|||
bundle.Code = code
|
||||
bundle.Description = description
|
||||
bundle.ExportTime = time.Now().Format("2006-01-02 15:04:05")
|
||||
menus := make([]map[string]any, 0, len(bundle.Menus))
|
||||
menus := make([]*dto.MenuResponse, 0, len(bundle.Menus))
|
||||
for _, v := range bundle.Menus {
|
||||
menus = append(menus, convertMenu(v))
|
||||
menus = append(menus, menuResponse(v))
|
||||
}
|
||||
apis := make([]map[string]any, 0, len(bundle.APIs))
|
||||
apis := make([]*dto.APIResponse, 0, len(bundle.APIs))
|
||||
for _, v := range bundle.APIs {
|
||||
apis = append(apis, apiDTO(v))
|
||||
apis = append(apis, apiResponse(v))
|
||||
}
|
||||
dicts := make([]map[string]any, 0, len(bundle.Dictionaries))
|
||||
dicts := make([]*dto.DictionaryResponse, 0, len(bundle.Dictionaries))
|
||||
for _, v := range bundle.Dictionaries {
|
||||
dicts = append(dicts, dictionaryDTO(v))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
package worker
|
||||
|
||||
import "github.com/google/wire"
|
||||
|
||||
// ProviderSet contains background task runtime providers.
|
||||
var ProviderSet = wire.NewSet(NewTaskExecutor, NewTaskScheduler, NewTaskRuntime)
|
||||
Loading…
Reference in New Issue