cosy.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package cosy
  2. import (
  3. "github.com/0xJacky/Nginx-UI/internal/logger"
  4. "github.com/gin-gonic/gin"
  5. "github.com/go-playground/validator/v10"
  6. "gorm.io/gorm"
  7. )
  8. var validate *validator.Validate
  9. func init() {
  10. validate = validator.New()
  11. }
  12. type Ctx[T any] struct {
  13. ctx *gin.Context
  14. rules gin.H
  15. Payload map[string]interface{}
  16. Model T
  17. abort bool
  18. nextHandler *gin.HandlerFunc
  19. beforeDecodeHookFunc []func(ctx *Ctx[T])
  20. beforeExecuteHookFunc []func(ctx *Ctx[T])
  21. executedHookFunc []func(ctx *Ctx[T])
  22. gormScopes []func(tx *gorm.DB) *gorm.DB
  23. preloads []string
  24. scan func(tx *gorm.DB) any
  25. transformer func(*T) any
  26. permanentlyDelete bool
  27. SelectedFields []string
  28. }
  29. func Core[T any](c *gin.Context) *Ctx[T] {
  30. return &Ctx[T]{
  31. ctx: c,
  32. gormScopes: make([]func(tx *gorm.DB) *gorm.DB, 0),
  33. beforeExecuteHookFunc: make([]func(ctx *Ctx[T]), 0),
  34. beforeDecodeHookFunc: make([]func(ctx *Ctx[T]), 0),
  35. }
  36. }
  37. func (c *Ctx[T]) SetValidRules(rules gin.H) *Ctx[T] {
  38. c.rules = rules
  39. return c
  40. }
  41. func (c *Ctx[T]) BeforeDecodeHook(hook ...func(ctx *Ctx[T])) *Ctx[T] {
  42. c.beforeDecodeHookFunc = append(c.beforeDecodeHookFunc, hook...)
  43. return c
  44. }
  45. func (c *Ctx[T]) BeforeExecuteHook(hook ...func(ctx *Ctx[T])) *Ctx[T] {
  46. c.beforeExecuteHookFunc = append(c.beforeExecuteHookFunc, hook...)
  47. return c
  48. }
  49. func (c *Ctx[T]) ExecutedHook(hook ...func(ctx *Ctx[T])) *Ctx[T] {
  50. c.executedHookFunc = append(c.executedHookFunc, hook...)
  51. return c
  52. }
  53. func (c *Ctx[T]) SetPreloads(args ...string) *Ctx[T] {
  54. c.preloads = append(c.preloads, args...)
  55. return c
  56. }
  57. func (c *Ctx[T]) beforeExecuteHook() {
  58. if len(c.beforeExecuteHookFunc) > 0 {
  59. for _, v := range c.beforeExecuteHookFunc {
  60. v(c)
  61. }
  62. }
  63. }
  64. func (c *Ctx[T]) beforeDecodeHook() {
  65. if len(c.beforeDecodeHookFunc) > 0 {
  66. for _, v := range c.beforeDecodeHookFunc {
  67. v(c)
  68. }
  69. }
  70. }
  71. func (c *Ctx[T]) validate() (errs gin.H) {
  72. c.Payload = make(gin.H)
  73. _ = c.ctx.ShouldBindJSON(&c.Payload)
  74. errs = validate.ValidateMap(c.Payload, c.rules)
  75. if len(errs) > 0 {
  76. logger.Debug(errs)
  77. for k := range errs {
  78. errs[k] = c.rules[k]
  79. }
  80. return
  81. }
  82. // Make sure that the key in c.Payload is also the key of rules
  83. validated := make(map[string]interface{})
  84. for k, v := range c.Payload {
  85. if _, ok := c.rules[k]; ok {
  86. validated[k] = v
  87. }
  88. }
  89. c.Payload = validated
  90. return
  91. }
  92. func (c *Ctx[T]) SetScan(scan func(tx *gorm.DB) any) *Ctx[T] {
  93. c.scan = scan
  94. return c
  95. }
  96. func (c *Ctx[T]) SetTransformer(t func(m *T) any) *Ctx[T] {
  97. c.transformer = t
  98. return c
  99. }
  100. func (c *Ctx[T]) AbortWithError(err error) {
  101. c.abort = true
  102. errHandler(c.ctx, err)
  103. }
  104. func (c *Ctx[T]) Abort() {
  105. c.abort = true
  106. }
  107. func (c *Ctx[T]) PermanentlyDelete() *Ctx[T] {
  108. c.permanentlyDelete = true
  109. return c
  110. }
  111. func (c *Ctx[T]) GormScope(hook func(tx *gorm.DB) *gorm.DB) *Ctx[T] {
  112. c.gormScopes = append(c.gormScopes, hook)
  113. return c
  114. }