complete role crud

This commit is contained in:
yanghao05
2023-02-04 19:54:29 +08:00
parent 2fb6bba903
commit 285e1f1c51
13 changed files with 270 additions and 19 deletions

13
common/err/common.go Normal file
View File

@@ -0,0 +1,13 @@
package err
import (
"net/http"
"github.com/rogeecn/gen"
)
var (
BindBodyFailed = gen.NewBusError(http.StatusBadRequest, http.StatusBadRequest, "Body参数错误")
BindQueryFailed = gen.NewBusError(http.StatusBadRequest, http.StatusBadRequest, "Query参数错误")
BindPathFailed = gen.NewBusError(http.StatusBadRequest, http.StatusBadRequest, "Path参数错误: %s")
)

6
common/request/page.go Normal file
View File

@@ -0,0 +1,6 @@
package request
type PageFilter struct {
Page uint64 `form:"page"`
Limit uint64 `form:"limit"`
}

6
common/response/page.go Normal file
View File

@@ -0,0 +1,6 @@
package response
type PageResponse[T any] struct {
Items []T `json:"items,omitempty"`
Total uint64 `json:"total,omitempty"`
}

47
database/seeders/sys_role.go Executable file
View File

@@ -0,0 +1,47 @@
package seeders
import (
"atom/container"
"atom/contracts"
"atom/database/models"
"log"
"github.com/brianvoe/gofakeit/v6"
"go.uber.org/dig"
"gorm.io/gorm"
)
func init() {
if err := container.Container.Provide(NewSysRoleSeeder, dig.Group("seeders")); err != nil {
log.Fatal(err)
}
}
type SysRoleSeeder struct {
}
func NewSysRoleSeeder() contracts.Seeder {
return &SysRoleSeeder{}
}
func (s *SysRoleSeeder) Run(faker *gofakeit.Faker, db *gorm.DB) {
times := 10
for i := 0; i < times; i++ {
data := s.Generate(faker, i)
if i == 0 {
stmt := &gorm.Statement{DB: db}
_ = stmt.Parse(&data)
log.Printf("seeding %s for %d times", stmt.Schema.Table, times)
}
db.Create(&data)
}
}
func (s *SysRoleSeeder) Generate(faker *gofakeit.Faker, idx int) models.SysRole {
return models.SysRole{
UUID: faker.UUID(),
Name: faker.Name(),
ParentID: uint64(faker.IntRange(1, 100)),
DefaultRouter: faker.Name(),
}
}

2
go.mod
View File

@@ -1,6 +1,6 @@
module atom
go 1.18
go 1.19
require (
github.com/brianvoe/gofakeit/v6 v6.20.1

View File

@@ -5,6 +5,7 @@ import (
"atom/modules/auth/controller"
"atom/modules/auth/dao"
"atom/modules/auth/routes"
"atom/modules/auth/service"
"log"
"go.uber.org/dig"
@@ -22,6 +23,9 @@ func init() {
}
//service
if err := container.Container.Provide(service.NewRoleService); err != nil {
log.Fatal(err)
}
// dao
if err := container.Container.Provide(dao.NewRoleDao); err != nil {

View File

@@ -1,28 +1,50 @@
package controller
import (
"atom/common/request"
"atom/common/response"
"atom/database/models"
"atom/modules/auth/dto"
"atom/providers/config"
"atom/modules/auth/service"
"github.com/gin-gonic/gin"
)
type RoleController interface {
GetName(*gin.Context) (string, error)
GetByFilter(*gin.Context, dto.RoleRequestFilter, request.PageFilter) (*response.PageResponse[*models.SysRole], error)
Create(*gin.Context, dto.RoleRequestForm) error
Delete(*gin.Context, int) error
UpdateByID(*gin.Context, int, dto.RoleRequestForm) error
}
type roleControllerImpl struct {
conf *config.Config
roleSvc service.RoleService
}
func NewRoleController(conf *config.Config) RoleController {
return &roleControllerImpl{conf: conf}
func NewRoleController(
roleSvc service.RoleService,
) RoleController {
return &roleControllerImpl{
roleSvc: roleSvc,
}
}
func (c *roleControllerImpl) GetName(ctx *gin.Context) (string, error) {
return "Role", nil
func (c *roleControllerImpl) GetByFilter(
ctx *gin.Context,
filter dto.RoleRequestFilter,
page request.PageFilter,
) (*response.PageResponse[*models.SysRole], error) {
return c.roleSvc.GetByFilter(ctx, filter, page)
}
func (c *roleControllerImpl) Create(ctx *gin.Context, req *dto.RoleCreateRequest) error {
return nil
func (c *roleControllerImpl) Create(ctx *gin.Context, req dto.RoleRequestForm) error {
_, err := c.roleSvc.Create(ctx, req)
return err
}
func (c *roleControllerImpl) UpdateByID(ctx *gin.Context, id int, req dto.RoleRequestForm) error {
_, err := c.roleSvc.UpdateByID(ctx, uint64(id), req)
return err
}
func (c *roleControllerImpl) Delete(ctx *gin.Context, id int) error {
return c.roleSvc.DeleteByID(ctx, uint64(id))
}

View File

@@ -1,12 +1,15 @@
package dao
import (
"atom/common/request"
"atom/database/models"
"atom/database/query"
"atom/modules/auth/dto"
"context"
)
type RoleDao interface {
GetByFilter(context.Context, dto.RoleRequestFilter, request.PageFilter) ([]*models.SysRole, uint64, error)
FindByID(context.Context, uint64) (*models.SysRole, error)
Create(context.Context, *models.SysRole) (*models.SysRole, error)
UpdateByID(context.Context, *models.SysRole) (*models.SysRole, error)
@@ -22,6 +25,35 @@ func NewRoleDao(query *query.Query) RoleDao {
return &roleDaoImpl{query: query}
}
func (dao *roleDaoImpl) GetByFilter(ctx context.Context, filter dto.RoleRequestFilter, page request.PageFilter) ([]*models.SysRole, uint64, error) {
role := dao.query.SysRole
query := role.WithContext(ctx)
if filter.DefaultRouter != nil {
query = query.Where(role.DefaultRouter.Eq(*filter.DefaultRouter))
}
if filter.Name != nil {
query = query.Where(role.Name.Like(*filter.Name))
}
if filter.ParentID != nil {
query = query.Where(role.ParentID.Eq(uint64(*filter.ParentID)))
}
total, err := query.Count()
if err != nil {
return nil, 0, err
}
items, err := query.Find()
if err != nil {
return nil, 0, err
}
return items, uint64(total), nil
}
func (dao *roleDaoImpl) FindByID(ctx context.Context, id uint64) (*models.SysRole, error) {
role := dao.query.SysRole
return role.WithContext(ctx).Where(role.ID.Eq(id)).First()

View File

@@ -1,7 +1,12 @@
package dto
type RoleCreateRequest struct {
UUID string `json:"alias,omitempty"`
type RoleRequestFilter struct {
Name *string `form:"name"`
ParentID *uint `form:"parent_id"`
DefaultRouter *string `form:"default_router"`
}
type RoleRequestForm struct {
Name string `json:"name,omitempty"`
ParentID uint `json:"parent_id,omitempty"`
DefaultRouter string `json:"default_router,omitempty"`

View File

@@ -1,8 +1,11 @@
package routes
import (
"atom/common/err"
"atom/common/request"
"atom/contracts"
"atom/modules/auth/controller"
"atom/modules/auth/dto"
"atom/providers/http"
"github.com/rogeecn/gen"
@@ -29,9 +32,29 @@ func NewRoute(
func (r *Route) Register() {
group := r.svc.Engine.Group("auth")
{
roleGroup := group.Group("role")
roleGroup := group.Group("roles")
{
roleGroup.GET("/roles", gen.DataFunc(r.role.GetName))
roleGroup.GET("", gen.DataFunc2(
r.role.GetByFilter,
gen.BindQuery(dto.RoleRequestFilter{}, err.BindQueryFailed),
gen.BindQuery(request.PageFilter{}, err.BindQueryFailed),
))
roleGroup.POST("", gen.Func1(
r.role.Create,
gen.BindBody(dto.RoleRequestForm{}, err.BindBodyFailed),
))
roleGroup.PUT("/:id", gen.Func2(
r.role.UpdateByID,
gen.Int("role_id", err.BindPathFailed.Format("id")),
gen.BindBody(dto.RoleRequestForm{}, err.BindBodyFailed),
))
roleGroup.DELETE("/:id", gen.Func1(
r.role.Delete,
gen.Int("role_id", err.BindPathFailed.Format("id")),
))
}
permissionGroup := group.Group("permission")

View File

@@ -1,20 +1,75 @@
package service
import (
"atom/common/request"
"atom/common/response"
"atom/database/models"
"atom/modules/auth/dao"
"atom/modules/auth/dto"
"atom/providers/uuid"
"context"
)
type RoleService interface {
Create(ctx context.Context) error
GetByFilter(context.Context, dto.RoleRequestFilter, request.PageFilter) (*response.PageResponse[*models.SysRole], error)
Create(context.Context, dto.RoleRequestForm) (*models.SysRole, error)
UpdateByID(context.Context, uint64, dto.RoleRequestForm) (*models.SysRole, error)
DeleteByID(context.Context, uint64) error
}
type roleService struct {
dao dao.RoleDao
uuid *uuid.Generator
}
func NewRoleService() RoleService {
return &roleService{}
func NewRoleService(
dao dao.RoleDao,
uuid *uuid.Generator,
) RoleService {
return &roleService{
dao: dao,
uuid: uuid,
}
}
func (svc *roleService) Create(ctx context.Context) error {
return nil
func (svc *roleService) GetByFilter(
ctx context.Context,
filter dto.RoleRequestFilter,
page request.PageFilter,
) (*response.PageResponse[*models.SysRole], error) {
items, count, err := svc.dao.GetByFilter(ctx, filter, page)
if err != nil {
return nil, err
}
return &response.PageResponse[*models.SysRole]{
Items: items,
Total: count,
}, nil
}
func (svc *roleService) Create(ctx context.Context, req dto.RoleRequestForm) (*models.SysRole, error) {
model := models.SysRole{
UUID: svc.uuid.MustGenerate(),
Name: req.Name,
ParentID: uint64(req.ParentID),
DefaultRouter: req.DefaultRouter,
}
return svc.dao.Create(ctx, &model)
}
func (svc *roleService) UpdateByID(ctx context.Context, id uint64, req dto.RoleRequestForm) (*models.SysRole, error) {
model, err := svc.dao.FindByID(ctx, id)
if err != nil {
return nil, err
}
model.Name = req.Name
model.ParentID = uint64(req.ParentID)
model.DefaultRouter = req.DefaultRouter
return svc.dao.UpdateByID(ctx, model)
}
func (svc *roleService) DeleteByID(ctx context.Context, id uint64) error {
return svc.dao.DeleteByID(ctx, id)
}

View File

@@ -11,4 +11,5 @@ import (
_ "atom/providers/log"
_ "atom/providers/query"
_ "atom/providers/single_flight"
_ "atom/providers/uuid"
)

37
providers/uuid/uuid.go Normal file
View File

@@ -0,0 +1,37 @@
package uuid
import (
"atom/container"
"log"
"github.com/gofrs/uuid"
)
func init() {
if err := container.Container.Provide(NewUUID); err != nil {
log.Fatal(err)
}
}
type Generator struct {
generator uuid.Generator
}
func NewUUID() (*Generator, error) {
return &Generator{
generator: uuid.DefaultGenerator,
}, nil
}
func (u *Generator) MustGenerate() string {
uuid, _ := u.Generate()
return uuid
}
func (u *Generator) Generate() (string, error) {
uuid, err := u.generator.NewV4()
if err != nil {
return "", err
}
return uuid.String(), err
}