You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
5.7 KiB
168 lines
5.7 KiB
1 week ago
|
package service
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"gofaster/internal/auth/model"
|
||
|
"gofaster/internal/auth/repository"
|
||
|
|
||
|
"go.uber.org/zap"
|
||
|
)
|
||
|
|
||
|
// FrontendRouteService 前台路由服务
|
||
|
type FrontendRouteService struct {
|
||
|
frontendRouteRepo *repository.FrontendRouteRepository
|
||
|
frontendBackendRouteRepo *repository.FrontendBackendRouteRepository
|
||
|
logger *zap.Logger
|
||
|
}
|
||
|
|
||
|
// NewFrontendRouteService 创建前台路由服务实例
|
||
|
func NewFrontendRouteService(
|
||
|
frontendRouteRepo *repository.FrontendRouteRepository,
|
||
|
frontendBackendRouteRepo *repository.FrontendBackendRouteRepository,
|
||
|
logger *zap.Logger,
|
||
|
) *FrontendRouteService {
|
||
|
return &FrontendRouteService{
|
||
|
frontendRouteRepo: frontendRouteRepo,
|
||
|
frontendBackendRouteRepo: frontendBackendRouteRepo,
|
||
|
logger: logger,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// SyncFrontendRoute 同步单个前台路由
|
||
|
func (s *FrontendRouteService) SyncFrontendRoute(routeData map[string]interface{}) error {
|
||
|
s.logger.Info("开始同步前台路由", zap.String("path", routeData["path"].(string)))
|
||
|
|
||
|
// 1. 创建或更新前台路由
|
||
|
frontendRoute := &model.FrontendRoute{
|
||
|
Path: routeData["path"].(string),
|
||
|
Name: routeData["name"].(string),
|
||
|
Component: routeData["component"].(string),
|
||
|
Module: routeData["module"].(string),
|
||
|
Description: routeData["description"].(string),
|
||
|
Sort: int(routeData["sort"].(float64)),
|
||
|
Status: 1,
|
||
|
}
|
||
|
|
||
|
if err := s.frontendRouteRepo.UpsertByPath(frontendRoute); err != nil {
|
||
|
s.logger.Error("同步前台路由失败", zap.Error(err))
|
||
|
return fmt.Errorf("同步前台路由失败: %w", err)
|
||
|
}
|
||
|
|
||
|
// 2. 获取前台路由ID
|
||
|
existingRoute, err := s.frontendRouteRepo.FindByPath(frontendRoute.Path)
|
||
|
if err != nil {
|
||
|
s.logger.Error("查找前台路由失败", zap.Error(err))
|
||
|
return fmt.Errorf("查找前台路由失败: %w", err)
|
||
|
}
|
||
|
|
||
|
// 3. 处理后台路由关联
|
||
|
if backendRoutes, ok := routeData["backend_routes"].([]interface{}); ok {
|
||
|
// 先删除现有的关联
|
||
|
if err := s.frontendBackendRouteRepo.DeleteByFrontendRouteID(existingRoute.ID); err != nil {
|
||
|
s.logger.Error("删除现有关联失败", zap.Error(err))
|
||
|
return fmt.Errorf("删除现有关联失败: %w", err)
|
||
|
}
|
||
|
|
||
|
// 创建新的关联
|
||
|
for i, backendRouteData := range backendRoutes {
|
||
|
backendRoute := backendRouteData.(map[string]interface{})
|
||
|
relation := &model.FrontendBackendRoute{
|
||
|
FrontendRouteID: existingRoute.ID,
|
||
|
BackendRoute: backendRoute["backend_route"].(string),
|
||
|
HTTPMethod: backendRoute["http_method"].(string),
|
||
|
AuthGroup: s.getAuthGroupByMethod(backendRoute["http_method"].(string)),
|
||
|
Module: backendRoute["module"].(string),
|
||
|
Description: backendRoute["description"].(string),
|
||
|
IsDefault: i == 0, // 第一个为默认关联
|
||
|
Sort: i,
|
||
|
Status: 1,
|
||
|
}
|
||
|
|
||
|
if err := s.frontendBackendRouteRepo.Upsert(relation); err != nil {
|
||
|
s.logger.Error("创建前后台路由关联失败", zap.Error(err))
|
||
|
return fmt.Errorf("创建前后台路由关联失败: %w", err)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
s.logger.Info("前台路由同步成功", zap.String("path", frontendRoute.Path))
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// BatchSyncFrontendRoutes 批量同步前台路由
|
||
|
func (s *FrontendRouteService) BatchSyncFrontendRoutes(routesData []map[string]interface{}) error {
|
||
|
s.logger.Info("开始批量同步前台路由", zap.Int("count", len(routesData)))
|
||
|
|
||
|
for i, routeData := range routesData {
|
||
|
if err := s.SyncFrontendRoute(routeData); err != nil {
|
||
|
s.logger.Error("批量同步前台路由失败",
|
||
|
zap.Int("index", i),
|
||
|
zap.String("path", routeData["path"].(string)),
|
||
|
zap.Error(err))
|
||
|
return fmt.Errorf("批量同步前台路由失败 [%d]: %w", i, err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
s.logger.Info("批量同步前台路由完成", zap.Int("count", len(routesData)))
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// GetFrontendRoutes 获取前台路由列表
|
||
|
func (s *FrontendRouteService) GetFrontendRoutes() ([]*model.FrontendRoute, error) {
|
||
|
return s.frontendRouteRepo.List()
|
||
|
}
|
||
|
|
||
|
// GetFrontendRouteByID 根据ID获取前台路由
|
||
|
func (s *FrontendRouteService) GetFrontendRouteByID(id uint) (*model.FrontendRoute, error) {
|
||
|
return s.frontendRouteRepo.FindByID(id)
|
||
|
}
|
||
|
|
||
|
// GetFrontendRouteByPath 根据路径获取前台路由
|
||
|
func (s *FrontendRouteService) GetFrontendRouteByPath(path string) (*model.FrontendRoute, error) {
|
||
|
return s.frontendRouteRepo.FindByPath(path)
|
||
|
}
|
||
|
|
||
|
// GetFrontendRoutesByModule 根据模块获取前台路由
|
||
|
func (s *FrontendRouteService) GetFrontendRoutesByModule(module string) ([]*model.FrontendRoute, error) {
|
||
|
return s.frontendRouteRepo.FindByModule(module)
|
||
|
}
|
||
|
|
||
|
// GetRouteRelations 获取路由关联关系
|
||
|
func (s *FrontendRouteService) GetRouteRelations() ([]map[string]interface{}, error) {
|
||
|
return s.frontendBackendRouteRepo.GetWithFrontendRoute()
|
||
|
}
|
||
|
|
||
|
// GetRouteRelationsByFrontendRouteID 根据前台路由ID获取关联关系
|
||
|
func (s *FrontendRouteService) GetRouteRelationsByFrontendRouteID(frontendRouteID uint) ([]*model.FrontendBackendRoute, error) {
|
||
|
return s.frontendBackendRouteRepo.FindByFrontendRouteID(frontendRouteID)
|
||
|
}
|
||
|
|
||
|
// GetStats 获取统计信息
|
||
|
func (s *FrontendRouteService) GetStats() (map[string]interface{}, error) {
|
||
|
frontendStats, err := s.frontendRouteRepo.GetStats()
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
relationStats, err := s.frontendBackendRouteRepo.GetStats()
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return map[string]interface{}{
|
||
|
"frontend_routes": frontendStats,
|
||
|
"route_relations": relationStats,
|
||
|
}, nil
|
||
|
}
|
||
|
|
||
|
// getAuthGroupByMethod 根据HTTP方法获取权限分组
|
||
|
func (s *FrontendRouteService) getAuthGroupByMethod(method string) string {
|
||
|
editMethods := []string{"POST", "PUT", "PATCH", "DELETE"}
|
||
|
for _, editMethod := range editMethods {
|
||
|
if method == editMethod {
|
||
|
return "Edit"
|
||
|
}
|
||
|
}
|
||
|
return "Read"
|
||
|
}
|