kra/internal/data/system/api.go

266 lines
6.5 KiB
Go

package system
import (
"context"
"errors"
"strings"
"kra/internal/biz/system"
"kra/internal/data/model"
"kra/internal/data/query"
"gorm.io/gorm"
)
type apiRepo struct {
db *gorm.DB
}
// NewApiRepo 创建API仓储
func NewApiRepo(db *gorm.DB) system.ApiRepo {
return &apiRepo{db: db}
}
func (r *apiRepo) Create(ctx context.Context, api *system.Api) error {
_, err := query.SysAPI.WithContext(ctx).Where(
query.SysAPI.Path.Eq(api.Path),
query.SysAPI.Method.Eq(api.Method),
).First()
if err == nil {
return errors.New("存在相同api")
}
if !errors.Is(err, gorm.ErrRecordNotFound) {
return err
}
m := toModelAPI(api)
return query.SysAPI.WithContext(ctx).Create(m)
}
func (r *apiRepo) Update(ctx context.Context, api *system.Api) error {
old, err := query.SysAPI.WithContext(ctx).Where(query.SysAPI.ID.Eq(int64(api.ID))).First()
if err != nil {
return err
}
if old.Path != api.Path || old.Method != api.Method {
dup, ferr := query.SysAPI.WithContext(ctx).Where(
query.SysAPI.Path.Eq(api.Path),
query.SysAPI.Method.Eq(api.Method),
).First()
if ferr == nil && dup.ID != int64(api.ID) {
return errors.New("存在相同api路径")
}
if ferr != nil && !errors.Is(ferr, gorm.ErrRecordNotFound) {
return ferr
}
}
m := toModelAPI(api)
_, err = query.SysAPI.WithContext(ctx).Where(query.SysAPI.ID.Eq(int64(api.ID))).Updates(m)
return err
}
func (r *apiRepo) Delete(ctx context.Context, id uint) error {
_, err := query.SysAPI.WithContext(ctx).Where(query.SysAPI.ID.Eq(int64(id))).Delete()
return err
}
func (r *apiRepo) DeleteByIds(ctx context.Context, ids []uint) error {
int64Ids := make([]int64, len(ids))
for i, id := range ids {
int64Ids[i] = int64(id)
}
_, err := query.SysAPI.WithContext(ctx).Where(query.SysAPI.ID.In(int64Ids...)).Delete()
return err
}
func (r *apiRepo) FindByID(ctx context.Context, id uint) (*system.Api, error) {
m, err := query.SysAPI.WithContext(ctx).Where(query.SysAPI.ID.Eq(int64(id))).First()
if err != nil {
return nil, err
}
return toBizAPI(m), nil
}
func (r *apiRepo) FindByPathMethod(ctx context.Context, path, method string) (*system.Api, error) {
m, err := query.SysAPI.WithContext(ctx).Where(
query.SysAPI.Path.Eq(path),
query.SysAPI.Method.Eq(method),
).First()
if err != nil {
return nil, err
}
return toBizAPI(m), nil
}
func (r *apiRepo) List(ctx context.Context, page, pageSize int, filters map[string]string, orderKey string, desc bool) ([]*system.Api, int64, error) {
q := query.SysAPI.WithContext(ctx)
if v, ok := filters["path"]; ok && v != "" {
q = q.Where(query.SysAPI.Path.Like("%" + v + "%"))
}
if v, ok := filters["description"]; ok && v != "" {
q = q.Where(query.SysAPI.Description.Like("%" + v + "%"))
}
if v, ok := filters["method"]; ok && v != "" {
q = q.Where(query.SysAPI.Method.Eq(v))
}
if v, ok := filters["api_group"]; ok && v != "" {
q = q.Where(query.SysAPI.APIGroup.Eq(v))
}
total, err := q.Count()
if err != nil {
return nil, 0, err
}
orderMap := map[string]bool{"id": true, "path": true, "api_group": true, "description": true, "method": true}
if orderKey != "" && orderMap[orderKey] {
switch orderKey {
case "id":
if desc {
q = q.Order(query.SysAPI.ID.Desc())
} else {
q = q.Order(query.SysAPI.ID)
}
case "path":
if desc {
q = q.Order(query.SysAPI.Path.Desc())
} else {
q = q.Order(query.SysAPI.Path)
}
case "api_group":
if desc {
q = q.Order(query.SysAPI.APIGroup.Desc())
} else {
q = q.Order(query.SysAPI.APIGroup)
}
case "description":
if desc {
q = q.Order(query.SysAPI.Description.Desc())
} else {
q = q.Order(query.SysAPI.Description)
}
case "method":
if desc {
q = q.Order(query.SysAPI.Method.Desc())
} else {
q = q.Order(query.SysAPI.Method)
}
}
} else {
q = q.Order(query.SysAPI.ID.Desc())
}
offset := (page - 1) * pageSize
list, err := q.Offset(offset).Limit(pageSize).Find()
if err != nil {
return nil, 0, err
}
apis := make([]*system.Api, len(list))
for i, m := range list {
apis[i] = toBizAPI(m)
}
return apis, total, nil
}
func (r *apiRepo) FindAll(ctx context.Context) ([]*system.Api, error) {
list, err := query.SysAPI.WithContext(ctx).Order(query.SysAPI.ID.Desc()).Find()
if err != nil {
return nil, err
}
apis := make([]*system.Api, len(list))
for i, m := range list {
apis[i] = toBizAPI(m)
}
return apis, nil
}
func (r *apiRepo) FindByIds(ctx context.Context, ids []uint) ([]*system.Api, error) {
int64Ids := make([]int64, len(ids))
for i, id := range ids {
int64Ids[i] = int64(id)
}
list, err := query.SysAPI.WithContext(ctx).Where(query.SysAPI.ID.In(int64Ids...)).Find()
if err != nil {
return nil, err
}
apis := make([]*system.Api, len(list))
for i, m := range list {
apis[i] = toBizAPI(m)
}
return apis, nil
}
func (r *apiRepo) GetApiGroups(ctx context.Context) ([]string, map[string]string, error) {
list, err := query.SysAPI.WithContext(ctx).Find()
if err != nil {
return nil, nil, err
}
groupMap := make(map[string]bool)
apiGroupMap := make(map[string]string)
var groups []string
for _, m := range list {
if !groupMap[m.APIGroup] {
groupMap[m.APIGroup] = true
groups = append(groups, m.APIGroup)
}
if len(m.Path) > 1 {
parts := strings.Split(m.Path, "/")
if len(parts) > 1 {
apiGroupMap[parts[1]] = m.APIGroup
}
}
}
return groups, apiGroupMap, nil
}
func (r *apiRepo) CreateIgnoreApi(ctx context.Context, path, method string) error {
m := &model.SysIgnoreAPI{
Path: path,
Method: method,
}
return r.db.WithContext(ctx).Create(m).Error
}
func (r *apiRepo) DeleteIgnoreApi(ctx context.Context, path, method string) error {
return r.db.WithContext(ctx).Unscoped().Where("path = ? AND method = ?", path, method).Delete(&model.SysIgnoreAPI{}).Error
}
func (r *apiRepo) FindAllIgnoreApis(ctx context.Context) ([]*system.IgnoreApi, error) {
var list []model.SysIgnoreAPI
if err := r.db.WithContext(ctx).Find(&list).Error; err != nil {
return nil, err
}
result := make([]*system.IgnoreApi, len(list))
for i, m := range list {
result[i] = &system.IgnoreApi{
Path: m.Path,
Method: m.Method,
}
}
return result, nil
}
// 转换函数
func toModelAPI(a *system.Api) *model.SysAPI {
return &model.SysAPI{
ID: int64(a.ID),
Path: a.Path,
Description: a.Description,
APIGroup: a.ApiGroup,
Method: a.Method,
}
}
func toBizAPI(m *model.SysAPI) *system.Api {
return &system.Api{
ID: uint(m.ID),
Path: m.Path,
Description: m.Description,
ApiGroup: m.APIGroup,
Method: m.Method,
}
}