优化结构
This commit is contained in:
@@ -2,8 +2,28 @@
|
||||
|
||||
`service` adapts HTTP-facing DTOs to business usecases and owns application
|
||||
orchestration. Request/response/filter contracts live in `dto/`; the root
|
||||
package contains resource services, conversions, and security
|
||||
coordination.
|
||||
package is a compatibility facade and module provider aggregator.
|
||||
|
||||
`dto_alias.go` is a compatibility bridge for existing service callers. New
|
||||
transport code should import `service/dto` directly when it needs a contract.
|
||||
Implementations are grouped by the same business modules as `biz` and `data`:
|
||||
|
||||
| Directory | Responsibility |
|
||||
| --- | --- |
|
||||
| `system/` | authentication, users, authorization, menus, organization, dictionaries, settings, audit, media, announcements, email, versions, exports |
|
||||
| `payment/` | payment orchestration and callback handling |
|
||||
| `integration/` | integration configuration orchestration |
|
||||
| `task/` | scheduled task orchestration |
|
||||
| `dto/` | HTTP request/response contracts |
|
||||
|
||||
The stateless router-prefix helper lives in `internal/utils/routepath` because
|
||||
both service modules and HTTP middleware use it; it does not depend on a
|
||||
business usecase or DTO.
|
||||
|
||||
Each module owns its Wire `ProviderSet`. The root `service` package re-exports
|
||||
the existing service types and constructors through aliases and thin wrappers, so handlers, middleware
|
||||
and generated Wire code can migrate independently without a flag day.
|
||||
|
||||
Within `system/`, larger cross-cutting resources stay in the same package while
|
||||
being split by concern (`audit.go` and its error/log companions, `media.go` and
|
||||
upload companion, and `export.go`/`export_excel.go`). New transport code should
|
||||
import the module package directly when it does not need the compatibility
|
||||
facade.
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package integration
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -0,0 +1,6 @@
|
||||
package integration
|
||||
|
||||
import "github.com/google/wire"
|
||||
|
||||
// ProviderSet wires integration transport services.
|
||||
var ProviderSet = wire.NewSet(NewIntegrationConfigService)
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package payment
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -0,0 +1,6 @@
|
||||
package payment
|
||||
|
||||
import "github.com/google/wire"
|
||||
|
||||
// ProviderSet wires payment transport services.
|
||||
var ProviderSet = wire.NewSet(NewPaymentService)
|
||||
@@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
+145
-3
@@ -1,6 +1,148 @@
|
||||
package service
|
||||
|
||||
import "github.com/google/wire"
|
||||
// This package is a compatibility facade for the transport layer. Concrete
|
||||
// implementations live under service/system, service/payment,
|
||||
// service/integration, and service/task; aliases here preserve the original
|
||||
// service.* API used by handlers and the composition root.
|
||||
|
||||
// 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, NewIntegrationConfigService)
|
||||
import (
|
||||
"kra/internal/biz/integration"
|
||||
paymentbiz "kra/internal/biz/payment"
|
||||
"kra/internal/biz/system"
|
||||
taskbiz "kra/internal/biz/task"
|
||||
"kra/internal/service/dto"
|
||||
integrationservice "kra/internal/service/integration"
|
||||
paymentservice "kra/internal/service/payment"
|
||||
systemservice "kra/internal/service/system"
|
||||
taskservice "kra/internal/service/task"
|
||||
"kra/internal/utils/routepath"
|
||||
|
||||
"github.com/google/wire"
|
||||
)
|
||||
|
||||
type AccessControlService = systemservice.AccessControlService
|
||||
type AnnouncementInput = systemservice.AnnouncementInput
|
||||
type AnnouncementService = systemservice.AnnouncementService
|
||||
type APIService = systemservice.APIService
|
||||
type AuditService = systemservice.AuditService
|
||||
type AuditRecorder = systemservice.AuditRecorder
|
||||
type AuthService = systemservice.AuthService
|
||||
type AuthorityService = systemservice.AuthorityService
|
||||
type DepartmentService = systemservice.DepartmentService
|
||||
type DictionaryService = systemservice.DictionaryService
|
||||
type EmailService = systemservice.EmailService
|
||||
type ExportService = systemservice.ExportService
|
||||
type ExportToken = systemservice.ExportToken
|
||||
type LogViewerService = systemservice.LogViewerService
|
||||
type MediaService = systemservice.MediaService
|
||||
type MenuService = systemservice.MenuService
|
||||
type ParameterService = systemservice.ParameterService
|
||||
type PermissionService = systemservice.PermissionService
|
||||
type PositionService = systemservice.PositionService
|
||||
type SecurityService = systemservice.SecurityService
|
||||
type PasswordPolicyError = systemservice.PasswordPolicyError
|
||||
type SystemConfigService = systemservice.SystemConfigService
|
||||
type TokenService = systemservice.TokenService
|
||||
type VersionService = systemservice.VersionService
|
||||
type PaymentService = paymentservice.PaymentService
|
||||
type IntegrationConfigService = integrationservice.IntegrationConfigService
|
||||
type TaskService = taskservice.TaskService
|
||||
type UserService = systemservice.UserService
|
||||
|
||||
func NewAccessControlService(uc *system.AccessControlUsecase) *AccessControlService {
|
||||
return systemservice.NewAccessControlService(uc)
|
||||
}
|
||||
func NewAnnouncementService(uc *system.AnnouncementUsecase) *AnnouncementService {
|
||||
return systemservice.NewAnnouncementService(uc)
|
||||
}
|
||||
func NewAPIService(uc *system.APIUsecase, settings system.RuntimeSettings) *APIService {
|
||||
return systemservice.NewAPIService(uc, settings)
|
||||
}
|
||||
func NewAuditService(uc *system.AuditUsecase) *AuditService {
|
||||
return systemservice.NewAuditService(uc)
|
||||
}
|
||||
func NewAuditRecorder(uc *system.AuditRecorderUsecase) *AuditRecorder {
|
||||
return systemservice.NewAuditRecorder(uc)
|
||||
}
|
||||
func NewAuthService(uc *system.AuthenticationUsecase) *AuthService {
|
||||
return systemservice.NewAuthService(uc)
|
||||
}
|
||||
func NewAuthorityService(uc *system.AuthorityUsecase) *AuthorityService {
|
||||
return systemservice.NewAuthorityService(uc)
|
||||
}
|
||||
func NewDepartmentService(uc *system.DepartmentUsecase) *DepartmentService {
|
||||
return systemservice.NewDepartmentService(uc)
|
||||
}
|
||||
func NewDictionaryService(uc *system.DictionaryUsecase) *DictionaryService {
|
||||
return systemservice.NewDictionaryService(uc)
|
||||
}
|
||||
func NewEmailService(uc *system.EmailUsecase) *EmailService {
|
||||
return systemservice.NewEmailService(uc)
|
||||
}
|
||||
func NewExportService(uc *system.ExportUsecase, cache system.Cache) *ExportService {
|
||||
return systemservice.NewExportService(uc, cache)
|
||||
}
|
||||
func NewIntegrationConfigService(uc *integration.IntegrationConfigUsecase) *IntegrationConfigService {
|
||||
return integrationservice.NewIntegrationConfigService(uc)
|
||||
}
|
||||
func NewLogViewerService(uc *system.LogViewerUsecase) *LogViewerService {
|
||||
return systemservice.NewLogViewerService(uc)
|
||||
}
|
||||
func NewMediaService(uc *system.MediaUsecase, settings system.RuntimeSettings) *MediaService {
|
||||
return systemservice.NewMediaService(uc, settings)
|
||||
}
|
||||
func NewMenuService(uc *system.MenuUsecase) *MenuService {
|
||||
return systemservice.NewMenuService(uc)
|
||||
}
|
||||
func NewParameterService(uc *system.ParameterUsecase) *ParameterService {
|
||||
return systemservice.NewParameterService(uc)
|
||||
}
|
||||
func NewPaymentService(uc *paymentbiz.PaymentUsecase) *PaymentService {
|
||||
return paymentservice.NewPaymentService(uc)
|
||||
}
|
||||
func NewPermissionService(uc *system.PermissionUsecase) *PermissionService {
|
||||
return systemservice.NewPermissionService(uc)
|
||||
}
|
||||
func NewPositionService(uc *system.PositionUsecase) *PositionService {
|
||||
return systemservice.NewPositionService(uc)
|
||||
}
|
||||
func NewSecurityService(uc *system.SecurityUsecase) *SecurityService {
|
||||
return systemservice.NewSecurityService(uc)
|
||||
}
|
||||
func NewSystemConfigService(uc *system.SystemConfigUsecase, settings system.RuntimeSettings) *SystemConfigService {
|
||||
return systemservice.NewSystemConfigService(uc, settings)
|
||||
}
|
||||
func NewTaskService(uc *taskbiz.TaskApplicationUsecase) *TaskService {
|
||||
return taskservice.NewTaskService(uc)
|
||||
}
|
||||
func NewTokenService(uc *system.TokenUsecase, issuer system.TokenIssuer) *TokenService {
|
||||
return systemservice.NewTokenService(uc, issuer)
|
||||
}
|
||||
func NewUserService(uc *system.UserUsecase, settings *SecurityService) *UserService {
|
||||
return systemservice.NewUserService(uc, settings)
|
||||
}
|
||||
func NewVersionService(uc *system.VersionUsecase) *VersionService {
|
||||
return systemservice.NewVersionService(uc)
|
||||
}
|
||||
|
||||
var ErrExportTokenInvalid = systemservice.ErrExportTokenInvalid
|
||||
var ErrExportTokenMalformed = systemservice.ErrExportTokenMalformed
|
||||
var ErrExportTokenType = systemservice.ErrExportTokenType
|
||||
|
||||
func NormalizeRoutePath(path, routerPrefix string) string {
|
||||
return routepath.Normalize(path, routerPrefix)
|
||||
}
|
||||
|
||||
func IsPasswordPolicyError(err error) bool { return systemservice.IsPasswordPolicyError(err) }
|
||||
|
||||
func DefaultPaymentCallbackAck(provider string, success bool) dto.PaymentCallbackAck {
|
||||
return paymentservice.DefaultPaymentCallbackAck(provider, success)
|
||||
}
|
||||
|
||||
// ProviderSet aggregates all service modules for Wire.
|
||||
var ProviderSet = wire.NewSet(
|
||||
systemservice.ProviderSet,
|
||||
paymentservice.ProviderSet,
|
||||
integrationservice.ProviderSet,
|
||||
taskservice.ProviderSet,
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,8 +1,9 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"kra/internal/biz/system"
|
||||
"kra/internal/utils/routepath"
|
||||
"strings"
|
||||
|
||||
"kra/internal/service/dto"
|
||||
@@ -21,7 +22,7 @@ func (s *APIService) NormalizeRoutePath(path string) string {
|
||||
if s.settings == nil {
|
||||
return path
|
||||
}
|
||||
return NormalizeRoutePath(path, s.settings.RouterPrefix())
|
||||
return routepath.Normalize(path, s.settings.RouterPrefix())
|
||||
}
|
||||
|
||||
func (s *APIService) apiDomain(value *dto.APIRequest) *system.API {
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"kra/internal/biz/system"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -0,0 +1,30 @@
|
||||
package system
|
||||
|
||||
import "github.com/google/wire"
|
||||
|
||||
// ProviderSet wires HTTP-facing services backed by the system business
|
||||
// module.
|
||||
var ProviderSet = wire.NewSet(
|
||||
NewAuthService,
|
||||
NewUserService,
|
||||
NewSystemConfigService,
|
||||
NewAuthorityService,
|
||||
NewPermissionService,
|
||||
NewAccessControlService,
|
||||
NewAPIService,
|
||||
NewMenuService,
|
||||
NewDepartmentService,
|
||||
NewPositionService,
|
||||
NewDictionaryService,
|
||||
NewParameterService,
|
||||
NewTokenService,
|
||||
NewSecurityService,
|
||||
NewVersionService,
|
||||
NewExportService,
|
||||
NewAuditService,
|
||||
NewAuditRecorder,
|
||||
NewLogViewerService,
|
||||
NewMediaService,
|
||||
NewAnnouncementService,
|
||||
NewEmailService,
|
||||
)
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"kra/internal/biz/system"
|
||||
"kra/internal/routecatalog"
|
||||
"kra/internal/service/dto"
|
||||
"kra/internal/utils/routepath"
|
||||
)
|
||||
|
||||
func (s *SystemConfigService) Initialize(ctx context.Context, input *dto.DatabaseInitRequest, apis []*system.API) error {
|
||||
@@ -28,7 +29,7 @@ func (s *SystemConfigService) Initialize(ctx context.Context, input *dto.Databas
|
||||
func (s *SystemConfigService) InitializeRoutes(ctx context.Context, input *dto.DatabaseInitRequest, routes []dto.Route) error {
|
||||
apis := make([]*system.API, 0, len(routes))
|
||||
for _, route := range routes {
|
||||
path := NormalizeRoutePath(route.Path, s.settings.RouterPrefix())
|
||||
path := routepath.Normalize(route.Path, s.settings.RouterPrefix())
|
||||
descriptor := routecatalog.Describe(route.Method, path)
|
||||
group, description := descriptor.Group, descriptor.Description
|
||||
apis = append(apis, &system.API{Path: path, Method: route.Method, APIGroup: group, Description: description})
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"kra/internal/biz/system"
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -0,0 +1,6 @@
|
||||
package task
|
||||
|
||||
import "github.com/google/wire"
|
||||
|
||||
// ProviderSet wires task transport services.
|
||||
var ProviderSet = wire.NewSet(NewTaskService)
|
||||
@@ -1,4 +1,4 @@
|
||||
package service
|
||||
package task
|
||||
|
||||
import (
|
||||
"context"
|
||||
Reference in New Issue
Block a user