优化结构
This commit is contained in:
@@ -1,3 +0,0 @@
|
||||
# Service
|
||||
|
||||
本目录负责管理端 DTO 与领域对象之间的转换和输入校验,不直接访问数据库。固定 JSON 契约放在 `dto/`,只有用户设置、导出行等真正动态的数据使用 `map[string]any`。
|
||||
@@ -1,29 +0,0 @@
|
||||
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
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type AnnouncementInput struct {
|
||||
ID uint
|
||||
Title string
|
||||
Content string
|
||||
UserID *int
|
||||
Attachments json.RawMessage
|
||||
}
|
||||
|
||||
type AnnouncementService struct{ uc *biz.AnnouncementUsecase }
|
||||
|
||||
func NewAnnouncementService(uc *biz.AnnouncementUsecase) *AnnouncementService {
|
||||
return &AnnouncementService{uc: uc}
|
||||
}
|
||||
|
||||
func announcementDTO(item *biz.Announcement) *dto.AnnouncementResponse {
|
||||
return &dto.AnnouncementResponse{ID: item.ID, CreatedAt: item.CreatedAt, UpdatedAt: item.UpdatedAt, DeletedAt: nil, Title: item.Title, Content: item.Content, UserID: item.UserID, Attachments: json.RawMessage(item.Attachments)}
|
||||
}
|
||||
|
||||
func announcementDO(in AnnouncementInput) *biz.Announcement {
|
||||
return &biz.Announcement{ID: in.ID, Title: in.Title, Content: in.Content, UserID: in.UserID, Attachments: in.Attachments}
|
||||
}
|
||||
|
||||
func (s *AnnouncementService) Create(ctx context.Context, in AnnouncementInput) error {
|
||||
return s.uc.Create(ctx, announcementDO(in))
|
||||
}
|
||||
|
||||
func (s *AnnouncementService) Update(ctx context.Context, in AnnouncementInput) error {
|
||||
return s.uc.Update(ctx, announcementDO(in))
|
||||
}
|
||||
|
||||
func (s *AnnouncementService) Delete(ctx context.Context, id string) error {
|
||||
return s.uc.Delete(ctx, id)
|
||||
}
|
||||
|
||||
func (s *AnnouncementService) DeleteByIDs(ctx context.Context, ids []string) error {
|
||||
return s.uc.DeleteByIDs(ctx, ids)
|
||||
}
|
||||
|
||||
func (s *AnnouncementService) Find(ctx context.Context, id string) (*dto.AnnouncementResponse, error) {
|
||||
item, err := s.uc.Find(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return announcementDTO(item), nil
|
||||
}
|
||||
|
||||
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([]*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) ([]*dto.SelectOptionResponse, error) {
|
||||
items, err := s.uc.UserOptions(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := make([]*dto.SelectOptionResponse, 0, len(items))
|
||||
for _, item := range items {
|
||||
result = append(result, &dto.SelectOptionResponse{Label: item.Label, Value: item.Value})
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type APIService struct {
|
||||
uc *biz.APIUsecase
|
||||
settings biz.RuntimeSettings
|
||||
}
|
||||
|
||||
func NewAPIService(uc *biz.APIUsecase, settings biz.RuntimeSettings) *APIService {
|
||||
return &APIService{uc: uc, settings: settings}
|
||||
}
|
||||
|
||||
func (s *APIService) NormalizeRoutePath(path string) string {
|
||||
if s.settings == nil {
|
||||
return path
|
||||
}
|
||||
return NormalizeRoutePath(path, s.settings.RouterPrefix())
|
||||
}
|
||||
|
||||
func (s *APIService) apiDomain(value *dto.APIRequest) *biz.API {
|
||||
return &biz.API{ID: value.ID, Path: s.NormalizeRoutePath(value.Path), Description: value.Description, APIGroup: value.APIGroup, Method: value.Method}
|
||||
}
|
||||
|
||||
func apiResponse(value *biz.API) *dto.APIResponse {
|
||||
return &dto.APIResponse{ID: value.ID, CreatedAt: value.CreatedAt, UpdatedAt: value.UpdatedAt, DeletedAt: nil, Path: value.Path, Description: value.Description, APIGroup: value.APIGroup, Method: value.Method}
|
||||
}
|
||||
|
||||
func apiResponses(items []*biz.API) []*dto.APIResponse {
|
||||
out := make([]*dto.APIResponse, 0, len(items))
|
||||
for _, item := range items {
|
||||
out = append(out, apiResponse(item))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (s *APIService) ListAPI(ctx context.Context, req *dto.APIListRequest) ([]*dto.APIResponse, int64, error) {
|
||||
items, total, err := s.uc.ListAPIs(ctx, req.Page, req.PageSize, &biz.API{Path: req.Path, Description: req.Description, APIGroup: req.APIGroup, Method: req.Method, OrderKey: req.OrderKey, Desc: req.Desc})
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return apiResponses(items), total, nil
|
||||
}
|
||||
|
||||
func (s *APIService) AllAPI(ctx context.Context, strict bool) ([]*dto.APIResponse, error) {
|
||||
items, _, err := s.uc.ListAPIs(ctx, 0, 0, &biz.API{StrictAll: strict})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return apiResponses(items), nil
|
||||
}
|
||||
|
||||
func (s *APIService) Groups(ctx context.Context) ([]string, map[string]string, error) {
|
||||
// The compatible group endpoint uses an unqualified Find, whose natural order is
|
||||
// the primary-key ascending order. GetAllApis intentionally uses id DESC,
|
||||
// so do not reuse it here or the group/dropdown order changes.
|
||||
items, _, err := s.uc.ListAPIs(ctx, 0, 0, &biz.API{OrderKey: "id"})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
seen := make(map[string]bool)
|
||||
groups := make([]string, 0)
|
||||
groupAPIMap := make(map[string]string)
|
||||
for _, item := range items {
|
||||
if !seen[item.APIGroup] {
|
||||
seen[item.APIGroup] = true
|
||||
groups = append(groups, item.APIGroup)
|
||||
}
|
||||
parts := strings.Split(item.Path, "/")
|
||||
if len(parts) > 1 {
|
||||
groupAPIMap[parts[1]] = item.APIGroup
|
||||
}
|
||||
}
|
||||
return groups, groupAPIMap, nil
|
||||
}
|
||||
|
||||
func (s *APIService) CreateAPIRequest(ctx context.Context, req *dto.APIRequest) (*dto.APIResponse, error) {
|
||||
value := s.apiDomain(req)
|
||||
if err := s.uc.CreateAPI(ctx, value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return apiResponse(value), nil
|
||||
}
|
||||
func (s *APIService) UpdateAPIRequest(ctx context.Context, req *dto.APIRequest) error {
|
||||
return s.uc.UpdateAPI(ctx, s.apiDomain(req))
|
||||
}
|
||||
func (s *APIService) FindAPIResponse(ctx context.Context, id uint) (*dto.APIResponse, error) {
|
||||
value, err := s.uc.FindAPI(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return apiResponse(value), nil
|
||||
}
|
||||
func (s *APIService) ApplyAPISyncRequest(ctx context.Context, req *dto.ApplyAPISyncRequest) error {
|
||||
added := make([]*biz.API, 0, len(req.NewAPIs))
|
||||
deleted := make([]*biz.API, 0, len(req.DeleteAPIs))
|
||||
for i := range req.NewAPIs {
|
||||
added = append(added, s.apiDomain(&req.NewAPIs[i]))
|
||||
}
|
||||
for i := range req.DeleteAPIs {
|
||||
deleted = append(deleted, s.apiDomain(&req.DeleteAPIs[i]))
|
||||
}
|
||||
return s.uc.ApplyAPISync(ctx, added, deleted)
|
||||
}
|
||||
func (s *APIService) SetPolicyPathsRequest(ctx context.Context, req *dto.SetPolicyPathsRequest) error {
|
||||
paths := make([]*biz.API, 0, len(req.Infos))
|
||||
for _, value := range req.Infos {
|
||||
paths = append(paths, &biz.API{Path: value.Path, Method: value.Method})
|
||||
}
|
||||
return s.uc.SetPolicyPaths(ctx, req.AuthorityID, paths)
|
||||
}
|
||||
func (s *APIService) PolicyPathResponses(ctx context.Context, authorityID uint) ([]dto.PolicyPathRequest, error) {
|
||||
items, err := s.uc.PolicyPaths(ctx, authorityID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var out []dto.PolicyPathRequest
|
||||
if len(items) > 0 {
|
||||
out = make([]dto.PolicyPathRequest, 0, len(items))
|
||||
}
|
||||
for _, item := range items {
|
||||
out = append(out, dto.PolicyPathRequest{Path: item.Path, Method: item.Method})
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
func (s *APIService) SyncAPIResponses(ctx context.Context, routes []dto.APIRequest) (*dto.APISyncResponse, error) {
|
||||
items := make([]*biz.API, 0, len(routes))
|
||||
for i := range routes {
|
||||
routes[i].Path = s.NormalizeRoutePath(routes[i].Path)
|
||||
// The compatible sync endpoint compares Gin's route table directly, so newly
|
||||
// discovered routes carry only path and method. Group/description are
|
||||
// intentionally left empty for the operator to fill in the sync dialog.
|
||||
items = append(items, s.apiDomain(&routes[i]))
|
||||
}
|
||||
return s.SyncAPIs(ctx, items)
|
||||
}
|
||||
|
||||
func (s *APIService) DeleteAPIs(ctx context.Context, ids []uint) error {
|
||||
return s.uc.DeleteAPIs(ctx, ids)
|
||||
}
|
||||
func (s *APIService) DeleteAPI(ctx context.Context, id uint) error {
|
||||
return s.uc.DeleteAPI(ctx, id)
|
||||
}
|
||||
func (s *APIService) APIRoleIDs(ctx context.Context, path, method string) ([]uint, error) {
|
||||
return s.uc.APIRoleIDs(ctx, s.NormalizeRoutePath(path), method)
|
||||
}
|
||||
func (s *APIService) SetAPIRoles(ctx context.Context, path, method string, ids []uint) error {
|
||||
return s.uc.SetAPIRoles(ctx, s.NormalizeRoutePath(path), method, ids)
|
||||
}
|
||||
func (s *APIService) FreshCasbin(ctx context.Context) error {
|
||||
return s.uc.FreshCasbin(ctx)
|
||||
}
|
||||
func (s *APIService) SyncAPIs(ctx context.Context, routes []*biz.API) (*dto.APISyncResponse, error) {
|
||||
diff, err := s.uc.SyncAPIs(ctx, routes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &dto.APISyncResponse{NewAPIs: apiResponses(diff.Added), DeleteAPIs: apiResponses(diff.Deleted), IgnoreAPIs: apiResponses(diff.Ignored)}, nil
|
||||
}
|
||||
func (s *APIService) SetAPIIgnored(ctx context.Context, path, method string, ignored bool) error {
|
||||
return s.uc.SetAPIIgnored(ctx, s.NormalizeRoutePath(path), method, ignored)
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type TokenService struct {
|
||||
uc *biz.TokenUsecase
|
||||
issuer biz.TokenIssuer
|
||||
}
|
||||
|
||||
func NewTokenService(uc *biz.TokenUsecase, issuer biz.TokenIssuer) *TokenService {
|
||||
return &TokenService{uc: uc, issuer: issuer}
|
||||
}
|
||||
|
||||
func tokenDTO(v *biz.APIToken) *dto.APITokenResponse {
|
||||
var user *dto.UserResponse
|
||||
if v.User != nil {
|
||||
user = convertUser(v.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) {
|
||||
user, duration, err := s.uc.PrepareAPIToken(ctx, userID, authorityID, days)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
issued, err := s.issuer.IssueToken(user, authorityID, false, duration)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
record := &biz.APIToken{UserID: userID, AuthorityID: authorityID, Token: issued.Value, Status: true, ExpiresAt: time.Now().Add(duration), Remark: remark}
|
||||
if err = s.uc.CreateAPIToken(ctx, record); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return issued.Value, nil
|
||||
}
|
||||
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([]*dto.APITokenResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, tokenDTO(v))
|
||||
}
|
||||
return out, total, nil
|
||||
}
|
||||
func (s *TokenService) DisableAPIToken(ctx context.Context, id uint) error {
|
||||
return s.uc.DisableToken(ctx, id)
|
||||
}
|
||||
func (s *TokenService) BlacklistToken(ctx context.Context, token string) error {
|
||||
return s.uc.BlacklistToken(ctx, token)
|
||||
}
|
||||
func (s *TokenService) IsTokenDisabled(ctx context.Context, token string) (bool, error) {
|
||||
return s.uc.IsTokenDisabled(ctx, token)
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type AuditService struct{ uc *biz.AuditUsecase }
|
||||
|
||||
func NewAuditService(uc *biz.AuditUsecase) *AuditService { return &AuditService{uc: uc} }
|
||||
|
||||
type AuditRecorder struct{ uc *biz.AuditRecorderUsecase }
|
||||
|
||||
func NewAuditRecorder(uc *biz.AuditRecorderUsecase) *AuditRecorder { return &AuditRecorder{uc: uc} }
|
||||
|
||||
func (s *AuditRecorder) RecordOperation(ctx context.Context, v *biz.OperationRecord) error {
|
||||
return s.uc.RecordOperation(ctx, v)
|
||||
}
|
||||
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) ([]*dto.OperationRecordResponse, int64, error) {
|
||||
return s.Operations(ctx, page, size, &biz.OperationRecord{Path: path, Method: method, Status: status})
|
||||
}
|
||||
func opDTO(v *biz.OperationRecord) *dto.OperationRecordResponse {
|
||||
var user any = map[string]any{}
|
||||
if v.User != nil {
|
||||
user = convertUser(v.User)
|
||||
}
|
||||
return &dto.OperationRecordResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, 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) ([]*dto.OperationRecordResponse, int64, error) {
|
||||
items, total, err := s.uc.ListOperations(ctx, page, size, q)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
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) (*dto.OperationRecordResponse, error) {
|
||||
v, err := s.uc.FindOperation(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return opDTO(v), nil
|
||||
}
|
||||
func (s *AuditService) DeleteOperations(ctx context.Context, ids []int) error {
|
||||
return s.uc.DeleteOperations(ctx, ids)
|
||||
}
|
||||
|
||||
func (s *AuditRecorder) RecordLogin(ctx context.Context, v *biz.LoginLog) error {
|
||||
return s.uc.RecordLogin(ctx, v)
|
||||
}
|
||||
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) ([]*dto.LoginLogResponse, int64, error) {
|
||||
return s.Logins(ctx, page, size, &biz.LoginLog{Username: username, Status: status, FilterByStatus: status})
|
||||
}
|
||||
func loginDTO(v *biz.LoginLog) *dto.LoginLogResponse {
|
||||
var user any = map[string]any{}
|
||||
if v.User != nil {
|
||||
user = convertUser(v.User)
|
||||
}
|
||||
return &dto.LoginLogResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, 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) ([]*dto.LoginLogResponse, int64, error) {
|
||||
items, total, err := s.uc.ListLogins(ctx, page, size, q)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
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) (*dto.LoginLogResponse, error) {
|
||||
v, err := s.uc.FindLogin(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return loginDTO(v), nil
|
||||
}
|
||||
func (s *AuditService) DeleteLogins(ctx context.Context, ids []int) error {
|
||||
return s.uc.DeleteLogins(ctx, ids)
|
||||
}
|
||||
|
||||
func (s *AuditRecorder) RecordDataAccess(ctx context.Context, v *biz.DataAccessLog) error {
|
||||
return s.uc.RecordDataAccess(ctx, v)
|
||||
}
|
||||
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) ([]*dto.DataAccessLogResponse, int64, error) {
|
||||
return s.DataAccess(ctx, req.Page, req.PageSize, &biz.DataAccessLog{EventType: req.EventType, TargetTable: req.TargetTable})
|
||||
}
|
||||
func dataAccessDTO(v *biz.DataAccessLog) *dto.DataAccessLogResponse {
|
||||
return &dto.DataAccessLogResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, 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) ([]*dto.DataAccessLogResponse, int64, error) {
|
||||
items, total, err := s.uc.ListDataAccess(ctx, page, size, q)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]*dto.DataAccessLogResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, dataAccessDTO(v))
|
||||
}
|
||||
return out, total, nil
|
||||
}
|
||||
func (s *AuditService) DeleteDataAccess(ctx context.Context, ids []uint) error {
|
||||
return s.uc.DeleteDataAccess(ctx, ids)
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
func errorDTO(v *biz.ErrorRecord) *dto.ErrorRecordResponse {
|
||||
return &dto.ErrorRecordResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, 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)
|
||||
}
|
||||
func recordedErrorDomain(value *dto.ErrorRecordRequest) *biz.ErrorRecord {
|
||||
form, info := value.Form, value.Info
|
||||
result := &biz.ErrorRecord{Form: &form, Info: &info, Level: value.Level, RequestID: value.RequestID, TraceID: value.TraceID, Status: value.Status}
|
||||
if value.Solution != "" {
|
||||
solution := value.Solution
|
||||
result.Solution = &solution
|
||||
}
|
||||
return result
|
||||
}
|
||||
func mutatedErrorDomain(value *dto.ErrorRecordMutationRequest) *biz.ErrorRecord {
|
||||
return &biz.ErrorRecord{ID: value.ID, CreatedAt: value.CreatedAt, UpdatedAt: value.UpdatedAt, Form: value.Form, Info: value.Info, Level: value.Level, RequestID: value.RequestID, TraceID: value.TraceID, Solution: value.Solution, Status: value.Status}
|
||||
}
|
||||
func (s *AuditRecorder) CreateErrorRequest(ctx context.Context, req *dto.ErrorRecordRequest) error {
|
||||
return s.CreateError(ctx, recordedErrorDomain(req))
|
||||
}
|
||||
func (s *AuditRecorder) CreateErrorMutationRequest(ctx context.Context, req *dto.ErrorRecordMutationRequest) error {
|
||||
return s.CreateError(ctx, mutatedErrorDomain(req))
|
||||
}
|
||||
func (s *AuditService) UpdateErrorRequest(ctx context.Context, req *dto.ErrorRecordMutationRequest) error {
|
||||
return s.UpdateError(ctx, mutatedErrorDomain(req))
|
||||
}
|
||||
func (s *AuditService) ErrorsFilter(ctx context.Context, page, size int, form, info string, createdAtRange []time.Time) ([]*dto.ErrorRecordResponse, int64, error) {
|
||||
query := &biz.ErrorRecord{CreatedAtRange: createdAtRange}
|
||||
if form != "" {
|
||||
query.Form = &form
|
||||
}
|
||||
if info != "" {
|
||||
query.Info = &info
|
||||
}
|
||||
return s.Errors(ctx, page, size, query)
|
||||
}
|
||||
func (s *AuditService) UpdateError(ctx context.Context, v *biz.ErrorRecord) error {
|
||||
return s.uc.UpdateError(ctx, v)
|
||||
}
|
||||
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) (*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) ([]*dto.ErrorRecordResponse, int64, error) {
|
||||
items, total, err := s.uc.ListErrors(ctx, page, size, q)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]*dto.ErrorRecordResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, errorDTO(v))
|
||||
}
|
||||
return out, total, nil
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type LogViewerService struct{ uc *biz.LogViewerUsecase }
|
||||
|
||||
func NewLogViewerService(uc *biz.LogViewerUsecase) *LogViewerService {
|
||||
return &LogViewerService{uc: uc}
|
||||
}
|
||||
|
||||
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([]*dto.LogDateResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, &dto.LogDateResponse{Date: v.Date, FileCount: v.FileCount})
|
||||
}
|
||||
return &dto.LogDatesResponse{Month: month, Dates: out}, nil
|
||||
}
|
||||
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([]*dto.LogFileResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, &dto.LogFileResponse{Path: v.Path, Name: v.Name, Size: v.Size, ModifiedAt: v.ModifiedAt})
|
||||
}
|
||||
return &dto.LogFilesResponse{Date: date, Files: out}, nil
|
||||
}
|
||||
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 &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
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type AuthService struct {
|
||||
uc *biz.AuthenticationUsecase
|
||||
}
|
||||
|
||||
func NewAuthService(uc *biz.AuthenticationUsecase) *AuthService {
|
||||
return &AuthService{uc: uc}
|
||||
}
|
||||
|
||||
func loginResult(value *biz.AuthenticationResult) *dto.LoginResponse {
|
||||
return &dto.LoginResponse{User: convertUser(value.User), Token: value.Token, ExpiresAt: value.ExpiresAt.UnixMilli(), NeedChangePassword: value.NeedChangePassword}
|
||||
}
|
||||
|
||||
func (s *AuthService) Login(ctx context.Context, req *dto.LoginRequest, ip, agent string) (*dto.LoginResponse, error) {
|
||||
value, err := s.uc.Login(ctx, &biz.LoginAttempt{Username: req.Username, Password: req.Password, CaptchaID: req.CaptchaID, Captcha: req.Captcha, IP: ip, Agent: agent})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return loginResult(value), nil
|
||||
}
|
||||
|
||||
func (s *AuthService) SwitchAuthority(ctx context.Context, claims *biz.AuthClaims, authorityID uint) (*dto.LoginResponse, error) {
|
||||
value, err := s.uc.SwitchAuthority(ctx, claims, authorityID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return loginResult(value), nil
|
||||
}
|
||||
|
||||
func (s *AuthService) AuthenticateToken(ctx context.Context, token string) (*biz.TokenAuthentication, error) {
|
||||
return s.uc.AuthenticateToken(ctx, token)
|
||||
}
|
||||
@@ -1,94 +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}
|
||||
}
|
||||
|
||||
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 {
|
||||
var menus []*dto.MenuResponse
|
||||
if value.Menus != nil {
|
||||
menus = menuResponses(value.Menus)
|
||||
}
|
||||
return &dto.AuthorityResponse{CreatedAt: value.CreatedAt, UpdatedAt: value.UpdatedAt, DeletedAt: value.DeletedAt, AuthorityID: value.AuthorityID, AuthorityName: value.AuthorityName, ParentID: value.ParentID, Children: nil, Menus: menus, 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
|
||||
}
|
||||
result := authorityResponse(value)
|
||||
result.Children = []*dto.AuthorityResponse{}
|
||||
return result, 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)
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type DepartmentService struct{ uc *biz.DepartmentUsecase }
|
||||
|
||||
func NewDepartmentService(uc *biz.DepartmentUsecase) *DepartmentService {
|
||||
return &DepartmentService{uc: uc}
|
||||
}
|
||||
|
||||
func departmentResponse(value *biz.Department) *dto.DepartmentResponse {
|
||||
var children []*dto.DepartmentResponse
|
||||
if value.Children != nil {
|
||||
children = make([]*dto.DepartmentResponse, 0, len(value.Children))
|
||||
for _, child := range value.Children {
|
||||
children = append(children, departmentResponse(child))
|
||||
}
|
||||
}
|
||||
var leader any
|
||||
if value.Leader != nil {
|
||||
leader = convertUser(value.Leader)
|
||||
}
|
||||
return &dto.DepartmentResponse{ID: value.ID, CreatedAt: value.CreatedAt, UpdatedAt: value.UpdatedAt, DeletedAt: nil, Name: value.Name, ParentID: value.ParentID, Ancestors: value.Ancestors, Sort: value.Sort, LeaderID: value.LeaderID, Leader: leader, Status: value.Status, Children: children, NamePath: value.NamePath}
|
||||
}
|
||||
|
||||
func departmentDomain(value *dto.DepartmentRequest) *biz.Department {
|
||||
return &biz.Department{ID: value.ID, Name: value.Name, ParentID: value.ParentID, Sort: value.Sort, LeaderID: value.LeaderID, Status: value.Status}
|
||||
}
|
||||
|
||||
func (s *DepartmentService) Departments(ctx context.Context, name string) ([]*dto.DepartmentResponse, error) {
|
||||
items, err := s.uc.Departments(ctx, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make([]*dto.DepartmentResponse, 0, len(items))
|
||||
for _, item := range items {
|
||||
out = append(out, departmentResponse(item))
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (s *DepartmentService) Create(ctx context.Context, req *dto.DepartmentRequest) error {
|
||||
return s.uc.CreateDepartment(ctx, departmentDomain(req))
|
||||
}
|
||||
|
||||
func (s *DepartmentService) Update(ctx context.Context, req *dto.DepartmentRequest) error {
|
||||
return s.uc.UpdateDepartment(ctx, departmentDomain(req))
|
||||
}
|
||||
|
||||
func (s *DepartmentService) Delete(ctx context.Context, id uint) error {
|
||||
return s.uc.DeleteDepartment(ctx, id)
|
||||
}
|
||||
|
||||
func (s *DepartmentService) Department(ctx context.Context, id uint) (*dto.DepartmentResponse, error) {
|
||||
value, err := s.uc.Department(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return departmentResponse(value), nil
|
||||
}
|
||||
|
||||
func (s *DepartmentService) UserIDs(ctx context.Context, id uint) ([]uint, error) {
|
||||
return s.uc.DepartmentUserIDs(ctx, id)
|
||||
}
|
||||
|
||||
func (s *DepartmentService) SetUsers(ctx context.Context, req *dto.SetDepartmentUsersRequest) error {
|
||||
return s.uc.SetDepartmentUsers(ctx, req.DepartmentID, req.UserIDs)
|
||||
}
|
||||
|
||||
func (s *DepartmentService) SetUserDepartments(ctx context.Context, req *dto.SetUserDepartmentsRequest) error {
|
||||
return s.uc.SetUserDepartments(ctx, req.ID, req.DepartmentIDs, req.Primary)
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"kra/internal/biz"
|
||||
)
|
||||
|
||||
func TestDepartmentResponsePreservesNilAndEmptyChildren(t *testing.T) {
|
||||
if got := departmentResponse(&biz.Department{}).Children; got != nil {
|
||||
t.Fatalf("single/search department children = %#v, want nil", got)
|
||||
}
|
||||
if got := departmentResponse(&biz.Department{Children: []*biz.Department{}}).Children; got == nil || len(got) != 0 {
|
||||
t.Fatalf("tree leaf children = %#v, want empty slice", got)
|
||||
}
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type DictionaryService struct{ uc *biz.DictionaryUsecase }
|
||||
|
||||
func NewDictionaryService(uc *biz.DictionaryUsecase) *DictionaryService {
|
||||
return &DictionaryService{uc: uc}
|
||||
}
|
||||
|
||||
func dictionaryDomain(value *dto.DictionaryRequest) *biz.Dictionary {
|
||||
return &biz.Dictionary{ID: value.ID, Name: value.Name, Type: value.Type, Status: value.Status, Desc: value.Description, ParentID: value.ParentID}
|
||||
}
|
||||
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
|
||||
}
|
||||
return dictionaryDTO(value), nil
|
||||
}
|
||||
func (s *DictionaryService) UpdateDictionaryRequest(ctx context.Context, req *dto.DictionaryRequest) error {
|
||||
return s.UpdateDictionary(ctx, dictionaryDomain(req))
|
||||
}
|
||||
func dictionaryDTO(v *biz.Dictionary) *dto.DictionaryResponse {
|
||||
var children []*dto.DictionaryResponse
|
||||
if v.Children != nil {
|
||||
children = make([]*dto.DictionaryResponse, 0, len(v.Children))
|
||||
for _, x := range v.Children {
|
||||
children = append(children, dictionaryDTO(x))
|
||||
}
|
||||
}
|
||||
var details []*dto.DictionaryDetailResponse
|
||||
if v.Details != nil {
|
||||
details = make([]*dto.DictionaryDetailResponse, 0, len(v.Details))
|
||||
for _, x := range v.Details {
|
||||
details = append(details, detailDTO(x))
|
||||
}
|
||||
}
|
||||
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) ([]*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([]*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) (*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) (*dto.DictionaryExportResponse, error) {
|
||||
v, err := s.uc.ExportDictionary(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var details []*dto.DictionaryDetailExportResponse
|
||||
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)
|
||||
}
|
||||
func (s *DictionaryService) UpdateDictionary(ctx context.Context, v *biz.Dictionary) error {
|
||||
return s.uc.UpdateDictionary(ctx, v)
|
||||
}
|
||||
func (s *DictionaryService) DeleteDictionary(ctx context.Context, id uint) error {
|
||||
return s.uc.DeleteDictionary(ctx, id)
|
||||
}
|
||||
|
||||
func detailDomain(value *dto.DictionaryDetailRequest) *biz.DictionaryDetail {
|
||||
return &biz.DictionaryDetail{ID: value.ID, Label: value.Label, Value: value.Value, Extend: value.Extend, Status: value.Status, Sort: value.Sort, DictionaryID: value.DictionaryID, ParentID: value.ParentID, Level: value.Level, Path: value.Path}
|
||||
}
|
||||
func (s *DictionaryService) CreateDictionaryDetailRequest(ctx context.Context, req *dto.DictionaryDetailRequest) error {
|
||||
return s.CreateDictionaryDetail(ctx, detailDomain(req))
|
||||
}
|
||||
func (s *DictionaryService) UpdateDictionaryDetailRequest(ctx context.Context, req *dto.DictionaryDetailRequest) error {
|
||||
return s.UpdateDictionaryDetail(ctx, detailDomain(req))
|
||||
}
|
||||
func detailDTO(v *biz.DictionaryDetail) *dto.DictionaryDetailResponse {
|
||||
var children []*dto.DictionaryDetailResponse
|
||||
if v.Children != nil {
|
||||
children = make([]*dto.DictionaryDetailResponse, 0, len(v.Children))
|
||||
for _, x := range v.Children {
|
||||
children = append(children, detailDTO(x))
|
||||
}
|
||||
}
|
||||
disabled := v.Status != nil && !*v.Status
|
||||
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: disabled, Children: children}
|
||||
}
|
||||
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([]*dto.DictionaryDetailResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, detailDTO(v))
|
||||
}
|
||||
return out, total, nil
|
||||
}
|
||||
func (s *DictionaryService) DictionaryDetailsRequest(ctx context.Context, page, size int, request dto.DictionaryDetailListRequest) ([]*dto.DictionaryDetailResponse, int64, error) {
|
||||
return s.DictionaryDetails(ctx, page, size, biz.DictionaryDetailFilter{
|
||||
DictionaryID: request.DictionaryID,
|
||||
Label: request.Label,
|
||||
Value: request.Value,
|
||||
Status: request.Status,
|
||||
ParentID: request.ParentID,
|
||||
Level: request.Level,
|
||||
})
|
||||
}
|
||||
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) DictionaryPath(ctx context.Context, id uint) ([]*dto.DictionaryDetailResponse, error) {
|
||||
path := make([]*dto.DictionaryDetailResponse, 0)
|
||||
for id != 0 {
|
||||
value, err := s.uc.FindDictionaryDetail(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
path = append([]*dto.DictionaryDetailResponse{detailDTO(value)}, path...)
|
||||
if value.ParentID == nil {
|
||||
break
|
||||
}
|
||||
id = *value.ParentID
|
||||
}
|
||||
return path, nil
|
||||
}
|
||||
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([]*dto.DictionaryDetailResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, detailDTO(v))
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
func (s *DictionaryService) CreateDictionaryDetail(ctx context.Context, v *biz.DictionaryDetail) error {
|
||||
return s.uc.CreateDictionaryDetail(ctx, v)
|
||||
}
|
||||
func (s *DictionaryService) UpdateDictionaryDetail(ctx context.Context, v *biz.DictionaryDetail) error {
|
||||
return s.uc.UpdateDictionaryDetail(ctx, v)
|
||||
}
|
||||
func (s *DictionaryService) DeleteDictionaryDetail(ctx context.Context, id uint) error {
|
||||
return s.uc.DeleteDictionaryDetail(ctx, id)
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
func (s *DictionaryService) ImportDictionaryJSON(ctx context.Context, raw string) error {
|
||||
var payload struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Status *bool `json:"status"`
|
||||
Description string `json:"desc"`
|
||||
Details []dto.DictionaryDetailRequest `json:"sysDictionaryDetails"`
|
||||
}
|
||||
if err := json.Unmarshal([]byte(raw), &payload); err != nil {
|
||||
return errors.New("JSON 格式错误: " + err.Error())
|
||||
}
|
||||
if payload.Name == "" {
|
||||
return errors.New("字典名称不能为空")
|
||||
}
|
||||
if payload.Type == "" {
|
||||
return errors.New("字典类型不能为空")
|
||||
}
|
||||
dictionary := dictionaryDomain(&dto.DictionaryRequest{Name: payload.Name, Type: payload.Type, Status: payload.Status, Description: payload.Description})
|
||||
details := make([]*biz.DictionaryDetail, 0, len(payload.Details))
|
||||
for i := range payload.Details {
|
||||
details = append(details, detailDomain(&payload.Details[i]))
|
||||
}
|
||||
return s.uc.ImportDictionary(ctx, dictionary, details)
|
||||
}
|
||||
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([]*dto.DictionaryDetailResponse, 0, len(items))
|
||||
for _, item := range items {
|
||||
out = append(out, detailDTO(item))
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"kra/internal/biz"
|
||||
)
|
||||
|
||||
type dictionaryExportRepo struct {
|
||||
biz.DictionaryRepo
|
||||
value *biz.Dictionary
|
||||
}
|
||||
|
||||
func (r dictionaryExportRepo) ExportDictionary(context.Context, uint) (*biz.Dictionary, error) {
|
||||
return r.value, nil
|
||||
}
|
||||
|
||||
func TestExportDictionaryPreservesNilDetails(t *testing.T) {
|
||||
service := NewDictionaryService(biz.NewDictionaryUsecase(dictionaryExportRepo{value: &biz.Dictionary{Name: "empty", Type: "empty"}}))
|
||||
result, err := service.ExportDictionary(context.Background(), 1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if result.SysDictionaryDetails != nil {
|
||||
t.Fatalf("export details = %#v, want nil", result.SysDictionaryDetails)
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package dto
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
type AnnouncementRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
UserID *int `json:"userID"`
|
||||
Attachments json.RawMessage `json:"attachments"`
|
||||
}
|
||||
|
||||
type AnnouncementSearchRequest struct {
|
||||
Page int `form:"page"`
|
||||
PageSize int `form:"pageSize"`
|
||||
StartCreatedAt *time.Time `form:"startCreatedAt"`
|
||||
EndCreatedAt *time.Time `form:"endCreatedAt"`
|
||||
}
|
||||
|
||||
type AnnouncementResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
// Keep the soft-delete slot in the transport shape while omitting it from
|
||||
// JSON responses.
|
||||
DeletedAt any `json:"-"`
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
UserID *int `json:"userID"`
|
||||
Attachments any `json:"attachments"`
|
||||
}
|
||||
|
||||
type SelectOptionResponse struct {
|
||||
Label string `json:"label"`
|
||||
Value uint `json:"value"`
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
package dto
|
||||
|
||||
import "time"
|
||||
|
||||
type APIRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
Path string `json:"path"`
|
||||
Description string `json:"description"`
|
||||
APIGroup string `json:"apiGroup"`
|
||||
Method string `json:"method"`
|
||||
}
|
||||
|
||||
type APIListRequest struct {
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
Path string `json:"path"`
|
||||
Description string `json:"description"`
|
||||
APIGroup string `json:"apiGroup"`
|
||||
Method string `json:"method"`
|
||||
OrderKey string `json:"orderKey"`
|
||||
Desc bool `json:"desc"`
|
||||
}
|
||||
|
||||
type APIResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"-"`
|
||||
Path string `json:"path"`
|
||||
Description string `json:"description"`
|
||||
APIGroup string `json:"apiGroup"`
|
||||
Method string `json:"method"`
|
||||
}
|
||||
|
||||
type DeleteAPIRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
}
|
||||
type DeleteAPIsRequest struct {
|
||||
IDs []uint `json:"ids"`
|
||||
}
|
||||
type GetAPIRequest struct {
|
||||
ID uint `json:"id"`
|
||||
}
|
||||
type SetAPIRolesRequest struct {
|
||||
Path string `json:"path"`
|
||||
Method string `json:"method"`
|
||||
AuthorityIDs []uint `json:"authorityIds"`
|
||||
}
|
||||
type IgnoreAPIRequest struct {
|
||||
Path string `json:"path"`
|
||||
Method string `json:"method"`
|
||||
Flag bool `json:"flag"`
|
||||
}
|
||||
type ApplyAPISyncRequest struct {
|
||||
NewAPIs []APIRequest `json:"newApis"`
|
||||
DeleteAPIs []APIRequest `json:"deleteApis"`
|
||||
}
|
||||
type PolicyPathRequest struct {
|
||||
Path string `json:"path"`
|
||||
Method string `json:"method"`
|
||||
}
|
||||
type SetPolicyPathsRequest struct {
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
Infos []PolicyPathRequest `json:"casbinInfos"`
|
||||
}
|
||||
type GetPolicyPathsRequest struct {
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
}
|
||||
|
||||
type APISyncResponse struct {
|
||||
NewAPIs []*APIResponse `json:"newApis"`
|
||||
DeleteAPIs []*APIResponse `json:"deleteApis"`
|
||||
IgnoreAPIs []*APIResponse `json:"ignoreApis"`
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
package dto
|
||||
|
||||
import "time"
|
||||
|
||||
type OperationRecordRequest struct {
|
||||
IP string
|
||||
Method string
|
||||
Path string
|
||||
Status int
|
||||
LatencyMS int64
|
||||
Agent string
|
||||
ErrorMessage string
|
||||
Body string
|
||||
Response string
|
||||
UserID uint
|
||||
RequestID string
|
||||
TraceID string
|
||||
DeviceID string
|
||||
}
|
||||
|
||||
type DataAccessRecordRequest struct {
|
||||
EventType string
|
||||
Operation string
|
||||
UserID uint
|
||||
AuthorityID uint
|
||||
RequestID string
|
||||
Method string
|
||||
Path string
|
||||
Detail string
|
||||
}
|
||||
|
||||
type DataAccessListRequest struct {
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
EventType string `json:"eventType"`
|
||||
TargetTable string `json:"targetTable"`
|
||||
}
|
||||
|
||||
type OperationRecordSearchRequest struct {
|
||||
Page int `form:"page"`
|
||||
PageSize int `form:"pageSize"`
|
||||
Path string `form:"path"`
|
||||
Method string `form:"method"`
|
||||
Status int `form:"status"`
|
||||
}
|
||||
|
||||
type LoginLogSearchRequest struct {
|
||||
Page int `form:"page"`
|
||||
PageSize int `form:"pageSize"`
|
||||
Username string `form:"username"`
|
||||
Status bool `form:"status"`
|
||||
}
|
||||
|
||||
type AuditIDQuery struct {
|
||||
ID uint `form:"ID"`
|
||||
}
|
||||
|
||||
type AuditIDsRequest struct {
|
||||
IDs []int `json:"ids"`
|
||||
}
|
||||
|
||||
type ErrorRecordRequest struct {
|
||||
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"`
|
||||
}
|
||||
|
||||
// ErrorRecordMutationRequest mirrors the public error-record model. Pointer
|
||||
// fields preserve the distinction between an omitted value and an explicitly
|
||||
// supplied empty string, which is required by the update contract.
|
||||
type ErrorRecordMutationRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
Form *string `json:"form" binding:"required"`
|
||||
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 OperationRecordResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"-"`
|
||||
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"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"-"`
|
||||
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"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"-"`
|
||||
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"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"-"`
|
||||
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"`
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package dto
|
||||
|
||||
import (
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func bindErrorMutation(t *testing.T, body string) (ErrorRecordMutationRequest, error) {
|
||||
t.Helper()
|
||||
context, _ := gin.CreateTestContext(httptest.NewRecorder())
|
||||
context.Request = httptest.NewRequest("PUT", "/sysError/updateSysError", strings.NewReader(body))
|
||||
context.Request.Header.Set("Content-Type", "application/json")
|
||||
var request ErrorRecordMutationRequest
|
||||
return request, context.ShouldBindJSON(&request)
|
||||
}
|
||||
|
||||
func TestErrorRecordMutationAcceptsExplicitEmptyPointerFields(t *testing.T) {
|
||||
request, err := bindErrorMutation(t, `{"ID":1,"form":"","info":"","solution":""}`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if request.Form == nil || *request.Form != "" || request.Info == nil || *request.Info != "" || request.Solution == nil || *request.Solution != "" {
|
||||
t.Fatalf("explicit empty values lost: form=%#v info=%#v solution=%#v", request.Form, request.Info, request.Solution)
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorRecordMutationRequiresFormButKeepsOtherFieldsOmittable(t *testing.T) {
|
||||
request, err := bindErrorMutation(t, `{"ID":1}`)
|
||||
if err == nil {
|
||||
t.Fatal("missing form unexpectedly accepted")
|
||||
}
|
||||
if request.Info != nil || request.Solution != nil {
|
||||
t.Fatalf("omitted fields = (%#v, %#v), want nil", request.Info, request.Solution)
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package dto
|
||||
|
||||
type LoginResponse struct {
|
||||
User *UserResponse `json:"user"`
|
||||
Token string `json:"token"`
|
||||
ExpiresAt int64 `json:"expiresAt"`
|
||||
NeedChangePassword bool `json:"needChangePassword"`
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package dto
|
||||
|
||||
import "time"
|
||||
|
||||
type AuthorityRequest struct {
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
AuthorityName string `json:"authorityName"`
|
||||
ParentID *uint `json:"parentId"`
|
||||
DataScope int `json:"dataScope"`
|
||||
DefaultRouter string `json:"defaultRouter"`
|
||||
}
|
||||
|
||||
type CopyAuthorityRequest struct {
|
||||
Authority AuthorityRequest `json:"authority"`
|
||||
OldAuthorityID uint `json:"oldAuthorityId"`
|
||||
}
|
||||
|
||||
type DeleteAuthorityRequest struct {
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
}
|
||||
type SetRoleUsersRequest struct {
|
||||
AuthorityID uint `json:"authorityId" form:"authorityId"`
|
||||
UserIDs []uint `json:"userIds" form:"userIds"`
|
||||
}
|
||||
type SetDataScopeRequest struct {
|
||||
AuthorityID uint `json:"authorityId" form:"authorityId"`
|
||||
DataScope int `json:"dataScope" form:"dataScope"`
|
||||
DepartmentIDs []uint `json:"deptIds" form:"deptIds"`
|
||||
}
|
||||
|
||||
type AuthorityResponse struct {
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt *time.Time `json:"DeletedAt"`
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
AuthorityName string `json:"authorityName"`
|
||||
ParentID *uint `json:"parentId"`
|
||||
Children []*AuthorityResponse `json:"children"`
|
||||
Menus []*MenuResponse `json:"menus"`
|
||||
DataScope int `json:"dataScope"`
|
||||
DefaultRouter string `json:"defaultRouter"`
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package dto
|
||||
|
||||
type SendEmailRequest struct {
|
||||
To string `json:"to"`
|
||||
Subject string `json:"subject"`
|
||||
Body string `json:"body"`
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
package dto
|
||||
|
||||
import "time"
|
||||
|
||||
type ExportConditionRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
TemplateID string `json:"templateID"`
|
||||
From string `json:"from"`
|
||||
Column string `json:"column"`
|
||||
Operator string `json:"operator"`
|
||||
}
|
||||
type ExportJoinRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
TemplateID string `json:"templateID"`
|
||||
Join string `json:"joins"`
|
||||
Table string `json:"table"`
|
||||
On string `json:"on"`
|
||||
}
|
||||
type ExportTemplateRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
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 []ExportConditionRequest `json:"conditions"`
|
||||
Joins []ExportJoinRequest `json:"joinTemplate"`
|
||||
}
|
||||
|
||||
type ExportConditionResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
TemplateID string `json:"templateID"`
|
||||
From string `json:"from"`
|
||||
Column string `json:"column"`
|
||||
Operator string `json:"operator"`
|
||||
}
|
||||
|
||||
type ExportJoinResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
TemplateID string `json:"templateID"`
|
||||
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"`
|
||||
// The compatible embedded gorm.DeletedAt field is json:"-".
|
||||
DeletedAt any `json:"-"`
|
||||
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"`
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
package dto
|
||||
|
||||
import "time"
|
||||
|
||||
type MediaResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
// The compatible model embeds gorm.DeletedAt with json:"-", so this field is omitted.
|
||||
DeletedAt any `json:"-"`
|
||||
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:"-"`
|
||||
Name string `json:"name"`
|
||||
PID uint `json:"pid"`
|
||||
Children []*MediaCategoryResponse `json:"children"`
|
||||
}
|
||||
|
||||
type StorageObjectResponse struct {
|
||||
Key string `json:"Key"`
|
||||
Size int64 `json:"Size"`
|
||||
LastModified time.Time `json:"LastModified"`
|
||||
ContentType string `json:"ContentType"`
|
||||
}
|
||||
|
||||
type InitUploadResponse struct {
|
||||
Instant bool `json:"instant"`
|
||||
UploadID uint `json:"uploadId"`
|
||||
UploadedChunks []int `json:"uploadedChunks"`
|
||||
Media *MediaResponse `json:"media,omitempty"`
|
||||
}
|
||||
|
||||
type MediaListRequest struct {
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
Keyword string `json:"keyword"`
|
||||
ClassID int `json:"classId"`
|
||||
Tag string `json:"tag"`
|
||||
UserID uint `json:"userId"`
|
||||
StartCreatedAt time.Time `json:"startCreatedAt"`
|
||||
EndCreatedAt time.Time `json:"endCreatedAt"`
|
||||
OrderKey string `json:"orderKey"`
|
||||
Desc bool `json:"desc"`
|
||||
}
|
||||
type IDRequest struct {
|
||||
ID uint `json:"ID" form:"id"`
|
||||
}
|
||||
type IDsRequest struct {
|
||||
IDs []uint `json:"ids"`
|
||||
}
|
||||
type MediaBatchDeleteRequest struct {
|
||||
IDs []uint `json:"ids" binding:"required"`
|
||||
}
|
||||
type RenameMediaRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
type ImportMediaRequest struct {
|
||||
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 StorageListRequest struct {
|
||||
Prefix string `json:"prefix"`
|
||||
Cursor string `json:"cursor"`
|
||||
Limit int `json:"limit"`
|
||||
}
|
||||
type CategoryRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
Name string `json:"name"`
|
||||
PID uint `json:"pid"`
|
||||
}
|
||||
type InitUploadRequest struct {
|
||||
FileName string `json:"fileName" binding:"required"`
|
||||
FileHash string `json:"fileHash" binding:"required"`
|
||||
FileSize int64 `json:"fileSize" binding:"required"`
|
||||
ChunkSize int64 `json:"chunkSize" binding:"required"`
|
||||
ChunkTotal int `json:"chunkTotal" binding:"required"`
|
||||
Mime string `json:"mime"`
|
||||
}
|
||||
type CompleteUploadRequest struct {
|
||||
UploadID uint `json:"uploadId" binding:"required"`
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
package dto
|
||||
|
||||
import "time"
|
||||
|
||||
type MenuMetaRequest struct {
|
||||
ActiveName string `json:"activeName"`
|
||||
KeepAlive bool `json:"keepAlive"`
|
||||
DefaultMenu bool `json:"defaultMenu"`
|
||||
Title string `json:"title"`
|
||||
Icon string `json:"icon"`
|
||||
CloseTab bool `json:"closeTab"`
|
||||
TransitionType string `json:"transitionType"`
|
||||
}
|
||||
|
||||
type MenuButtonRequest struct {
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
ID uint `json:"ID"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"desc"`
|
||||
SysBaseMenuID uint `json:"sysBaseMenuID"`
|
||||
}
|
||||
|
||||
type MenuParameterRequest struct {
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
ID uint `json:"ID"`
|
||||
SysBaseMenuID uint `json:"SysBaseMenuID"`
|
||||
Type string `json:"type"`
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type MenuRequest struct {
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
ID uint `json:"ID"`
|
||||
ParentID uint `json:"parentId"`
|
||||
Path string `json:"path"`
|
||||
Name string `json:"name"`
|
||||
Hidden bool `json:"hidden"`
|
||||
Component string `json:"component"`
|
||||
Sort int `json:"sort"`
|
||||
Meta MenuMetaRequest `json:"meta"`
|
||||
MenuButtons []MenuButtonRequest `json:"menuBtn"`
|
||||
Parameters []MenuParameterRequest `json:"parameters"`
|
||||
}
|
||||
|
||||
type DeleteMenuRequest struct {
|
||||
ID int `json:"id"`
|
||||
}
|
||||
|
||||
type GetMenuRequest struct {
|
||||
ID int `json:"id"`
|
||||
}
|
||||
|
||||
type SetAuthorityMenusRequest struct {
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
Menus []MenuRequest `json:"menus"`
|
||||
}
|
||||
|
||||
type GetAuthorityMenusRequest struct {
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
}
|
||||
|
||||
type SetMenuRolesRequest struct {
|
||||
MenuID uint `json:"menuId" form:"menuId"`
|
||||
AuthorityIDs []uint `json:"authorityIds"`
|
||||
}
|
||||
|
||||
type MenuMetaResponse struct {
|
||||
ActiveName string `json:"activeName"`
|
||||
KeepAlive bool `json:"keepAlive"`
|
||||
DefaultMenu bool `json:"defaultMenu"`
|
||||
Title string `json:"title"`
|
||||
Icon string `json:"icon"`
|
||||
CloseTab bool `json:"closeTab"`
|
||||
TransitionType string `json:"transitionType"`
|
||||
}
|
||||
|
||||
type MenuButtonResponse struct {
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
ID uint `json:"ID"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"desc"`
|
||||
SysBaseMenuID uint `json:"sysBaseMenuID"`
|
||||
}
|
||||
|
||||
type MenuParameterResponse struct {
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
ID uint `json:"ID"`
|
||||
SysBaseMenuID uint `json:"SysBaseMenuID"`
|
||||
Type string `json:"type"`
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type MenuResponse struct {
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
ID uint `json:"ID"`
|
||||
MenuID uint `json:"menuId,omitempty"`
|
||||
ParentID uint `json:"parentId"`
|
||||
Path string `json:"path"`
|
||||
Name string `json:"name"`
|
||||
Hidden bool `json:"hidden"`
|
||||
Component string `json:"component"`
|
||||
Sort int `json:"sort"`
|
||||
Meta MenuMetaResponse `json:"meta"`
|
||||
Children []*MenuResponse `json:"children"`
|
||||
Parameters []MenuParameterResponse `json:"parameters"`
|
||||
MenuButtons []MenuButtonResponse `json:"menuBtn"`
|
||||
Authorities []*AuthorityResponse `json:"authoritys"`
|
||||
}
|
||||
|
||||
type DynamicMenuResponse struct {
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
ID uint `json:"ID"`
|
||||
MenuID uint `json:"menuId"`
|
||||
ParentID uint `json:"parentId"`
|
||||
Path string `json:"path"`
|
||||
Name string `json:"name"`
|
||||
Hidden bool `json:"hidden"`
|
||||
Component string `json:"component"`
|
||||
Sort int `json:"sort"`
|
||||
Meta MenuMetaResponse `json:"meta"`
|
||||
Children []*DynamicMenuResponse `json:"children"`
|
||||
Parameters []MenuParameterResponse `json:"parameters"`
|
||||
MenuButtons []MenuButtonResponse `json:"menuBtn"`
|
||||
Buttons map[string]uint `json:"btns"`
|
||||
Authorities []*AuthorityResponse `json:"authoritys"`
|
||||
}
|
||||
|
||||
type AuthorityMenuResponse struct {
|
||||
// The administration response embeds the base-menu fields, so menu fields are
|
||||
// flat in the response (there is no sysBaseMenu envelope). Keep the
|
||||
// authority ID internal, matching the compatible json:"-" field.
|
||||
*DynamicMenuResponse
|
||||
AuthorityID uint `json:"-"`
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
package dto
|
||||
|
||||
import "time"
|
||||
|
||||
type DepartmentRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
Name string `json:"name"`
|
||||
ParentID uint `json:"parentId"`
|
||||
Sort int `json:"sort"`
|
||||
LeaderID uint `json:"leaderId"`
|
||||
Status *bool `json:"status"`
|
||||
}
|
||||
|
||||
type DepartmentListRequest struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
type DeleteDepartmentRequest struct {
|
||||
ID uint `json:"ID" form:"id"`
|
||||
}
|
||||
type SetDepartmentUsersRequest struct {
|
||||
DepartmentID uint `json:"deptId" form:"deptId"`
|
||||
UserIDs []uint `json:"userIds"`
|
||||
}
|
||||
type SetUserDepartmentsRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
DepartmentIDs []uint `json:"deptIds"`
|
||||
Primary uint `json:"primaryDeptId"`
|
||||
}
|
||||
|
||||
type DepartmentResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"-"`
|
||||
Name string `json:"name"`
|
||||
ParentID uint `json:"parentId"`
|
||||
Ancestors string `json:"ancestors"`
|
||||
Sort int `json:"sort"`
|
||||
LeaderID uint `json:"leaderId"`
|
||||
Leader any `json:"leader"`
|
||||
Status *bool `json:"status"`
|
||||
Children []*DepartmentResponse `json:"children"`
|
||||
NamePath string `json:"namePath"`
|
||||
}
|
||||
|
||||
type PositionRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
Name string `json:"name"`
|
||||
Code string `json:"code"`
|
||||
Sort int `json:"sort"`
|
||||
Status *bool `json:"status"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
type PositionListRequest struct {
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
Name string `json:"name"`
|
||||
Code string `json:"code"`
|
||||
Status *bool `json:"status"`
|
||||
}
|
||||
type DeletePositionRequest struct {
|
||||
ID uint `json:"ID" form:"id"`
|
||||
}
|
||||
type SetPositionUsersRequest struct {
|
||||
PositionID uint `json:"positionId" form:"positionId"`
|
||||
UserIDs []uint `json:"userIds"`
|
||||
}
|
||||
type SetUserPositionsRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
PositionIDs []uint `json:"positionIds"`
|
||||
}
|
||||
|
||||
type PositionResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"-"`
|
||||
Name string `json:"name"`
|
||||
Code string `json:"code"`
|
||||
Sort int `json:"sort"`
|
||||
Status *bool `json:"status"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
package dto
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
type PaymentConfigRequest struct {
|
||||
Provider string `json:"provider"`
|
||||
Enabled bool `json:"enabled"`
|
||||
Config json.RawMessage `json:"config"`
|
||||
}
|
||||
|
||||
// PaymentConfigResponse is the transport representation returned by the
|
||||
// payment configuration endpoint. Values are already masked by the usecase's
|
||||
// repository boundary.
|
||||
type PaymentConfigResponse struct {
|
||||
Provider string `json:"provider"`
|
||||
Enabled bool `json:"enabled"`
|
||||
Config json.RawMessage `json:"config"`
|
||||
}
|
||||
|
||||
type PaymentOrderListRequest struct {
|
||||
Page int `form:"page"`
|
||||
PageSize int `form:"pageSize"`
|
||||
Provider string `form:"provider"`
|
||||
TradeNo string `form:"tradeNo"`
|
||||
BusinessType string `form:"businessType"`
|
||||
BusinessID string `form:"businessId"`
|
||||
PaymentStatus string `form:"paymentStatus"`
|
||||
RefundStatus string `form:"refundStatus"`
|
||||
}
|
||||
|
||||
type PaymentRequest struct {
|
||||
Provider string `json:"provider"`
|
||||
TradeNo string `json:"tradeNo"`
|
||||
Subject string `json:"subject"`
|
||||
Amount int64 `json:"amount"`
|
||||
OriginalAmount int64 `json:"originalAmount"`
|
||||
Currency string `json:"currency"`
|
||||
NotifyURL string `json:"notifyUrl"`
|
||||
ReturnURL string `json:"returnUrl"`
|
||||
Extra map[string]any `json:"extra"`
|
||||
ClientIP string `json:"-"`
|
||||
BusinessType string `json:"businessType"`
|
||||
BusinessID string `json:"businessId"`
|
||||
PaymentMode string `json:"paymentMode"`
|
||||
}
|
||||
type PaymentQueryRequest struct {
|
||||
Provider string `json:"provider"`
|
||||
TradeNo string `json:"tradeNo"`
|
||||
}
|
||||
type PaymentRefundRequest struct {
|
||||
Provider string `json:"provider"`
|
||||
TradeNo string `json:"tradeNo"`
|
||||
Amount int64 `json:"amount"`
|
||||
}
|
||||
|
||||
// PaymentCallbackRequest is populated by the HTTP transport and converted to
|
||||
// the biz callback object inside service.
|
||||
type PaymentCallbackRequest struct {
|
||||
Provider string
|
||||
Headers map[string]string
|
||||
Body []byte
|
||||
Query map[string]string
|
||||
}
|
||||
|
||||
type PaymentCallbackAck struct {
|
||||
StatusCode int
|
||||
ContentType string
|
||||
Body []byte
|
||||
}
|
||||
|
||||
type PaymentResultResponse struct {
|
||||
Provider string `json:"provider"`
|
||||
Status string `json:"status"`
|
||||
TradeNo string `json:"tradeNo"`
|
||||
ProviderTradeNo string `json:"providerTradeNo"`
|
||||
Amount int64 `json:"amount"`
|
||||
PayerPaidAmount int64 `json:"payerPaidAmount,omitempty"`
|
||||
CashPaidAmount int64 `json:"cashPaidAmount,omitempty"`
|
||||
PointPaidAmount int64 `json:"pointPaidAmount,omitempty"`
|
||||
DiscountAmount int64 `json:"discountAmount,omitempty"`
|
||||
ProviderDiscountAmount int64 `json:"providerDiscountAmount,omitempty"`
|
||||
MerchantDiscountAmount int64 `json:"merchantDiscountAmount,omitempty"`
|
||||
SettlementAmount int64 `json:"settlementAmount,omitempty"`
|
||||
Currency string `json:"currency"`
|
||||
PayerCurrency string `json:"payerCurrency,omitempty"`
|
||||
AmountBreakdownKnown bool `json:"amountBreakdownKnown"`
|
||||
Duplicate bool `json:"duplicate"`
|
||||
Payload json.RawMessage `json:"payload"`
|
||||
OrderStatus string `json:"orderStatus,omitempty"`
|
||||
FulfillmentStatus string `json:"fulfillmentStatus,omitempty"`
|
||||
RefundStatus string `json:"refundStatus,omitempty"`
|
||||
}
|
||||
|
||||
type PaymentOrderResponse struct {
|
||||
ID uint64 `json:"ID"`
|
||||
Provider string `json:"provider"`
|
||||
TradeNo string `json:"tradeNo"`
|
||||
ProviderTradeNo string `json:"providerTradeNo"`
|
||||
BusinessType string `json:"businessType"`
|
||||
BusinessID string `json:"businessId"`
|
||||
Subject string `json:"subject"`
|
||||
PaymentMode string `json:"paymentMode"`
|
||||
OriginalAmount int64 `json:"originalAmount"`
|
||||
Amount int64 `json:"amount"`
|
||||
PaidAmount int64 `json:"paidAmount"`
|
||||
PayerPaidAmount int64 `json:"payerPaidAmount"`
|
||||
CashPaidAmount int64 `json:"cashPaidAmount"`
|
||||
PointPaidAmount int64 `json:"pointPaidAmount"`
|
||||
DiscountAmount int64 `json:"discountAmount"`
|
||||
ProviderDiscountAmount int64 `json:"providerDiscountAmount"`
|
||||
MerchantDiscountAmount int64 `json:"merchantDiscountAmount"`
|
||||
SettlementAmount int64 `json:"settlementAmount"`
|
||||
Currency string `json:"currency"`
|
||||
PayerCurrency string `json:"payerCurrency,omitempty"`
|
||||
AmountBreakdownKnown bool `json:"amountBreakdownKnown"`
|
||||
PaymentStatus string `json:"paymentStatus"`
|
||||
ProviderStatus string `json:"providerStatus"`
|
||||
FulfillmentStatus string `json:"fulfillmentStatus"`
|
||||
RefundStatus string `json:"refundStatus"`
|
||||
RefundedAmount int64 `json:"refundedAmount"`
|
||||
RefundRequestedAmount int64 `json:"refundRequestedAmount"`
|
||||
RefundNo string `json:"refundNo,omitempty"`
|
||||
LastError string `json:"lastError,omitempty"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
PaidAt *time.Time `json:"paidAt,omitempty"`
|
||||
FulfilledAt *time.Time `json:"fulfilledAt,omitempty"`
|
||||
RefundedAt *time.Time `json:"refundedAt,omitempty"`
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package dto
|
||||
|
||||
type GetAuthorityButtonsRequest struct {
|
||||
MenuID uint `json:"menuID"`
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
Selected []uint `json:"selected"`
|
||||
}
|
||||
|
||||
type SetAuthorityButtonsRequest struct {
|
||||
MenuID uint `json:"menuID"`
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
Selected []uint `json:"selected"`
|
||||
}
|
||||
@@ -1,172 +0,0 @@
|
||||
package dto
|
||||
|
||||
import "time"
|
||||
|
||||
type DictionaryRequest struct {
|
||||
ID uint `json:"ID" form:"ID"`
|
||||
Name string `json:"name" form:"name"`
|
||||
Type string `json:"type" form:"type"`
|
||||
Status *bool `json:"status" form:"status"`
|
||||
Description string `json:"desc" form:"desc"`
|
||||
ParentID *uint `json:"parentID" form:"parentID"`
|
||||
}
|
||||
type DictionaryDetailRequest struct {
|
||||
ID uint `json:"ID" form:"ID"`
|
||||
Label string `json:"label" form:"label"`
|
||||
Value string `json:"value" form:"value"`
|
||||
Extend string `json:"extend" form:"extend"`
|
||||
Status *bool `json:"status" form:"status"`
|
||||
Sort int `json:"sort" form:"sort"`
|
||||
DictionaryID uint `json:"sysDictionaryID" form:"sysDictionaryID"`
|
||||
ParentID *uint `json:"parentID" form:"parentID"`
|
||||
Level int `json:"level"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
type ImportDictionaryRequest struct {
|
||||
JSON string `json:"json"`
|
||||
}
|
||||
type DictionaryDetailsByParentRequest struct {
|
||||
DictionaryID uint `json:"sysDictionaryID" form:"sysDictionaryID" binding:"required"`
|
||||
ParentID *uint `json:"parentID" form:"parentID"`
|
||||
IncludeChildren bool `json:"includeChildren" form:"includeChildren"`
|
||||
}
|
||||
|
||||
type DictionaryDetailListRequest struct {
|
||||
DictionaryID uint
|
||||
Label string
|
||||
Value string
|
||||
Status *bool
|
||||
ParentID *uint
|
||||
Level *int
|
||||
}
|
||||
type SystemParameterRequest struct {
|
||||
ID uint `json:"ID" form:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt" form:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt" form:"UpdatedAt"`
|
||||
Name string `json:"name" form:"name" binding:"required"`
|
||||
Key string `json:"key" form:"key" binding:"required"`
|
||||
Value string `json:"value" form:"value" binding:"required"`
|
||||
Description string `json:"desc" form:"desc"`
|
||||
}
|
||||
|
||||
type SystemParameterSearchRequest struct {
|
||||
Page int `json:"page" form:"page"`
|
||||
PageSize int `json:"pageSize" form:"pageSize"`
|
||||
StartCreatedAt *time.Time `json:"startCreatedAt" form:"startCreatedAt"`
|
||||
EndCreatedAt *time.Time `json:"endCreatedAt" form:"endCreatedAt"`
|
||||
Name string `json:"name" form:"name"`
|
||||
Key string `json:"key" form:"key"`
|
||||
}
|
||||
type CreateAPITokenRequest struct {
|
||||
UserID uint `json:"userId"`
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
Days int `json:"days"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
type APITokenListRequest struct {
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
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:"-"`
|
||||
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"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"-"`
|
||||
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:"-"`
|
||||
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:"-"`
|
||||
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:"-"`
|
||||
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,133 +0,0 @@
|
||||
package dto
|
||||
|
||||
import "time"
|
||||
|
||||
type LoginRequest struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Captcha string `json:"captcha"`
|
||||
CaptchaID string `json:"captchaId"`
|
||||
}
|
||||
|
||||
type Route struct {
|
||||
Path string
|
||||
Method string
|
||||
}
|
||||
|
||||
type UserListRequest struct {
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
Username string `json:"username"`
|
||||
NickName string `json:"nickName"`
|
||||
Phone string `json:"phone"`
|
||||
Email string `json:"email"`
|
||||
OrderKey string `json:"orderKey"`
|
||||
Desc bool `json:"desc"`
|
||||
}
|
||||
|
||||
type UserRequest struct {
|
||||
ID uint `json:"ID" form:"id"`
|
||||
Username string `json:"userName"`
|
||||
Password string `json:"passWord"`
|
||||
NickName string `json:"nickName"`
|
||||
HeaderImg string `json:"headerImg"`
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
AuthorityIDs []uint `json:"authorityIds"`
|
||||
Enable int `json:"enable"`
|
||||
Phone string `json:"phone"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
type SelfUserRequest struct {
|
||||
NickName string `json:"nickName"`
|
||||
HeaderImg string `json:"headerImg"`
|
||||
Phone string `json:"phone"`
|
||||
Email string `json:"email"`
|
||||
Enable int `json:"enable"`
|
||||
}
|
||||
|
||||
type ResetPasswordRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
type ChangePasswordRequest struct {
|
||||
Password string `json:"password"`
|
||||
NewPassword string `json:"newPassword"`
|
||||
}
|
||||
|
||||
type UserAuthoritiesRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
AuthorityIDs []uint `json:"authorityIds"`
|
||||
}
|
||||
|
||||
type SwitchAuthorityRequest struct {
|
||||
AuthorityID uint `json:"authorityId"`
|
||||
}
|
||||
|
||||
type LoginLogRequest struct {
|
||||
Username string
|
||||
IP string
|
||||
Status bool
|
||||
ErrorMessage string
|
||||
Agent string
|
||||
UserID uint
|
||||
}
|
||||
|
||||
type UserResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"-"`
|
||||
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"`
|
||||
PasswordUpdatedAt *time.Time `json:"passwordUpdatedAt"`
|
||||
}
|
||||
|
||||
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,30 +0,0 @@
|
||||
package dto
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
type SecurityConfigRequest 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 SetSystemConfigRequest struct {
|
||||
Config json.RawMessage `json:"config"`
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package dto
|
||||
|
||||
type DatabaseInitRequest struct {
|
||||
DBType string `json:"dbType"`
|
||||
Host string `json:"host"`
|
||||
Port string `json:"port"`
|
||||
UserName string `json:"userName"`
|
||||
Password string `json:"password"`
|
||||
DBName string `json:"dbName" binding:"required"`
|
||||
DBPath string `json:"dbPath"`
|
||||
Template string `json:"template"`
|
||||
AdminPassword string `json:"adminPassword" binding:"required"`
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
package dto
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
type TaskRequest struct {
|
||||
ID uint `json:"ID"`
|
||||
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"`
|
||||
}
|
||||
|
||||
type DeleteTaskRequest struct {
|
||||
ID uint `json:"ID" binding:"required"`
|
||||
}
|
||||
type ToggleTaskRequest struct {
|
||||
ID uint `json:"ID" binding:"required"`
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
type TaskListRequest struct {
|
||||
Page int `form:"page"`
|
||||
PageSize int `form:"pageSize"`
|
||||
Name string `form:"name"`
|
||||
ExecutorType string `form:"executorType"`
|
||||
Enabled *bool `form:"enabled"`
|
||||
}
|
||||
|
||||
type TaskLogListRequest struct {
|
||||
Page int `form:"page"`
|
||||
PageSize int `form:"pageSize"`
|
||||
TaskID uint `form:"taskId"`
|
||||
Status string `form:"status"`
|
||||
}
|
||||
|
||||
type TaskResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"-"`
|
||||
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"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"-"`
|
||||
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,94 +0,0 @@
|
||||
package dto
|
||||
|
||||
import "time"
|
||||
|
||||
type VersionResponse struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
DeletedAt any `json:"-"`
|
||||
VersionName *string `json:"versionName"`
|
||||
VersionCode *string `json:"versionCode"`
|
||||
Description *string `json:"description"`
|
||||
VersionData *string `json:"versionData"`
|
||||
}
|
||||
|
||||
type VersionSearchRequest struct {
|
||||
CreatedAtRange []time.Time `json:"createdAtRange" form:"createdAtRange[]"`
|
||||
VersionName *string `json:"versionName" form:"versionName"`
|
||||
VersionCode *string `json:"versionCode" form:"versionCode"`
|
||||
Page int `json:"page" form:"page"`
|
||||
PageSize int `json:"pageSize" form:"pageSize"`
|
||||
}
|
||||
|
||||
type VersionMenuMetaRequest struct {
|
||||
ActiveName string `json:"activeName"`
|
||||
KeepAlive bool `json:"keepAlive"`
|
||||
DefaultMenu bool `json:"defaultMenu"`
|
||||
Title string `json:"title"`
|
||||
Icon string `json:"icon"`
|
||||
CloseTab bool `json:"closeTab"`
|
||||
TransitionType string `json:"transitionType"`
|
||||
}
|
||||
type VersionMenuButtonRequest struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"desc"`
|
||||
}
|
||||
type VersionMenuParameterRequest struct {
|
||||
Type string `json:"type"`
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
type VersionMenuRequest struct {
|
||||
Path string `json:"path"`
|
||||
Name string `json:"name"`
|
||||
Hidden bool `json:"hidden"`
|
||||
Component string `json:"component"`
|
||||
Sort int `json:"sort"`
|
||||
Meta VersionMenuMetaRequest `json:"meta"`
|
||||
MenuButtons []VersionMenuButtonRequest `json:"menuBtn"`
|
||||
Parameters []VersionMenuParameterRequest `json:"parameters"`
|
||||
Children []VersionMenuRequest `json:"children"`
|
||||
}
|
||||
type VersionAPIRequest struct {
|
||||
Path string `json:"path"`
|
||||
Description string `json:"description"`
|
||||
APIGroup string `json:"apiGroup"`
|
||||
Method string `json:"method"`
|
||||
}
|
||||
type VersionDictionaryDetailRequest struct {
|
||||
Label string `json:"label"`
|
||||
Value string `json:"value"`
|
||||
Extend string `json:"extend"`
|
||||
Status *bool `json:"status"`
|
||||
Sort int `json:"sort"`
|
||||
ParentID *uint `json:"parentID"`
|
||||
Level int `json:"level"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
type VersionDictionaryRequest struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Status *bool `json:"status"`
|
||||
Description string `json:"desc"`
|
||||
Details []VersionDictionaryDetailRequest `json:"sysDictionaryDetails"`
|
||||
}
|
||||
type ImportVersionRequest struct {
|
||||
Version struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Code string `json:"code" binding:"required"`
|
||||
Description string `json:"description"`
|
||||
ExportTime string `json:"exportTime"`
|
||||
} `json:"version" binding:"required"`
|
||||
Menus []VersionMenuRequest `json:"menus"`
|
||||
APIs []VersionAPIRequest `json:"apis"`
|
||||
Dictionaries []VersionDictionaryRequest `json:"dictionaries"`
|
||||
}
|
||||
type ExportVersionRequest struct {
|
||||
VersionName string `json:"versionName" binding:"required"`
|
||||
VersionCode string `json:"versionCode" binding:"required"`
|
||||
Description string `json:"description"`
|
||||
MenuIDs []uint `json:"menuIds"`
|
||||
APIIDs []uint `json:"apiIds"`
|
||||
DictIDs []uint `json:"dictIds"`
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"kra/internal/biz"
|
||||
)
|
||||
|
||||
type EmailService struct{ uc *biz.EmailUsecase }
|
||||
|
||||
func NewEmailService(uc *biz.EmailUsecase) *EmailService { return &EmailService{uc: uc} }
|
||||
|
||||
func (s *EmailService) Test(ctx context.Context) error { return s.uc.Test(ctx) }
|
||||
|
||||
func (s *EmailService) Send(ctx context.Context, to, subject, body string) error {
|
||||
return s.uc.Send(ctx, to, subject, body)
|
||||
}
|
||||
|
||||
func (s *EmailService) Alert(ctx context.Context, subject, body string) error {
|
||||
return s.uc.Alert(ctx, subject, body)
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrExportTokenInvalid = errors.New("export token invalid")
|
||||
ErrExportTokenMalformed = errors.New("export token malformed")
|
||||
ErrExportTokenType = errors.New("export token type mismatch")
|
||||
)
|
||||
|
||||
type ExportService struct {
|
||||
uc *biz.ExportUsecase
|
||||
cache biz.Cache
|
||||
}
|
||||
|
||||
type ExportToken struct {
|
||||
TemplateID string
|
||||
Params map[string]string
|
||||
Blank bool
|
||||
}
|
||||
|
||||
type exportTokenCache struct {
|
||||
TemplateID string `json:"templateID"`
|
||||
Params map[string]string `json:"params"`
|
||||
Blank bool `json:"blank"`
|
||||
}
|
||||
|
||||
func NewExportService(uc *biz.ExportUsecase, cache biz.Cache) *ExportService {
|
||||
return &ExportService{uc: uc, cache: cache}
|
||||
}
|
||||
|
||||
func (s *ExportService) IssueToken(ctx context.Context, templateID string, params map[string]string, blank bool) (string, error) {
|
||||
token := strings.ReplaceAll(uuid.NewString(), "-", "")
|
||||
raw, err := json.Marshal(exportTokenCache{TemplateID: templateID, Params: params, Blank: blank})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err = s.cache.Set(ctx, "export:"+token, string(raw), 30*time.Minute); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func (s *ExportService) ConsumeToken(ctx context.Context, token string, expectBlank bool) (*ExportToken, error) {
|
||||
raw, ok, err := s.cache.Get(ctx, "export:"+token)
|
||||
if err != nil || !ok {
|
||||
return nil, ErrExportTokenInvalid
|
||||
}
|
||||
var value exportTokenCache
|
||||
if json.Unmarshal([]byte(raw), &value) != nil {
|
||||
return nil, ErrExportTokenMalformed
|
||||
}
|
||||
if value.Blank != expectBlank {
|
||||
return nil, ErrExportTokenType
|
||||
}
|
||||
_ = s.cache.Delete(ctx, "export:"+token)
|
||||
return &ExportToken{TemplateID: value.TemplateID, Params: value.Params, Blank: value.Blank}, nil
|
||||
}
|
||||
func exportTemplateDomain(value *dto.ExportTemplateRequest) *biz.ExportTemplate {
|
||||
out := &biz.ExportTemplate{ID: value.ID, DBName: value.DBName, Name: value.Name, TableName: value.TableName, TemplateID: value.TemplateID, TemplateInfo: value.TemplateInfo, SQL: value.SQL, ImportSQL: value.ImportSQL, Limit: value.Limit, Order: value.Order}
|
||||
for _, item := range value.Conditions {
|
||||
out.Conditions = append(out.Conditions, biz.ExportCondition{ID: item.ID, CreatedAt: item.CreatedAt, UpdatedAt: item.UpdatedAt, TemplateID: item.TemplateID, From: item.From, Column: item.Column, Operator: item.Operator})
|
||||
}
|
||||
for _, item := range value.Joins {
|
||||
out.Joins = append(out.Joins, biz.ExportJoin{ID: item.ID, CreatedAt: item.CreatedAt, UpdatedAt: item.UpdatedAt, TemplateID: item.TemplateID, Join: item.Join, Table: item.Table, On: item.On})
|
||||
}
|
||||
return out
|
||||
}
|
||||
func (s *ExportService) CreateRequest(ctx context.Context, req *dto.ExportTemplateRequest) error {
|
||||
return s.Create(ctx, exportTemplateDomain(req))
|
||||
}
|
||||
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) ([]*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) *dto.ExportTemplateResponse {
|
||||
var conditions []dto.ExportConditionResponse
|
||||
if v.Conditions != nil {
|
||||
conditions = make([]dto.ExportConditionResponse, 0, len(v.Conditions))
|
||||
for _, x := range v.Conditions {
|
||||
conditions = append(conditions, dto.ExportConditionResponse{ID: x.ID, CreatedAt: x.CreatedAt, UpdatedAt: x.UpdatedAt, TemplateID: x.TemplateID, From: x.From, Column: x.Column, Operator: x.Operator})
|
||||
}
|
||||
}
|
||||
var joins []dto.ExportJoinResponse
|
||||
if v.Joins != nil {
|
||||
joins = make([]dto.ExportJoinResponse, 0, len(v.Joins))
|
||||
for _, x := range v.Joins {
|
||||
joins = append(joins, dto.ExportJoinResponse{ID: x.ID, CreatedAt: x.CreatedAt, UpdatedAt: x.UpdatedAt, TemplateID: x.TemplateID, Join: x.Join, Table: x.Table, On: x.On})
|
||||
}
|
||||
}
|
||||
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)
|
||||
}
|
||||
func (s *ExportService) Update(ctx context.Context, v *biz.ExportTemplate) error {
|
||||
return s.uc.UpdateExportTemplate(ctx, v)
|
||||
}
|
||||
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) (*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) ([]*dto.ExportTemplateResponse, int64, error) {
|
||||
items, total, err := s.uc.ListExportTemplates(ctx, page, size, q)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]*dto.ExportTemplateResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, exportDTO(v))
|
||||
}
|
||||
return out, total, nil
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/xuri/excelize/v2"
|
||||
)
|
||||
|
||||
func templateColumns(raw string) ([]string, map[string]string, error) {
|
||||
labels := map[string]string{}
|
||||
decoder := json.NewDecoder(strings.NewReader(raw))
|
||||
token, err := decoder.Token()
|
||||
if err != nil || token != json.Delim('{') {
|
||||
return nil, nil, err
|
||||
}
|
||||
keys := make([]string, 0)
|
||||
for decoder.More() {
|
||||
keyToken, tokenErr := decoder.Token()
|
||||
if tokenErr != nil {
|
||||
return nil, nil, tokenErr
|
||||
}
|
||||
key := keyToken.(string)
|
||||
var label string
|
||||
if tokenErr = decoder.Decode(&label); tokenErr != nil {
|
||||
return nil, nil, tokenErr
|
||||
}
|
||||
keys = append(keys, key)
|
||||
labels[key] = label
|
||||
}
|
||||
if _, err = decoder.Token(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return keys, labels, nil
|
||||
}
|
||||
func (s *ExportService) Export(ctx context.Context, tid string, params map[string]string) ([]byte, string, error) {
|
||||
template, err := s.uc.FindExportTemplate(ctx, 0, tid)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
rows, _, err := s.uc.QueryExport(ctx, template, params)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
keys, labels, err := templateColumns(template.TemplateInfo)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
file := excelize.NewFile()
|
||||
sheet := file.GetSheetName(0)
|
||||
for column, key := range keys {
|
||||
cell, _ := excelize.CoordinatesToCellName(column+1, 1)
|
||||
_ = file.SetCellValue(sheet, cell, labels[key])
|
||||
}
|
||||
for rowIndex, row := range rows {
|
||||
for column, key := range keys {
|
||||
cell, _ := excelize.CoordinatesToCellName(column+1, rowIndex+2)
|
||||
lookup := strings.ReplaceAll(strings.ReplaceAll(key, `"`, ""), "`", "")
|
||||
if len(template.Joins) > 0 {
|
||||
if parts := strings.Split(lookup, " as "); len(parts) > 1 {
|
||||
lookup = strings.TrimSpace(parts[1])
|
||||
} else if parts = strings.Split(lookup, "."); len(parts) > 1 {
|
||||
lookup = parts[1]
|
||||
}
|
||||
}
|
||||
value := fmt.Sprintf("%v", row[lookup])
|
||||
if timestamp, ok := row[lookup].(time.Time); ok {
|
||||
value = timestamp.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
if number, parseErr := strconv.ParseFloat(value, 64); parseErr == nil {
|
||||
_ = file.SetCellValue(sheet, cell, number)
|
||||
} else {
|
||||
_ = file.SetCellValue(sheet, cell, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
buffer, err := file.WriteToBuffer()
|
||||
_ = file.Close()
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
return buffer.Bytes(), template.Name + ".xlsx", nil
|
||||
}
|
||||
func (s *ExportService) ExportBlankTemplate(ctx context.Context, tid string) ([]byte, string, error) {
|
||||
template, err := s.uc.FindExportTemplate(ctx, 0, tid)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
keys, labels, err := templateColumns(template.TemplateInfo)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
file := excelize.NewFile()
|
||||
sheet := file.GetSheetName(0)
|
||||
for column, key := range keys {
|
||||
cell, _ := excelize.CoordinatesToCellName(column+1, 1)
|
||||
_ = file.SetCellValue(sheet, cell, labels[key])
|
||||
}
|
||||
buffer, err := file.WriteToBuffer()
|
||||
_ = file.Close()
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
return buffer.Bytes(), template.Name + "_template.xlsx", nil
|
||||
}
|
||||
func (s *ExportService) Preview(ctx context.Context, tid string, params map[string]string) (string, error) {
|
||||
template, err := s.uc.FindExportTemplate(ctx, 0, tid)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return s.uc.PreviewExport(ctx, template, params)
|
||||
}
|
||||
func (s *ExportService) Import(ctx context.Context, tid string, reader io.Reader) error {
|
||||
template, err := s.uc.FindExportTemplate(ctx, 0, tid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
file, err := excelize.OpenReader(reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
rows, err := file.GetRows("Sheet1")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(rows) < 2 {
|
||||
return errors.New("Excel data is not enough.\nIt should contain title row and data")
|
||||
}
|
||||
keys, labels, err := templateColumns(template.TemplateInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
reverse := map[string]string{}
|
||||
for _, key := range keys {
|
||||
reverse[labels[key]] = key
|
||||
}
|
||||
headers := rows[0]
|
||||
for index := range headers {
|
||||
headers[index] = strings.TrimSpace(headers[index])
|
||||
}
|
||||
items := make([]map[string]any, 0, len(rows)-1)
|
||||
for _, row := range rows[1:] {
|
||||
item := map[string]any{}
|
||||
for column, value := range row {
|
||||
if column >= len(headers) {
|
||||
continue
|
||||
}
|
||||
key := reverse[headers[column]]
|
||||
if key != "" {
|
||||
item[key] = value
|
||||
}
|
||||
}
|
||||
items = append(items, item)
|
||||
}
|
||||
return s.uc.ImportExportRows(ctx, template, items)
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type MediaService struct {
|
||||
uc *biz.MediaUsecase
|
||||
settings biz.RuntimeSettings
|
||||
}
|
||||
|
||||
func NewMediaService(uc *biz.MediaUsecase, settings biz.RuntimeSettings) *MediaService {
|
||||
return &MediaService{uc: uc, settings: settings}
|
||||
}
|
||||
func (s *MediaService) MediaConfig() biz.MediaSettings {
|
||||
return s.settings.MediaSettings()
|
||||
}
|
||||
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) *dto.MediaCategoryResponse {
|
||||
var children []*dto.MediaCategoryResponse
|
||||
if v.Children != nil {
|
||||
children = make([]*dto.MediaCategoryResponse, 0, len(v.Children))
|
||||
for _, x := range v.Children {
|
||||
children = append(children, categoryDTO(x))
|
||||
}
|
||||
}
|
||||
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) (*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) (*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) ([]*dto.MediaResponse, int64, error) {
|
||||
items, total, err := s.uc.ListMedia(ctx, filter)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]*dto.MediaResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, mediaDTO(v))
|
||||
}
|
||||
return out, total, nil
|
||||
}
|
||||
func (s *MediaService) MediaListRequest(ctx context.Context, request *dto.MediaListRequest) ([]*dto.MediaResponse, int64, error) {
|
||||
return s.MediaList(ctx, biz.MediaFilter{
|
||||
Page: request.Page, PageSize: request.PageSize, Keyword: request.Keyword,
|
||||
CategoryID: request.ClassID, Tag: request.Tag, UserID: request.UserID,
|
||||
StartCreatedAt: request.StartCreatedAt, EndCreatedAt: request.EndCreatedAt,
|
||||
OrderKey: request.OrderKey, Desc: request.Desc,
|
||||
})
|
||||
}
|
||||
func (s *MediaService) Delete(ctx context.Context, id uint) error { return s.uc.Delete(ctx, id) }
|
||||
func (s *MediaService) Rename(ctx context.Context, id uint, name string) error {
|
||||
return s.uc.UpdateMediaName(ctx, id, name)
|
||||
}
|
||||
func (s *MediaService) ImportURLs(ctx context.Context, items []*biz.MediaFile) error {
|
||||
return s.uc.CreateMediaBatch(ctx, items)
|
||||
}
|
||||
func (s *MediaService) ImportURLRequests(ctx context.Context, values []dto.ImportMediaRequest) error {
|
||||
items := make([]*biz.MediaFile, 0, len(values))
|
||||
for _, value := range values {
|
||||
items = append(items, &biz.MediaFile{Name: value.Name, CategoryID: value.ClassID, URL: value.URL, Tag: value.Tag, Key: value.Key, Size: value.Size, Mime: value.Mime, MD5: value.MD5, UserID: value.UserID})
|
||||
}
|
||||
return s.ImportURLs(ctx, items)
|
||||
}
|
||||
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([]*dto.StorageObjectResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, &dto.StorageObjectResponse{Key: v.Path, Size: v.Size, LastModified: v.LastModified, ContentType: v.ContentType})
|
||||
}
|
||||
return out, next, more, nil
|
||||
}
|
||||
func (s *MediaService) Categories(ctx context.Context) ([]*dto.MediaCategoryResponse, error) {
|
||||
items, err := s.uc.ListCategories(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make([]*dto.MediaCategoryResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, categoryDTO(v))
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
func (s *MediaService) SaveCategory(ctx context.Context, v *biz.AttachmentCategory) error {
|
||||
return s.uc.SaveCategory(ctx, v)
|
||||
}
|
||||
func (s *MediaService) SaveCategoryRequest(ctx context.Context, value *dto.CategoryRequest) error {
|
||||
return s.SaveCategory(ctx, &biz.AttachmentCategory{ID: value.ID, Name: value.Name, ParentID: value.PID})
|
||||
}
|
||||
func (s *MediaService) DeleteCategory(ctx context.Context, id uint) error {
|
||||
return s.uc.DeleteCategory(ctx, id)
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
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) (*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 {
|
||||
// The compatible response leaves UploadedChunks nil on an instant-upload hit, producing
|
||||
// JSON null while still returning uploadId: 0.
|
||||
return &dto.InitUploadResponse{Instant: true, Media: mediaDTO(media)}, 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) (*dto.MediaResponse, error) {
|
||||
v, err := s.uc.CompleteUpload(ctx, userID, uploadID, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return mediaDTO(v), nil
|
||||
}
|
||||
func (s *MediaService) CancelUpload(ctx context.Context, userID, uploadID uint) error {
|
||||
return s.uc.CancelUpload(ctx, userID, uploadID)
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type MenuService struct{ uc *biz.MenuUsecase }
|
||||
|
||||
func NewMenuService(uc *biz.MenuUsecase) *MenuService { return &MenuService{uc: uc} }
|
||||
|
||||
func (s *MenuService) List(ctx context.Context) ([]*dto.MenuResponse, error) {
|
||||
items, err := s.uc.List(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return menuResponses(items), nil
|
||||
}
|
||||
|
||||
func (s *MenuService) Tree(ctx context.Context) ([]*dto.MenuResponse, error) {
|
||||
items, err := s.uc.Tree(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return menuResponses(items), nil
|
||||
}
|
||||
|
||||
func (s *MenuService) Create(ctx context.Context, req *dto.MenuRequest) error {
|
||||
return s.uc.Create(ctx, menuDomain(req))
|
||||
}
|
||||
func (s *MenuService) Update(ctx context.Context, req *dto.MenuRequest) error {
|
||||
return s.uc.Update(ctx, menuDomain(req))
|
||||
}
|
||||
func (s *MenuService) Delete(ctx context.Context, id uint) error { return s.uc.Delete(ctx, id) }
|
||||
|
||||
func (s *MenuService) Find(ctx context.Context, id uint) (*dto.MenuResponse, error) {
|
||||
item, err := s.uc.Find(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return menuResponse(item), nil
|
||||
}
|
||||
|
||||
func (s *MenuService) SetAuthorityMenus(ctx context.Context, req *dto.SetAuthorityMenusRequest) error {
|
||||
ids := make([]uint, 0, len(req.Menus))
|
||||
for _, menu := range req.Menus {
|
||||
ids = append(ids, menu.ID)
|
||||
}
|
||||
return s.uc.SetAuthorityMenus(ctx, req.AuthorityID, ids)
|
||||
}
|
||||
|
||||
func (s *MenuService) AuthorityMenus(ctx context.Context, authorityID uint) ([]*dto.AuthorityMenuResponse, error) {
|
||||
items, err := s.uc.AuthorityMenus(ctx, authorityID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var out []*dto.AuthorityMenuResponse
|
||||
for _, item := range items {
|
||||
item.MenuID = item.ID
|
||||
out = append(out, &dto.AuthorityMenuResponse{DynamicMenuResponse: dynamicMenuResponse(item), AuthorityID: authorityID})
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (s *MenuService) RoleIDs(ctx context.Context, menuID uint) ([]uint, error) {
|
||||
return s.uc.RoleIDs(ctx, menuID)
|
||||
}
|
||||
func (s *MenuService) DefaultRouterRoleIDs(ctx context.Context, menuID uint) ([]uint, error) {
|
||||
return s.uc.DefaultRouterRoleIDs(ctx, menuID)
|
||||
}
|
||||
func (s *MenuService) SetRoles(ctx context.Context, req *dto.SetMenuRolesRequest) error {
|
||||
return s.uc.SetRoles(ctx, req.MenuID, req.AuthorityIDs)
|
||||
}
|
||||
|
||||
func menuDomain(v *dto.MenuRequest) *biz.Menu {
|
||||
menu := &biz.Menu{CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, ID: v.ID, ParentID: v.ParentID, Path: v.Path, Name: v.Name, Hidden: v.Hidden, Component: v.Component, Sort: v.Sort, ActiveName: v.Meta.ActiveName, KeepAlive: v.Meta.KeepAlive, DefaultMenu: v.Meta.DefaultMenu, Title: v.Meta.Title, Icon: v.Meta.Icon, CloseTab: v.Meta.CloseTab, TransitionType: v.Meta.TransitionType}
|
||||
menu.Buttons = make([]*biz.MenuButton, 0, len(v.MenuButtons))
|
||||
for _, button := range v.MenuButtons {
|
||||
menu.Buttons = append(menu.Buttons, &biz.MenuButton{CreatedAt: button.CreatedAt, UpdatedAt: button.UpdatedAt, ID: button.ID, Name: button.Name, Description: button.Description, MenuID: v.ID})
|
||||
}
|
||||
menu.Parameters = make([]*biz.MenuParameter, 0, len(v.Parameters))
|
||||
for _, parameter := range v.Parameters {
|
||||
menu.Parameters = append(menu.Parameters, &biz.MenuParameter{CreatedAt: parameter.CreatedAt, UpdatedAt: parameter.UpdatedAt, ID: parameter.ID, MenuID: v.ID, Type: parameter.Type, Key: parameter.Key, Value: parameter.Value})
|
||||
}
|
||||
return menu
|
||||
}
|
||||
|
||||
func menuResponse(menu *biz.Menu) *dto.MenuResponse {
|
||||
var children []*dto.MenuResponse
|
||||
if menu.Children != nil {
|
||||
children = make([]*dto.MenuResponse, 0, len(menu.Children))
|
||||
for _, child := range menu.Children {
|
||||
children = append(children, menuResponse(child))
|
||||
}
|
||||
}
|
||||
var buttons []dto.MenuButtonResponse
|
||||
if menu.Buttons != nil {
|
||||
buttons = make([]dto.MenuButtonResponse, 0, len(menu.Buttons))
|
||||
for _, button := range menu.Buttons {
|
||||
buttons = append(buttons, dto.MenuButtonResponse{CreatedAt: button.CreatedAt, UpdatedAt: button.UpdatedAt, ID: button.ID, Name: button.Name, Description: button.Description, SysBaseMenuID: button.MenuID})
|
||||
}
|
||||
}
|
||||
var parameters []dto.MenuParameterResponse
|
||||
if menu.Parameters != nil {
|
||||
parameters = make([]dto.MenuParameterResponse, 0, len(menu.Parameters))
|
||||
for _, parameter := range menu.Parameters {
|
||||
parameters = append(parameters, dto.MenuParameterResponse{CreatedAt: parameter.CreatedAt, UpdatedAt: parameter.UpdatedAt, ID: parameter.ID, SysBaseMenuID: parameter.MenuID, Type: parameter.Type, Key: parameter.Key, Value: parameter.Value})
|
||||
}
|
||||
}
|
||||
return &dto.MenuResponse{CreatedAt: menu.CreatedAt, UpdatedAt: menu.UpdatedAt, ID: menu.ID, MenuID: menu.MenuID, ParentID: menu.ParentID, Path: menu.Path, Name: menu.Name, Hidden: menu.Hidden, Component: menu.Component, Sort: menu.Sort, Meta: dto.MenuMetaResponse{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, MenuButtons: buttons}
|
||||
}
|
||||
|
||||
func dynamicMenuResponse(menu *biz.Menu) *dto.DynamicMenuResponse {
|
||||
var children []*dto.DynamicMenuResponse
|
||||
if menu.Children != nil {
|
||||
children = make([]*dto.DynamicMenuResponse, 0, len(menu.Children))
|
||||
for _, child := range menu.Children {
|
||||
children = append(children, dynamicMenuResponse(child))
|
||||
}
|
||||
}
|
||||
var parameters []dto.MenuParameterResponse
|
||||
if menu.Parameters != nil {
|
||||
parameters = make([]dto.MenuParameterResponse, 0, len(menu.Parameters))
|
||||
for _, parameter := range menu.Parameters {
|
||||
parameters = append(parameters, dto.MenuParameterResponse{CreatedAt: parameter.CreatedAt, UpdatedAt: parameter.UpdatedAt, ID: parameter.ID, SysBaseMenuID: parameter.MenuID, Type: parameter.Type, Key: parameter.Key, Value: parameter.Value})
|
||||
}
|
||||
}
|
||||
var buttonAuthorities map[string]uint
|
||||
for _, button := range menu.Buttons {
|
||||
if button.AuthorityID == 0 {
|
||||
continue
|
||||
}
|
||||
if buttonAuthorities == nil {
|
||||
buttonAuthorities = make(map[string]uint)
|
||||
}
|
||||
buttonAuthorities[button.Name] = button.AuthorityID
|
||||
}
|
||||
return &dto.DynamicMenuResponse{CreatedAt: menu.CreatedAt, UpdatedAt: menu.UpdatedAt, ID: menu.ID, MenuID: menu.MenuID, ParentID: menu.ParentID, Path: menu.Path, Name: menu.Name, Hidden: menu.Hidden, Component: menu.Component, Sort: menu.Sort, Meta: dto.MenuMetaResponse{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, MenuButtons: nil, Buttons: buttonAuthorities}
|
||||
}
|
||||
|
||||
func menuResponses(items []*biz.Menu) []*dto.MenuResponse {
|
||||
if items == nil {
|
||||
return nil
|
||||
}
|
||||
out := make([]*dto.MenuResponse, 0, len(items))
|
||||
for _, item := range items {
|
||||
out = append(out, menuResponse(item))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func dynamicMenuResponses(items []*biz.Menu) []*dto.DynamicMenuResponse {
|
||||
out := make([]*dto.DynamicMenuResponse, 0, len(items))
|
||||
for _, item := range items {
|
||||
out = append(out, dynamicMenuResponse(item))
|
||||
}
|
||||
return out
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
func TestMenuDomainPreservesRelationIdentity(t *testing.T) {
|
||||
createdAt := time.Date(2025, time.March, 4, 5, 6, 7, 0, time.UTC)
|
||||
updatedAt := time.Date(2025, time.April, 5, 6, 7, 8, 0, time.UTC)
|
||||
menu := menuDomain(&dto.MenuRequest{
|
||||
CreatedAt: createdAt,
|
||||
UpdatedAt: updatedAt,
|
||||
ID: 10,
|
||||
MenuButtons: []dto.MenuButtonRequest{{
|
||||
CreatedAt: createdAt, UpdatedAt: updatedAt, ID: 31, Name: "edit", Description: "编辑",
|
||||
}},
|
||||
Parameters: []dto.MenuParameterRequest{{
|
||||
CreatedAt: createdAt, UpdatedAt: updatedAt, ID: 21, Type: "query", Key: "id", Value: "1",
|
||||
}},
|
||||
})
|
||||
if !menu.CreatedAt.Equal(createdAt) || !menu.UpdatedAt.Equal(updatedAt) {
|
||||
t.Fatalf("menu timestamps = (%v, %v), want (%v, %v)", menu.CreatedAt, menu.UpdatedAt, createdAt, updatedAt)
|
||||
}
|
||||
if len(menu.Buttons) != 1 || menu.Buttons[0].ID != 31 || menu.Buttons[0].MenuID != 10 || !menu.Buttons[0].CreatedAt.Equal(createdAt) || !menu.Buttons[0].UpdatedAt.Equal(updatedAt) {
|
||||
t.Fatalf("button conversion = %+v", menu.Buttons)
|
||||
}
|
||||
if len(menu.Parameters) != 1 || menu.Parameters[0].ID != 21 || menu.Parameters[0].MenuID != 10 || !menu.Parameters[0].CreatedAt.Equal(createdAt) || !menu.Parameters[0].UpdatedAt.Equal(updatedAt) {
|
||||
t.Fatalf("parameter conversion = %+v", menu.Parameters)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMenuResponseEmptyCollectionContracts(t *testing.T) {
|
||||
if got := menuResponses(nil); got != nil {
|
||||
t.Fatalf("base menu top-level nil = %#v, want nil", got)
|
||||
}
|
||||
if got := dynamicMenuResponses(nil); got == nil || len(got) != 0 {
|
||||
t.Fatalf("dynamic menu top-level empty = %#v, want non-nil empty slice", got)
|
||||
}
|
||||
|
||||
base := menuResponse(&biz.Menu{Children: nil, Buttons: []*biz.MenuButton{}, Parameters: []*biz.MenuParameter{}})
|
||||
if base.Children != nil {
|
||||
t.Fatalf("leaf children = %#v, want nil", base.Children)
|
||||
}
|
||||
if base.MenuButtons == nil || base.Parameters == nil {
|
||||
t.Fatalf("preloaded empty relations = (%#v, %#v), want empty slices", base.MenuButtons, base.Parameters)
|
||||
}
|
||||
encoded, err := json.Marshal(base)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var payload map[string]any
|
||||
if err := json.Unmarshal(encoded, &payload); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if value, ok := payload["authoritys"]; !ok || value != nil {
|
||||
t.Fatalf("authoritys JSON = %#v (present=%v), want explicit null", value, ok)
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type ParameterService struct{ uc *biz.ParameterUsecase }
|
||||
|
||||
func NewParameterService(uc *biz.ParameterUsecase) *ParameterService {
|
||||
return &ParameterService{uc: uc}
|
||||
}
|
||||
|
||||
func parameterDomain(value *dto.SystemParameterRequest) *biz.SystemParameter {
|
||||
return &biz.SystemParameter{ID: value.ID, CreatedAt: value.CreatedAt, UpdatedAt: value.UpdatedAt, Name: value.Name, Key: value.Key, Value: value.Value, Desc: value.Description}
|
||||
}
|
||||
func (s *ParameterService) CreateParameterRequest(ctx context.Context, req *dto.SystemParameterRequest) error {
|
||||
return s.CreateParameter(ctx, parameterDomain(req))
|
||||
}
|
||||
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) ([]*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) *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) ([]*dto.SystemParameterResponse, int64, error) {
|
||||
items, total, err := s.uc.ListParameters(ctx, page, size, q)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]*dto.SystemParameterResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, parameterDTO(v))
|
||||
}
|
||||
return out, total, nil
|
||||
}
|
||||
func (s *ParameterService) ParameterByID(ctx context.Context, id string) (*dto.SystemParameterResponse, error) {
|
||||
v, err := s.uc.FindParameterByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return parameterDTO(v), nil
|
||||
}
|
||||
func (s *ParameterService) ParameterByKey(ctx context.Context, key string) (*dto.SystemParameterResponse, error) {
|
||||
v, err := s.uc.FindParameterByKey(ctx, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return parameterDTO(v), nil
|
||||
}
|
||||
func (s *ParameterService) CreateParameter(ctx context.Context, v *biz.SystemParameter) error {
|
||||
return s.uc.CreateParameter(ctx, v)
|
||||
}
|
||||
func (s *ParameterService) UpdateParameter(ctx context.Context, v *biz.SystemParameter) error {
|
||||
return s.uc.UpdateParameter(ctx, v)
|
||||
}
|
||||
func (s *ParameterService) DeleteParameters(ctx context.Context, ids []string) error {
|
||||
return s.uc.DeleteParameters(ctx, ids)
|
||||
}
|
||||
@@ -1,169 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type PaymentService struct{ uc *biz.PaymentUsecase }
|
||||
|
||||
func NewPaymentService(uc *biz.PaymentUsecase) *PaymentService { return &PaymentService{uc: uc} }
|
||||
func (s *PaymentService) Configs(ctx context.Context) ([]*dto.PaymentConfigResponse, error) {
|
||||
configs, err := s.uc.Configs(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := make([]*dto.PaymentConfigResponse, 0, len(configs))
|
||||
for _, config := range configs {
|
||||
if config == nil {
|
||||
continue
|
||||
}
|
||||
result = append(result, &dto.PaymentConfigResponse{Provider: config.Provider, Enabled: config.Enabled, Config: config.Values})
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
func (s *PaymentService) SaveConfig(ctx context.Context, req *dto.PaymentConfigRequest) error {
|
||||
if req == nil {
|
||||
return errors.New("支付配置请求为空")
|
||||
}
|
||||
return s.uc.SaveConfig(ctx, &biz.PaymentConfig{Provider: req.Provider, Enabled: req.Enabled, Values: req.Config})
|
||||
}
|
||||
func (s *PaymentService) Order(ctx context.Context, provider, tradeNo string) (*dto.PaymentOrderResponse, error) {
|
||||
order, err := s.uc.Order(ctx, provider, tradeNo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &dto.PaymentOrderResponse{
|
||||
ID: order.ID,
|
||||
Provider: order.Provider, TradeNo: order.TradeNo, ProviderTradeNo: order.ProviderTradeNo,
|
||||
BusinessType: order.BusinessType, BusinessID: order.BusinessID, Subject: order.Subject,
|
||||
PaymentMode: order.PaymentMode, OriginalAmount: order.OriginalAmount,
|
||||
Amount: order.Amount, PaidAmount: order.PaidAmount, PayerPaidAmount: order.PayerPaidAmount,
|
||||
CashPaidAmount: order.CashPaidAmount, PointPaidAmount: order.PointPaidAmount,
|
||||
DiscountAmount: order.DiscountAmount, ProviderDiscountAmount: order.ProviderDiscountAmount,
|
||||
MerchantDiscountAmount: order.MerchantDiscountAmount, SettlementAmount: order.SettlementAmount,
|
||||
Currency: order.Currency, PayerCurrency: order.PayerCurrency, AmountBreakdownKnown: order.AmountBreakdownKnown,
|
||||
PaymentStatus: order.PaymentStatus, ProviderStatus: order.ProviderStatus, FulfillmentStatus: order.FulfillmentStatus,
|
||||
RefundStatus: order.RefundStatus, RefundedAmount: order.RefundedAmount, RefundRequestedAmount: order.RefundRequestedAmount, RefundNo: order.RefundNo, LastError: order.LastError,
|
||||
CreatedAt: order.CreatedAt, UpdatedAt: order.UpdatedAt, PaidAt: order.PaidAt,
|
||||
FulfilledAt: order.FulfilledAt, RefundedAt: order.RefundedAt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *PaymentService) Orders(ctx context.Context, req *dto.PaymentOrderListRequest) ([]*dto.PaymentOrderResponse, int64, int, int, error) {
|
||||
if req == nil {
|
||||
return nil, 0, 1, 10, errors.New("支付订单列表请求为空")
|
||||
}
|
||||
page, pageSize := req.Page, req.PageSize
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
if pageSize <= 0 {
|
||||
pageSize = 10
|
||||
}
|
||||
items, total, err := s.uc.Orders(ctx, page, pageSize, biz.PaymentOrderFilter{
|
||||
Provider: req.Provider, TradeNo: req.TradeNo, BusinessType: req.BusinessType,
|
||||
BusinessID: req.BusinessID, PaymentStatus: req.PaymentStatus, RefundStatus: req.RefundStatus,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, 0, page, pageSize, err
|
||||
}
|
||||
result := make([]*dto.PaymentOrderResponse, 0, len(items))
|
||||
for _, item := range items {
|
||||
converted, convertErr := paymentOrderResponse(item)
|
||||
if convertErr != nil {
|
||||
return nil, 0, page, pageSize, convertErr
|
||||
}
|
||||
result = append(result, converted)
|
||||
}
|
||||
return result, total, page, pageSize, nil
|
||||
}
|
||||
|
||||
func paymentOrderResponse(order *biz.PaymentOrder) (*dto.PaymentOrderResponse, error) {
|
||||
if order == nil {
|
||||
return nil, errors.New("支付订单为空")
|
||||
}
|
||||
return &dto.PaymentOrderResponse{
|
||||
ID: order.ID, Provider: order.Provider, TradeNo: order.TradeNo, ProviderTradeNo: order.ProviderTradeNo,
|
||||
BusinessType: order.BusinessType, BusinessID: order.BusinessID, Subject: order.Subject,
|
||||
PaymentMode: order.PaymentMode, OriginalAmount: order.OriginalAmount, Amount: order.Amount, PaidAmount: order.PaidAmount,
|
||||
PayerPaidAmount: order.PayerPaidAmount, CashPaidAmount: order.CashPaidAmount, PointPaidAmount: order.PointPaidAmount,
|
||||
DiscountAmount: order.DiscountAmount, ProviderDiscountAmount: order.ProviderDiscountAmount,
|
||||
MerchantDiscountAmount: order.MerchantDiscountAmount, SettlementAmount: order.SettlementAmount,
|
||||
Currency: order.Currency, PayerCurrency: order.PayerCurrency, AmountBreakdownKnown: order.AmountBreakdownKnown,
|
||||
PaymentStatus: order.PaymentStatus, ProviderStatus: order.ProviderStatus, FulfillmentStatus: order.FulfillmentStatus,
|
||||
RefundStatus: order.RefundStatus, RefundedAmount: order.RefundedAmount, RefundRequestedAmount: order.RefundRequestedAmount,
|
||||
RefundNo: order.RefundNo, LastError: order.LastError, CreatedAt: order.CreatedAt, UpdatedAt: order.UpdatedAt,
|
||||
PaidAt: order.PaidAt, FulfilledAt: order.FulfilledAt, RefundedAt: order.RefundedAt,
|
||||
}, nil
|
||||
}
|
||||
func (s *PaymentService) Create(ctx context.Context, req *dto.PaymentRequest) (*dto.PaymentResultResponse, error) {
|
||||
if req == nil {
|
||||
return nil, errors.New("支付请求为空")
|
||||
}
|
||||
result, err := s.uc.Create(ctx, &biz.PaymentRequest{
|
||||
Provider: req.Provider, TradeNo: req.TradeNo, Subject: req.Subject,
|
||||
Amount: req.Amount, OriginalAmount: req.OriginalAmount, Currency: req.Currency,
|
||||
NotifyURL: req.NotifyURL, ReturnURL: req.ReturnURL, ClientIP: req.ClientIP,
|
||||
Extra: req.Extra, BusinessType: req.BusinessType, BusinessID: req.BusinessID,
|
||||
PaymentMode: req.PaymentMode,
|
||||
})
|
||||
return paymentResultResponse(result), err
|
||||
}
|
||||
func (s *PaymentService) Query(ctx context.Context, req *dto.PaymentQueryRequest) (*dto.PaymentResultResponse, error) {
|
||||
if req == nil {
|
||||
return nil, errors.New("支付查询请求为空")
|
||||
}
|
||||
result, err := s.uc.Query(ctx, req.Provider, req.TradeNo)
|
||||
return paymentResultResponse(result), err
|
||||
}
|
||||
func (s *PaymentService) Refund(ctx context.Context, req *dto.PaymentRefundRequest) (*dto.PaymentResultResponse, error) {
|
||||
if req == nil {
|
||||
return nil, errors.New("支付退款请求为空")
|
||||
}
|
||||
result, err := s.uc.Refund(ctx, req.Provider, req.TradeNo, req.Amount)
|
||||
return paymentResultResponse(result), err
|
||||
}
|
||||
func (s *PaymentService) Callback(ctx context.Context, req *dto.PaymentCallbackRequest) (dto.PaymentCallbackAck, error) {
|
||||
if req == nil {
|
||||
return paymentCallbackAckResponse(biz.DefaultPaymentCallbackAck("", false)), errors.New("支付回调请求为空")
|
||||
}
|
||||
result, err := s.uc.Callback(ctx, &biz.PaymentCallback{Provider: req.Provider, Headers: req.Headers, Body: req.Body, Query: req.Query})
|
||||
if err != nil {
|
||||
return paymentCallbackAckResponse(biz.CallbackFailure(err, biz.DefaultPaymentCallbackAck(req.Provider, false))), err
|
||||
}
|
||||
ack := biz.DefaultPaymentCallbackAck(req.Provider, true)
|
||||
if result != nil && result.SuccessAck.StatusCode != 0 {
|
||||
ack = result.SuccessAck
|
||||
}
|
||||
return paymentCallbackAckResponse(ack), nil
|
||||
}
|
||||
|
||||
func DefaultPaymentCallbackAck(provider string, success bool) dto.PaymentCallbackAck {
|
||||
return paymentCallbackAckResponse(biz.DefaultPaymentCallbackAck(provider, success))
|
||||
}
|
||||
|
||||
func paymentResultResponse(result *biz.PaymentResult) *dto.PaymentResultResponse {
|
||||
if result == nil {
|
||||
return nil
|
||||
}
|
||||
return &dto.PaymentResultResponse{
|
||||
Provider: result.Provider, Status: result.Status, TradeNo: result.TradeNo,
|
||||
ProviderTradeNo: result.ProviderTradeNo, Amount: result.Amount,
|
||||
PayerPaidAmount: result.PayerPaidAmount, CashPaidAmount: result.CashPaidAmount,
|
||||
PointPaidAmount: result.PointPaidAmount, DiscountAmount: result.DiscountAmount,
|
||||
ProviderDiscountAmount: result.ProviderDiscountAmount,
|
||||
MerchantDiscountAmount: result.MerchantDiscountAmount, SettlementAmount: result.SettlementAmount,
|
||||
Currency: result.Currency, PayerCurrency: result.PayerCurrency,
|
||||
AmountBreakdownKnown: result.AmountBreakdownKnown, Duplicate: result.Duplicate,
|
||||
Payload: result.Payload, OrderStatus: result.OrderStatus,
|
||||
FulfillmentStatus: result.FulfillmentStatus, RefundStatus: result.RefundStatus,
|
||||
}
|
||||
}
|
||||
|
||||
func paymentCallbackAckResponse(ack biz.PaymentCallbackAck) dto.PaymentCallbackAck {
|
||||
return dto.PaymentCallbackAck{StatusCode: ack.StatusCode, ContentType: ack.ContentType, Body: ack.Body}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
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 string) (bool, error) {
|
||||
return s.uc.CanRemoveButton(ctx, id)
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type PositionService struct{ uc *biz.PositionUsecase }
|
||||
|
||||
func NewPositionService(uc *biz.PositionUsecase) *PositionService {
|
||||
return &PositionService{uc: uc}
|
||||
}
|
||||
|
||||
func positionDomain(value *dto.PositionRequest) *biz.Position {
|
||||
return &biz.Position{ID: value.ID, Name: value.Name, Code: value.Code, Sort: value.Sort, Status: value.Status, Remark: value.Remark}
|
||||
}
|
||||
|
||||
func positionResponse(value *biz.Position) *dto.PositionResponse {
|
||||
return &dto.PositionResponse{ID: value.ID, CreatedAt: value.CreatedAt, UpdatedAt: value.UpdatedAt, DeletedAt: nil, Name: value.Name, Code: value.Code, Sort: value.Sort, Status: value.Status, Remark: value.Remark}
|
||||
}
|
||||
|
||||
func (s *PositionService) Positions(ctx context.Context, req *dto.PositionListRequest) ([]*dto.PositionResponse, int64, error) {
|
||||
items, total, err := s.uc.Positions(ctx, req.Page, req.PageSize, &biz.PositionListFilter{Name: req.Name, Code: req.Code, Status: req.Status})
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]*dto.PositionResponse, 0, len(items))
|
||||
for _, item := range items {
|
||||
out = append(out, positionResponse(item))
|
||||
}
|
||||
return out, total, nil
|
||||
}
|
||||
|
||||
func (s *PositionService) Create(ctx context.Context, req *dto.PositionRequest) error {
|
||||
return s.uc.CreatePosition(ctx, positionDomain(req))
|
||||
}
|
||||
|
||||
func (s *PositionService) Update(ctx context.Context, req *dto.PositionRequest) error {
|
||||
return s.uc.UpdatePosition(ctx, positionDomain(req))
|
||||
}
|
||||
|
||||
func (s *PositionService) Delete(ctx context.Context, id uint) error {
|
||||
return s.uc.DeletePosition(ctx, id)
|
||||
}
|
||||
|
||||
func (s *PositionService) Position(ctx context.Context, id uint) (*dto.PositionResponse, error) {
|
||||
value, err := s.uc.Position(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return positionResponse(value), nil
|
||||
}
|
||||
|
||||
func (s *PositionService) UserIDs(ctx context.Context, id uint) ([]uint, error) {
|
||||
return s.uc.PositionUserIDs(ctx, id)
|
||||
}
|
||||
|
||||
func (s *PositionService) SetUsers(ctx context.Context, req *dto.SetPositionUsersRequest) error {
|
||||
return s.uc.SetPositionUsers(ctx, req.PositionID, req.UserIDs)
|
||||
}
|
||||
|
||||
func (s *PositionService) SetUserPositions(ctx context.Context, req *dto.SetUserPositionsRequest) error {
|
||||
return s.uc.SetUserPositions(ctx, req.ID, req.PositionIDs)
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package service
|
||||
|
||||
import "strings"
|
||||
|
||||
// NormalizeRoutePath removes only a complete configured router prefix. Paths
|
||||
// such as /administrator must not be shortened when the prefix is /admin.
|
||||
func NormalizeRoutePath(path, routerPrefix string) string {
|
||||
prefix := strings.TrimSuffix(strings.TrimSpace(routerPrefix), "/")
|
||||
if prefix == "" || prefix == "/" {
|
||||
return path
|
||||
}
|
||||
if path == prefix {
|
||||
return "/"
|
||||
}
|
||||
if strings.HasPrefix(path, prefix+"/") {
|
||||
return strings.TrimPrefix(path, prefix)
|
||||
}
|
||||
return path
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package service
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestNormalizeRoutePath(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
path string
|
||||
prefix string
|
||||
want string
|
||||
}{
|
||||
{name: "empty prefix", path: "/api/login", prefix: "", want: "/api/login"},
|
||||
{name: "configured prefix", path: "/admin/api/login", prefix: "/admin", want: "/api/login"},
|
||||
{name: "trailing slash prefix", path: "/admin/api/login", prefix: "/admin/", want: "/api/login"},
|
||||
{name: "prefix root", path: "/admin", prefix: "/admin", want: "/"},
|
||||
{name: "prefix boundary", path: "/administrator/api/login", prefix: "/admin", want: "/administrator/api/login"},
|
||||
{name: "already normalized", path: "/api/login", prefix: "/admin", want: "/api/login"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := NormalizeRoutePath(tt.path, tt.prefix); got != tt.want {
|
||||
t.Fatalf("NormalizeRoutePath(%q, %q) = %q, want %q", tt.path, tt.prefix, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type PasswordPolicyError struct{ Err error }
|
||||
|
||||
func (e *PasswordPolicyError) Error() string { return e.Err.Error() }
|
||||
func (e *PasswordPolicyError) Unwrap() error { return e.Err }
|
||||
|
||||
func IsPasswordPolicyError(err error) bool {
|
||||
var policyErr *PasswordPolicyError
|
||||
return errors.As(err, &policyErr)
|
||||
}
|
||||
|
||||
func securityDTO(v *biz.SecurityConfig) *dto.SecurityConfigResponse {
|
||||
return &dto.SecurityConfigResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, DeletedAt: nil, 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) (*dto.SecurityConfigResponse, error) {
|
||||
value, err := s.uc.Security(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return securityDTO(value), nil
|
||||
}
|
||||
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) (*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,
|
||||
PwdMinLength: value.PwdMinLength, PwdRequireUpper: value.PwdRequireUpper,
|
||||
PwdRequireLower: value.PwdRequireLower, PwdRequireDigit: value.PwdRequireDigit,
|
||||
PwdRequireSpecial: value.PwdRequireSpecial, LimitEnable: value.LimitEnable,
|
||||
LimitWindow: value.LimitWindow, LimitCount: value.LimitCount, LockEnable: value.LockEnable,
|
||||
LockThreshold: value.LockThreshold, LockDuration: value.LockDuration,
|
||||
PwdExpireEnable: value.PwdExpireEnable, PwdExpireDays: value.PwdExpireDays,
|
||||
ForceNewUserChangePassword: value.ForceNewUserChangePassword,
|
||||
})
|
||||
}
|
||||
func (s *SecurityService) ValidatePassword(ctx context.Context, password string) error {
|
||||
cfg, err := s.CurrentSecurity(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.uc.ValidatePassword(cfg, password); err != nil {
|
||||
return &PasswordPolicyError{Err: err}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"kra/internal/biz"
|
||||
)
|
||||
|
||||
type SecurityService struct {
|
||||
uc *biz.SecurityUsecase
|
||||
}
|
||||
|
||||
func NewSecurityService(uc *biz.SecurityUsecase) *SecurityService {
|
||||
return &SecurityService{uc: uc}
|
||||
}
|
||||
|
||||
func (s *SecurityService) ActiveToken(ctx context.Context, username string) (string, error) {
|
||||
return s.uc.ActiveToken(ctx, username)
|
||||
}
|
||||
|
||||
func (s *SecurityService) LoginLocked(ctx context.Context, username string) (bool, error) {
|
||||
return s.uc.LoginLocked(ctx, username)
|
||||
}
|
||||
|
||||
func (s *SecurityService) IncrementLoginFailure(ctx context.Context, username string, expiration time.Duration) (int64, error) {
|
||||
return s.uc.IncrementLoginFailure(ctx, username, expiration)
|
||||
}
|
||||
|
||||
func (s *SecurityService) LockLogin(ctx context.Context, username string, expiration time.Duration) error {
|
||||
return s.uc.LockLogin(ctx, username, expiration)
|
||||
}
|
||||
|
||||
func (s *SecurityService) ClearLoginState(ctx context.Context, username string) {
|
||||
s.uc.ClearLoginState(ctx, username)
|
||||
}
|
||||
|
||||
func (s *SecurityService) EnsureLoginIPCounter(ctx context.Context, ip string, expiration time.Duration) (int, error) {
|
||||
return s.uc.EnsureLoginIPCounter(ctx, ip, expiration)
|
||||
}
|
||||
|
||||
func (s *SecurityService) IncrementLoginIP(ctx context.Context, ip string, expiration time.Duration) (int64, error) {
|
||||
return s.uc.IncrementLoginIP(ctx, ip, expiration)
|
||||
}
|
||||
|
||||
func (s *SecurityService) IncrementRateLimit(ctx context.Context, key string, expiration time.Duration) (int64, error) {
|
||||
return s.uc.IncrementRateLimit(ctx, key, expiration)
|
||||
}
|
||||
|
||||
func (s *SecurityService) SetCaptcha(ctx context.Context, id, value string, expiration time.Duration) error {
|
||||
return s.uc.SetCaptcha(ctx, id, value, expiration)
|
||||
}
|
||||
|
||||
func (s *SecurityService) GetCaptcha(ctx context.Context, id string) (string, bool, error) {
|
||||
return s.uc.GetCaptcha(ctx, id)
|
||||
}
|
||||
|
||||
func (s *SecurityService) DeleteCaptcha(ctx context.Context, id string) error {
|
||||
return s.uc.DeleteCaptcha(ctx, id)
|
||||
}
|
||||
|
||||
func (s *SecurityService) UseMultipoint() bool { return s.uc.UseMultipoint() }
|
||||
|
||||
func (s *SecurityService) CaptchaSettings() biz.CaptchaSettings {
|
||||
return s.uc.CaptchaRuntimeSettings()
|
||||
}
|
||||
|
||||
func (s *SecurityService) ActiveTokenMatches(ctx context.Context, username, token string) (bool, error) {
|
||||
return s.uc.ActiveTokenMatches(ctx, username, token)
|
||||
}
|
||||
|
||||
func (s *SecurityService) RotateActiveToken(ctx context.Context, username, oldToken, newToken string, expiration time.Duration) error {
|
||||
return s.uc.RotateActiveToken(ctx, username, oldToken, newToken, expiration)
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package service
|
||||
|
||||
import "github.com/google/wire"
|
||||
|
||||
// ProviderSet is service providers.
|
||||
var ProviderSet = wire.NewSet(NewAuthService, NewUserService, NewSystemConfigService, NewAuthorityService, NewPermissionService, NewAccessControlService, NewAPIService, NewMenuService, NewDepartmentService, NewPositionService, NewDictionaryService, NewParameterService, NewTokenService, NewSecurityService, NewVersionService, NewExportService, NewAuditService, NewAuditRecorder, NewLogViewerService, NewTaskService, NewMediaService, NewAnnouncementService, NewEmailService, NewPaymentService)
|
||||
@@ -1,20 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"kra/internal/biz"
|
||||
)
|
||||
|
||||
type SystemConfigService struct {
|
||||
uc *biz.SystemConfigUsecase
|
||||
settings biz.RuntimeSettings
|
||||
}
|
||||
|
||||
func NewSystemConfigService(uc *biz.SystemConfigUsecase, settings biz.RuntimeSettings) *SystemConfigService {
|
||||
return &SystemConfigService{uc: uc, settings: settings}
|
||||
}
|
||||
|
||||
func (s *SystemConfigService) IsInitialized(ctx context.Context) (bool, error) {
|
||||
return s.uc.IsInitialized(ctx)
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
func (s *SystemConfigService) PersistConfig(ctx context.Context) error {
|
||||
return s.uc.PersistConfig(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) SystemConfig() (json.RawMessage, error) {
|
||||
return s.uc.ConfigurationJSON()
|
||||
}
|
||||
|
||||
func (s *SystemConfigService) SaveSystemConfig(ctx context.Context, req *dto.SetSystemConfigRequest) error {
|
||||
return s.uc.SaveConfigurationJSON(ctx, req.Config)
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package service
|
||||
|
||||
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() (*dto.ServerInfoResponse, error) {
|
||||
physicalCores, err := cpu.Counts(false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cpuPercent, err := cpu.Percent(200*time.Millisecond, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
memory, err := mem.VirtualMemory()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
diskInfo := make([]dto.ServerDiskResponse, 0)
|
||||
for _, mountPoint := range s.DiskMountPoints() {
|
||||
usage, usageErr := disk.Usage(mountPoint)
|
||||
if usageErr != nil {
|
||||
return nil, usageErr
|
||||
}
|
||||
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 &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
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/routeinfo"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
func (s *SystemConfigService) Initialize(ctx context.Context, input *dto.DatabaseInitRequest, apis []*biz.API) error {
|
||||
driver, config := input.DBType, ""
|
||||
switch driver {
|
||||
case "mysql":
|
||||
config = "charset=utf8mb4&parseTime=True&loc=Local"
|
||||
case "pgsql":
|
||||
config = "sslmode=disable TimeZone=Asia/Shanghai"
|
||||
case "sqlite", "mssql":
|
||||
default:
|
||||
// The compatible initialization flow treats an omitted or unknown dbType as MySQL during
|
||||
// initialization rather than rejecting it as an unsupported driver.
|
||||
driver = "mysql"
|
||||
config = "charset=utf8mb4&parseTime=True&loc=Local"
|
||||
}
|
||||
return s.uc.Initialize(ctx, &biz.DatabaseConfig{Driver: driver, Host: input.Host, Port: input.Port, User: input.UserName, Password: input.Password, Name: input.DBName, Path: input.DBPath, Config: config, Template: input.Template, AdminPassword: input.AdminPassword, APIs: apis})
|
||||
}
|
||||
|
||||
func (s *SystemConfigService) InitializeRoutes(ctx context.Context, input *dto.DatabaseInitRequest, routes []dto.Route) error {
|
||||
apis := make([]*biz.API, 0, len(routes))
|
||||
for _, route := range routes {
|
||||
path := NormalizeRoutePath(route.Path, s.settings.RouterPrefix())
|
||||
group, description := routeinfo.Metadata(route.Method, path)
|
||||
apis = append(apis, &biz.API{Path: path, Method: route.Method, APIGroup: group, Description: description})
|
||||
}
|
||||
return s.Initialize(ctx, input, apis)
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type TaskService struct {
|
||||
uc *biz.TaskApplicationUsecase
|
||||
}
|
||||
|
||||
func NewTaskService(uc *biz.TaskApplicationUsecase) *TaskService {
|
||||
return &TaskService{uc: uc}
|
||||
}
|
||||
func taskDomain(v *dto.TaskRequest) *biz.TimedTask {
|
||||
return &biz.TimedTask{ID: v.ID, Name: v.Name, Description: v.Description, Spec: v.Spec, WithSeconds: v.WithSeconds, ExecutorType: v.ExecutorType, MethodName: v.MethodName, Params: v.Params, HTTPURL: v.HTTPURL, HTTPMethod: v.HTTPMethod, HTTPHeader: v.HTTPHeader, HTTPBody: v.HTTPBody, HTTPAllowPrivate: v.HTTPAllowPrivate, Enabled: v.Enabled}
|
||||
}
|
||||
func (s *TaskService) CreateRequest(ctx context.Context, req *dto.TaskRequest) (uint, error) {
|
||||
value := taskDomain(req)
|
||||
if err := s.Create(ctx, value); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return value.ID, nil
|
||||
}
|
||||
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) ([]*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 {
|
||||
return s.uc.Create(ctx, v)
|
||||
}
|
||||
func (s *TaskService) Update(ctx context.Context, v *biz.TimedTask) error {
|
||||
return s.uc.Update(ctx, v)
|
||||
}
|
||||
func (s *TaskService) Delete(ctx context.Context, id uint) error {
|
||||
return s.uc.Delete(ctx, id)
|
||||
}
|
||||
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) *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) ([]*dto.TaskResponse, int64, error) {
|
||||
items, total, next, err := s.uc.List(ctx, page, size, q)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]*dto.TaskResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
var ptr *time.Time
|
||||
if value, ok := next[v.ID]; ok {
|
||||
copy := value
|
||||
ptr = ©
|
||||
}
|
||||
out = append(out, taskDTO(v, ptr))
|
||||
}
|
||||
return out, total, nil
|
||||
}
|
||||
|
||||
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([]*dto.TaskLogResponse, 0, len(items))
|
||||
for _, v := range items {
|
||||
out = append(out, &dto.TaskLogResponse{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, 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
|
||||
}
|
||||
|
||||
func (s *TaskService) Trigger(ctx context.Context, id uint) error { return s.uc.Trigger(ctx, id) }
|
||||
func (s *TaskService) Reload(ctx context.Context) error { return s.uc.Reload(ctx) }
|
||||
func (s *TaskService) Subscribe(userID uint) chan []byte { return s.uc.Subscribe(userID) }
|
||||
func (s *TaskService) Unsubscribe(userID uint, events chan []byte) { s.uc.Unsubscribe(userID, events) }
|
||||
|
||||
func (s *TaskService) RegisteredMethods() []*dto.TaskMethodResponse {
|
||||
methods := biz.RegisteredTaskMethods()
|
||||
out := make([]*dto.TaskMethodResponse, 0, len(methods))
|
||||
for _, method := range methods {
|
||||
out = append(out, &dto.TaskMethodResponse{Name: method.Name, Description: method.Description})
|
||||
}
|
||||
return out
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type userInput struct {
|
||||
ID uint
|
||||
Username, Password, NickName, HeaderImg, Phone, Email string
|
||||
AuthorityID uint
|
||||
Enable int
|
||||
AuthorityIDs []uint
|
||||
}
|
||||
|
||||
type UserService struct {
|
||||
uc *biz.UserUsecase
|
||||
settings *SecurityService
|
||||
}
|
||||
|
||||
func NewUserService(uc *biz.UserUsecase, settings *SecurityService) *UserService {
|
||||
return &UserService{uc: uc, settings: settings}
|
||||
}
|
||||
|
||||
func userRequestInput(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) ([]*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) (*dto.UserResponse, error) {
|
||||
return s.createUser(ctx, userRequestInput(value))
|
||||
}
|
||||
func (s *UserService) UpdateUserRequest(ctx context.Context, value *dto.UserRequest) error {
|
||||
return s.updateUser(ctx, userRequestInput(value))
|
||||
}
|
||||
func (s *UserService) UpdateSelfUserRequest(ctx context.Context, id uint, value *dto.SelfUserRequest) error {
|
||||
return s.updateSelfUser(ctx, userInput{ID: id, NickName: value.NickName, HeaderImg: value.HeaderImg, Phone: value.Phone, Email: value.Email, Enable: value.Enable})
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
return convertUser(value), nil
|
||||
}
|
||||
|
||||
func (s *UserService) UserByUUID(ctx context.Context, uuid string) (*dto.UserResponse, error) {
|
||||
value, err := s.uc.UserByUUID(ctx, uuid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return convertUser(value), nil
|
||||
}
|
||||
|
||||
func (s *UserService) Menus(ctx context.Context, authorityID uint) ([]*dto.DynamicMenuResponse, error) {
|
||||
menus, err := s.uc.Menus(ctx, authorityID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dynamicMenuResponses(menus), nil
|
||||
}
|
||||
|
||||
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([]*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) ([]*dto.AuthorityResponse, error) {
|
||||
values, err := s.uc.Authorities(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
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) (*dto.UserResponse, error) {
|
||||
if err := s.settings.ValidatePassword(ctx, input.Password); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
security, _ := s.settings.CurrentSecurity(ctx)
|
||||
mustChange := security != nil && security.ForceNewUserChangePassword
|
||||
user, err := s.uc.CreateUser(ctx, &biz.User{Username: input.Username, Password: input.Password, NickName: input.NickName, HeaderImg: input.HeaderImg, AuthorityID: input.AuthorityID, Phone: input.Phone, Email: input.Email, Enable: input.Enable, MustChangePassword: mustChange}, input.AuthorityIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return convertUser(user), nil
|
||||
}
|
||||
func (s *UserService) updateUser(ctx context.Context, input userInput) error {
|
||||
// The compatible ChangeUserInfo payload uses authorityIds for role assignment; the
|
||||
// standalone authorityId field is not applied by setUserInfo.
|
||||
return s.uc.UpdateUser(ctx, &biz.User{ID: input.ID, NickName: input.NickName, HeaderImg: input.HeaderImg, Phone: input.Phone, Email: input.Email, Enable: input.Enable}, input.AuthorityIDs)
|
||||
}
|
||||
func (s *UserService) updateSelfUser(ctx context.Context, input userInput) error {
|
||||
return s.uc.UpdateSelfUser(ctx, &biz.User{ID: input.ID, NickName: input.NickName, HeaderImg: input.HeaderImg, Phone: input.Phone, Email: input.Email, Enable: input.Enable})
|
||||
}
|
||||
func (s *UserService) DeleteUser(ctx context.Context, id uint) error {
|
||||
return s.uc.DeleteUser(ctx, id)
|
||||
}
|
||||
func (s *UserService) ResetPassword(ctx context.Context, id uint, password string) error {
|
||||
if err := s.settings.ValidatePassword(ctx, password); err != nil {
|
||||
return err
|
||||
}
|
||||
return s.uc.ResetPassword(ctx, id, password)
|
||||
}
|
||||
func (s *UserService) ChangePassword(ctx context.Context, id uint, oldPassword, newPassword string) error {
|
||||
if err := s.settings.ValidatePassword(ctx, newPassword); err != nil {
|
||||
return err
|
||||
}
|
||||
return s.uc.ChangePassword(ctx, id, oldPassword, newPassword)
|
||||
}
|
||||
|
||||
func (s *UserService) SetUserAuthorities(ctx context.Context, id uint, authorityIDs []uint) error {
|
||||
return s.uc.SetUserAuthorities(ctx, id, authorityIDs)
|
||||
}
|
||||
func (s *UserService) SetUserSetting(ctx context.Context, id uint, setting map[string]any) error {
|
||||
return s.uc.SetUserSetting(ctx, id, setting)
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
func convertAuthority(value biz.Authority) *dto.AuthorityResponse {
|
||||
var menus []*dto.MenuResponse
|
||||
if value.Menus != nil {
|
||||
menus = menuResponses(value.Menus)
|
||||
}
|
||||
return &dto.AuthorityResponse{CreatedAt: value.CreatedAt, UpdatedAt: value.UpdatedAt, DeletedAt: value.DeletedAt, AuthorityID: value.AuthorityID, AuthorityName: value.AuthorityName, ParentID: value.ParentID, Children: nil, Menus: menus, DataScope: value.DataScope, DefaultRouter: value.DefaultRouter}
|
||||
}
|
||||
func convertUser(user *biz.User) *dto.UserResponse {
|
||||
var authorities []*dto.AuthorityResponse
|
||||
if user.Authorities != nil {
|
||||
authorities = make([]*dto.AuthorityResponse, 0, len(user.Authorities))
|
||||
for _, value := range user.Authorities {
|
||||
authorities = append(authorities, convertAuthority(value))
|
||||
}
|
||||
}
|
||||
var departments []*dto.DepartmentResponse
|
||||
if user.Departments != nil {
|
||||
departments = make([]*dto.DepartmentResponse, 0, len(user.Departments))
|
||||
for i := range user.Departments {
|
||||
departments = append(departments, departmentResponse(&user.Departments[i]))
|
||||
}
|
||||
}
|
||||
var positions []*dto.PositionResponse
|
||||
if user.Positions != nil {
|
||||
positions = make([]*dto.PositionResponse, 0, len(user.Positions))
|
||||
for i := range user.Positions {
|
||||
positions = append(positions, positionResponse(&user.Positions[i]))
|
||||
}
|
||||
}
|
||||
// The primary department is represented by a zero-value object when it is
|
||||
// absent, preserving the response shape expected by the administration UI.
|
||||
var department any = dto.DepartmentResponse{}
|
||||
if user.Department != nil {
|
||||
department = departmentResponse(user.Department)
|
||||
}
|
||||
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, PasswordUpdatedAt: user.PasswordUpdatedAt}
|
||||
}
|
||||
@@ -1,268 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type VersionService struct{ uc *biz.VersionUsecase }
|
||||
|
||||
func NewVersionService(uc *biz.VersionUsecase) *VersionService { return &VersionService{uc: uc} }
|
||||
|
||||
type versionExportInfo struct {
|
||||
Name string `json:"name"`
|
||||
Code string `json:"code"`
|
||||
Description string `json:"description"`
|
||||
ExportTime string `json:"exportTime"`
|
||||
}
|
||||
|
||||
type versionExportMenuParameter struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
SysBaseMenuID uint `json:"SysBaseMenuID"`
|
||||
Type string `json:"type"`
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type versionExportMenuButton struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"desc"`
|
||||
SysBaseMenuID uint `json:"sysBaseMenuID"`
|
||||
}
|
||||
|
||||
type versionExportMenu struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
ParentID uint `json:"parentId"`
|
||||
Path string `json:"path"`
|
||||
Name string `json:"name"`
|
||||
Hidden bool `json:"hidden"`
|
||||
Component string `json:"component"`
|
||||
Sort int `json:"sort"`
|
||||
Meta dto.VersionMenuMetaRequest `json:"meta"`
|
||||
Authorities []any `json:"authoritys"`
|
||||
Children []*versionExportMenu `json:"children"`
|
||||
Parameters []versionExportMenuParameter `json:"parameters"`
|
||||
MenuButtons []versionExportMenuButton `json:"menuBtn"`
|
||||
}
|
||||
|
||||
type versionExportAPI struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
Path string `json:"path"`
|
||||
Description string `json:"description"`
|
||||
APIGroup string `json:"apiGroup"`
|
||||
Method string `json:"method"`
|
||||
}
|
||||
|
||||
type versionExportDictionaryDetail struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
Label string `json:"label"`
|
||||
Value string `json:"value"`
|
||||
Extend string `json:"extend"`
|
||||
Status *bool `json:"status"`
|
||||
Sort int `json:"sort"`
|
||||
DictionaryID int `json:"sysDictionaryID"`
|
||||
ParentID *uint `json:"parentID"`
|
||||
Children []versionExportDictionaryDetail `json:"children"`
|
||||
Level int `json:"level"`
|
||||
Path string `json:"path"`
|
||||
Disabled bool `json:"disabled"`
|
||||
}
|
||||
|
||||
type versionExportDictionary struct {
|
||||
ID uint `json:"ID"`
|
||||
CreatedAt time.Time `json:"CreatedAt"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Status *bool `json:"status"`
|
||||
Desc string `json:"desc"`
|
||||
ParentID *uint `json:"parentID"`
|
||||
Children []versionExportDictionary `json:"children"`
|
||||
Details []versionExportDictionaryDetail `json:"sysDictionaryDetails"`
|
||||
}
|
||||
|
||||
type versionExportDocument struct {
|
||||
Version versionExportInfo `json:"version"`
|
||||
Menus []*versionExportMenu `json:"menus"`
|
||||
APIs []versionExportAPI `json:"apis"`
|
||||
Dictionaries []versionExportDictionary `json:"dictionaries"`
|
||||
}
|
||||
|
||||
func exportMenu(value *biz.Menu) *versionExportMenu {
|
||||
menu := &versionExportMenu{
|
||||
Path: value.Path, Name: value.Name, Hidden: value.Hidden, Component: value.Component, Sort: value.Sort,
|
||||
Meta: dto.VersionMenuMetaRequest{ActiveName: value.ActiveName, KeepAlive: value.KeepAlive, DefaultMenu: value.DefaultMenu, Title: value.Title, Icon: value.Icon, CloseTab: value.CloseTab, TransitionType: value.TransitionType},
|
||||
}
|
||||
if len(value.Parameters) > 0 {
|
||||
menu.Parameters = make([]versionExportMenuParameter, 0, len(value.Parameters))
|
||||
for _, parameter := range value.Parameters {
|
||||
menu.Parameters = append(menu.Parameters, versionExportMenuParameter{Type: parameter.Type, Key: parameter.Key, Value: parameter.Value})
|
||||
}
|
||||
}
|
||||
if len(value.Buttons) > 0 {
|
||||
menu.MenuButtons = make([]versionExportMenuButton, 0, len(value.Buttons))
|
||||
for _, button := range value.Buttons {
|
||||
menu.MenuButtons = append(menu.MenuButtons, versionExportMenuButton{Name: button.Name, Description: button.Description})
|
||||
}
|
||||
}
|
||||
if len(value.Children) > 0 {
|
||||
menu.Children = make([]*versionExportMenu, 0, len(value.Children))
|
||||
for _, child := range value.Children {
|
||||
menu.Children = append(menu.Children, exportMenu(child))
|
||||
}
|
||||
}
|
||||
return menu
|
||||
}
|
||||
|
||||
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 versionValue(value *string) string {
|
||||
if value == nil {
|
||||
return ""
|
||||
}
|
||||
return *value
|
||||
}
|
||||
|
||||
func versionPointer(value string) *string { return &value }
|
||||
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([]*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) (*dto.VersionResponse, error) {
|
||||
v, err := s.uc.FindVersion(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return versionDTO(v), nil
|
||||
}
|
||||
func (s *VersionService) VersionData(ctx context.Context, id uint) (string, string, error) {
|
||||
v, err := s.uc.FindVersion(ctx, id)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
if v.Data != nil && *v.Data != "" {
|
||||
return *v.Data, versionValue(v.Code), nil
|
||||
}
|
||||
payload := versionExportDocument{
|
||||
Version: versionExportInfo{Name: versionValue(v.Name), Code: versionValue(v.Code), Description: versionValue(v.Description), ExportTime: v.CreatedAt.Format("2006-01-02 15:04:05")},
|
||||
Menus: []*versionExportMenu{},
|
||||
APIs: []versionExportAPI{},
|
||||
}
|
||||
raw, marshalErr := json.MarshalIndent(payload, "", " ")
|
||||
if marshalErr != nil {
|
||||
return "", "", marshalErr
|
||||
}
|
||||
return string(raw), versionValue(v.Code), nil
|
||||
}
|
||||
func (s *VersionService) DeleteVersions(ctx context.Context, ids []uint) error {
|
||||
return s.uc.DeleteVersions(ctx, ids)
|
||||
}
|
||||
|
||||
func (s *VersionService) Export(ctx context.Context, name, code, description string, menuIDs, apiIDs, dictIDs []uint) error {
|
||||
bundle, err := s.uc.BuildVersionBundle(ctx, menuIDs, apiIDs, dictIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bundle.Name = name
|
||||
bundle.Code = code
|
||||
bundle.Description = description
|
||||
bundle.ExportTime = time.Now().Format("2006-01-02 15:04:05")
|
||||
var menus []*versionExportMenu
|
||||
if bundle.Menus != nil {
|
||||
menus = make([]*versionExportMenu, 0, len(bundle.Menus))
|
||||
for _, value := range bundle.Menus {
|
||||
menus = append(menus, exportMenu(value))
|
||||
}
|
||||
}
|
||||
apis := make([]versionExportAPI, 0, len(bundle.APIs))
|
||||
for _, value := range bundle.APIs {
|
||||
apis = append(apis, versionExportAPI{Path: value.Path, Description: value.Description, APIGroup: value.APIGroup, Method: value.Method})
|
||||
}
|
||||
dictionaries := make([]versionExportDictionary, 0, len(bundle.Dictionaries))
|
||||
for _, value := range bundle.Dictionaries {
|
||||
details := make([]versionExportDictionaryDetail, 0, len(value.Details))
|
||||
for _, detail := range value.Details {
|
||||
details = append(details, versionExportDictionaryDetail{Label: detail.Label, Value: detail.Value, Extend: detail.Extend, Status: detail.Status, Sort: detail.Sort})
|
||||
}
|
||||
dictionaries = append(dictionaries, versionExportDictionary{Name: value.Name, Type: value.Type, Status: value.Status, Desc: value.Desc, Details: details})
|
||||
}
|
||||
payload := versionExportDocument{Version: versionExportInfo{Name: name, Code: code, Description: description, ExportTime: bundle.ExportTime}, Menus: menus, APIs: apis, Dictionaries: dictionaries}
|
||||
raw, err := json.MarshalIndent(payload, "", " ")
|
||||
if err != nil {
|
||||
return &biz.VersionStageError{Stage: biz.VersionStageJSON, Err: err}
|
||||
}
|
||||
if err = s.uc.CreateVersion(ctx, &biz.Version{Name: versionPointer(name), Code: versionPointer(code), Description: versionPointer(description), Data: versionPointer(string(raw))}); err != nil {
|
||||
return &biz.VersionStageError{Stage: biz.VersionStageSave, Err: err}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (s *VersionService) Import(ctx context.Context, bundle *biz.VersionBundle) error {
|
||||
return s.uc.ImportVersionBundle(ctx, bundle)
|
||||
}
|
||||
func versionMenuDomain(value dto.VersionMenuRequest) *biz.Menu {
|
||||
menu := &biz.Menu{Path: value.Path, Name: value.Name, Hidden: value.Hidden, Component: value.Component, Sort: value.Sort, ActiveName: value.Meta.ActiveName, KeepAlive: value.Meta.KeepAlive, DefaultMenu: value.Meta.DefaultMenu, Title: value.Meta.Title, Icon: value.Meta.Icon, CloseTab: value.Meta.CloseTab, TransitionType: value.Meta.TransitionType}
|
||||
for _, button := range value.MenuButtons {
|
||||
menu.Buttons = append(menu.Buttons, &biz.MenuButton{Name: button.Name, Description: button.Description})
|
||||
}
|
||||
for _, parameter := range value.Parameters {
|
||||
menu.Parameters = append(menu.Parameters, &biz.MenuParameter{Type: parameter.Type, Key: parameter.Key, Value: parameter.Value})
|
||||
}
|
||||
for _, child := range value.Children {
|
||||
menu.Children = append(menu.Children, versionMenuDomain(child))
|
||||
}
|
||||
return menu
|
||||
}
|
||||
func (s *VersionService) ImportRequest(ctx context.Context, req *dto.ImportVersionRequest) error {
|
||||
if req.Version.Name == "" || req.Version.Code == "" {
|
||||
return biz.ErrInvalidVersion
|
||||
}
|
||||
bundle := &biz.VersionBundle{Name: req.Version.Name, Code: req.Version.Code, Description: req.Version.Description, ExportTime: req.Version.ExportTime}
|
||||
for _, menu := range req.Menus {
|
||||
bundle.Menus = append(bundle.Menus, versionMenuDomain(menu))
|
||||
}
|
||||
for _, api := range req.APIs {
|
||||
bundle.APIs = append(bundle.APIs, &biz.API{Path: api.Path, Description: api.Description, APIGroup: api.APIGroup, Method: api.Method})
|
||||
}
|
||||
for _, dictionary := range req.Dictionaries {
|
||||
item := &biz.Dictionary{Name: dictionary.Name, Type: dictionary.Type, Status: dictionary.Status, Desc: dictionary.Description}
|
||||
for _, detail := range dictionary.Details {
|
||||
item.Details = append(item.Details, &biz.DictionaryDetail{Label: detail.Label, Value: detail.Value, Extend: detail.Extend, Status: detail.Status, Sort: detail.Sort, ParentID: detail.ParentID, Level: detail.Level, Path: detail.Path})
|
||||
}
|
||||
bundle.Dictionaries = append(bundle.Dictionaries, item)
|
||||
}
|
||||
if err := s.Import(ctx, bundle); err != nil {
|
||||
return err
|
||||
}
|
||||
raw, _ := json.Marshal(req)
|
||||
_ = s.uc.CreateVersion(ctx, &biz.Version{
|
||||
Name: versionPointer(req.Version.Name),
|
||||
Code: versionPointer(req.Version.Code + "_imported_" + time.Now().Format("20060102150405")),
|
||||
Description: versionPointer("导入版本: " + req.Version.Description),
|
||||
Data: versionPointer(string(raw)),
|
||||
})
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user