cosy.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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. SelectedFields []string
  27. }
  28. func Core[T any](c *gin.Context) *Ctx[T] {
  29. return &Ctx[T]{
  30. ctx: c,
  31. gormScopes: make([]func(tx *gorm.DB) *gorm.DB, 0),
  32. beforeExecuteHookFunc: make([]func(ctx *Ctx[T]), 0),
  33. beforeDecodeHookFunc: make([]func(ctx *Ctx[T]), 0),
  34. }
  35. }
  36. func (c *Ctx[T]) SetValidRules(rules gin.H) *Ctx[T] {
  37. c.rules = rules
  38. return c
  39. }
  40. func (c *Ctx[T]) BeforeDecodeHook(hook ...func(ctx *Ctx[T])) *Ctx[T] {
  41. c.beforeDecodeHookFunc = append(c.beforeDecodeHookFunc, hook...)
  42. return c
  43. }
  44. func (c *Ctx[T]) BeforeExecuteHook(hook ...func(ctx *Ctx[T])) *Ctx[T] {
  45. c.beforeExecuteHookFunc = append(c.beforeExecuteHookFunc, hook...)
  46. return c
  47. }
  48. func (c *Ctx[T]) ExecutedHook(hook ...func(ctx *Ctx[T])) *Ctx[T] {
  49. c.executedHookFunc = append(c.executedHookFunc, hook...)
  50. return c
  51. }
  52. func (c *Ctx[T]) SetPreloads(args ...string) *Ctx[T] {
  53. c.preloads = append(c.preloads, args...)
  54. return c
  55. }
  56. func (c *Ctx[T]) beforeExecuteHook() {
  57. if len(c.beforeExecuteHookFunc) > 0 {
  58. for _, v := range c.beforeExecuteHookFunc {
  59. v(c)
  60. }
  61. }
  62. }
  63. func (c *Ctx[T]) beforeDecodeHook() {
  64. if len(c.beforeDecodeHookFunc) > 0 {
  65. for _, v := range c.beforeDecodeHookFunc {
  66. v(c)
  67. }
  68. }
  69. }
  70. func (c *Ctx[T]) validate() (errs gin.H) {
  71. c.Payload = make(gin.H)
  72. _ = c.ctx.ShouldBindJSON(&c.Payload)
  73. errs = validate.ValidateMap(c.Payload, c.rules)
  74. if len(errs) > 0 {
  75. logger.Debug(errs)
  76. for k := range errs {
  77. errs[k] = c.rules[k]
  78. }
  79. return
  80. }
  81. // Make sure that the key in c.Payload is also the key of rules
  82. validated := make(map[string]interface{})
  83. for k, v := range c.Payload {
  84. if _, ok := c.rules[k]; ok {
  85. validated[k] = v
  86. }
  87. }
  88. c.Payload = validated
  89. return
  90. }
  91. func (c *Ctx[T]) SetScan(scan func(tx *gorm.DB) any) *Ctx[T] {
  92. c.scan = scan
  93. return c
  94. }
  95. func (c *Ctx[T]) SetTransformer(t func(m *T) any) *Ctx[T] {
  96. c.transformer = t
  97. return c
  98. }
  99. func (c *Ctx[T]) AbortWithError(err error) {
  100. c.abort = true
  101. errHandler(c.ctx, err)
  102. }
  103. func (c *Ctx[T]) Abort() {
  104. c.abort = true
  105. }
  106. func (c *Ctx[T]) GormScope(hook func(tx *gorm.DB) *gorm.DB) *Ctx[T] {
  107. c.gormScopes = append(c.gormScopes, hook)
  108. return c
  109. }