kra/internal/service/system/api.go

254 lines
7.0 KiB
Go

package system
import (
"kra/internal/biz/system"
"kra/internal/server/middleware"
types "kra/internal/service/types/system"
"github.com/go-kratos/kratos/v2/errors"
khttp "github.com/go-kratos/kratos/v2/transport/http"
)
// ApiService API服务
type ApiService struct {
uc *system.ApiUsecase
}
// NewApiService 创建API服务
func NewApiService(uc *system.ApiUsecase) *ApiService {
return &ApiService{uc: uc}
}
// CreateApi 创建API
func (s *ApiService) CreateApi(ctx khttp.Context) error {
var req types.CreateApiRequest
if err := ctx.Bind(&req); err != nil {
return err
}
api := &system.Api{
Path: req.Path,
Description: req.Description,
ApiGroup: req.ApiGroup,
Method: req.Method,
}
if err := s.uc.CreateApi(ctx, api); err != nil {
return errors.BadRequest("CREATE_FAILED", err.Error())
}
return ctx.Result(200, nil)
}
// UpdateApi 更新API
func (s *ApiService) UpdateApi(ctx khttp.Context) error {
var req types.UpdateApiRequest
if err := ctx.Bind(&req); err != nil {
return err
}
api := &system.Api{
ID: req.ID,
Path: req.Path,
Description: req.Description,
ApiGroup: req.ApiGroup,
Method: req.Method,
}
if err := s.uc.UpdateApi(ctx, api); err != nil {
return errors.BadRequest("UPDATE_FAILED", err.Error())
}
return ctx.Result(200, nil)
}
// DeleteApi 删除API
func (s *ApiService) DeleteApi(ctx khttp.Context) error {
var req types.DeleteApiRequest
if err := ctx.Bind(&req); err != nil {
return err
}
if err := s.uc.DeleteApi(ctx, req.ID); err != nil {
return errors.BadRequest("DELETE_FAILED", err.Error())
}
return ctx.Result(200, nil)
}
// DeleteApisByIds 批量删除API
func (s *ApiService) DeleteApisByIds(ctx khttp.Context) error {
var req types.DeleteApisByIdsRequest
if err := ctx.Bind(&req); err != nil {
return err
}
if err := s.uc.DeleteApisByIds(ctx, req.Ids); err != nil {
return errors.BadRequest("DELETE_FAILED", err.Error())
}
return ctx.Result(200, nil)
}
// GetApiById 根据ID获取API
func (s *ApiService) GetApiById(ctx khttp.Context) error {
var req types.GetApiByIdRequest
if err := ctx.Bind(&req); err != nil {
return err
}
api, err := s.uc.GetApiById(ctx, req.ID)
if err != nil {
return errors.NotFound("NOT_FOUND", err.Error())
}
return ctx.Result(200, &types.GetApiByIdReply{Api: toTypesApiInfo(api)})
}
// GetApiList 获取API列表
func (s *ApiService) GetApiList(ctx khttp.Context) error {
var req types.GetApiListRequest
if err := ctx.Bind(&req); err != nil {
return err
}
filters := make(map[string]string)
if req.Path != "" {
filters["path"] = req.Path
}
if req.Description != "" {
filters["description"] = req.Description
}
if req.Method != "" {
filters["method"] = req.Method
}
if req.ApiGroup != "" {
filters["api_group"] = req.ApiGroup
}
apis, total, err := s.uc.GetAPIInfoList(ctx, req.Page, req.PageSize, filters, req.OrderKey, req.Desc)
if err != nil {
return errors.InternalServer("LIST_ERROR", err.Error())
}
list := make([]types.ApiInfo, len(apis))
for i, api := range apis {
list[i] = toTypesApiInfo(api)
}
return ctx.Result(200, &types.GetApiListReply{List: list, Total: total, Page: req.Page, PageSize: req.PageSize})
}
// GetAllApis 获取所有API
func (s *ApiService) GetAllApis(ctx khttp.Context) error {
authorityID := middleware.GetAuthorityID(ctx)
apis, err := s.uc.GetAllApis(ctx, authorityID)
if err != nil {
return errors.InternalServer("LIST_ERROR", err.Error())
}
list := make([]types.ApiInfo, len(apis))
for i, api := range apis {
list[i] = toTypesApiInfo(api)
}
return ctx.Result(200, &types.GetAllApisReply{Apis: list})
}
// GetApiGroups 获取API分组
func (s *ApiService) GetApiGroups(ctx khttp.Context) error {
groups, apiGroupMap, err := s.uc.GetApiGroups(ctx)
if err != nil {
return errors.InternalServer("LIST_ERROR", err.Error())
}
return ctx.Result(200, &types.GetApiGroupsReply{Groups: groups, ApiGroupMap: apiGroupMap})
}
// SyncApi 同步API
func (s *ApiService) SyncApi(ctx khttp.Context) error {
newApis, deleteApis, ignoreApis, err := s.uc.SyncApi(ctx)
if err != nil {
return errors.InternalServer("SYNC_ERROR", err.Error())
}
return ctx.Result(200, &types.SyncApiReply{
NewApis: toTypesApiInfoList(newApis),
DeleteApis: toTypesApiInfoList(deleteApis),
IgnoreApis: toTypesApiInfoList(ignoreApis),
})
}
// IgnoreApi 忽略API
func (s *ApiService) IgnoreApi(ctx khttp.Context) error {
var req types.IgnoreApiRequest
if err := ctx.Bind(&req); err != nil {
return err
}
if err := s.uc.IgnoreApi(ctx, req.Path, req.Method, req.Flag); err != nil {
return errors.BadRequest("IGNORE_FAILED", err.Error())
}
return ctx.Result(200, nil)
}
// EnterSyncApi 确认同步API
func (s *ApiService) EnterSyncApi(ctx khttp.Context) error {
var req types.EnterSyncApiRequest
if err := ctx.Bind(&req); err != nil {
return err
}
newApis := make([]*system.Api, len(req.NewApis))
for i, api := range req.NewApis {
newApis[i] = &system.Api{
Path: api.Path,
Description: api.Description,
ApiGroup: api.ApiGroup,
Method: api.Method,
}
}
deleteApis := make([]*system.Api, len(req.DeleteApis))
for i, api := range req.DeleteApis {
deleteApis[i] = &system.Api{
ID: api.ID,
Path: api.Path,
Method: api.Method,
}
}
if err := s.uc.EnterSyncApi(ctx, newApis, deleteApis); err != nil {
return errors.BadRequest("SYNC_FAILED", err.Error())
}
return ctx.Result(200, nil)
}
// FreshCasbin 刷新Casbin缓存
func (s *ApiService) FreshCasbin(ctx khttp.Context) error {
if err := s.uc.FreshCasbin(); err != nil {
return errors.InternalServer("FRESH_FAILED", err.Error())
}
return ctx.Result(200, nil)
}
// toTypesApiInfo 转换API信息为types格式
func toTypesApiInfo(api *system.Api) types.ApiInfo {
if api == nil {
return types.ApiInfo{}
}
return types.ApiInfo{
ID: api.ID,
Path: api.Path,
Description: api.Description,
ApiGroup: api.ApiGroup,
Method: api.Method,
}
}
// toTypesApiInfoList 批量转换API信息
func toTypesApiInfoList(apis []*system.Api) []types.ApiInfo {
list := make([]types.ApiInfo, len(apis))
for i, api := range apis {
list[i] = toTypesApiInfo(api)
}
return list
}
// RegisterRoutes 注册API管理路由
func (s *ApiService) RegisterRoutes(rg *RouterGroup) {
// 公开路由
rg.Public.GET("/api/freshCasbin", s.FreshCasbin)
// 私有路由 + 操作记录(写操作)
rg.PrivateWithRecord.GET("/api/getApiGroups", s.GetApiGroups)
rg.PrivateWithRecord.GET("/api/syncApi", s.SyncApi)
rg.PrivateWithRecord.POST("/api/ignoreApi", s.IgnoreApi)
rg.PrivateWithRecord.POST("/api/enterSyncApi", s.EnterSyncApi)
rg.PrivateWithRecord.POST("/api/createApi", s.CreateApi)
rg.PrivateWithRecord.POST("/api/deleteApi", s.DeleteApi)
rg.PrivateWithRecord.POST("/api/getApiById", s.GetApiById)
rg.PrivateWithRecord.POST("/api/updateApi", s.UpdateApi)
rg.PrivateWithRecord.DELETE("/api/deleteApisByIds", s.DeleteApisByIds)
// 私有路由(读操作,不记录)
rg.Private.POST("/api/getAllApis", s.GetAllApis)
rg.Private.POST("/api/getApiList", s.GetApiList)
}