wms-be/modules/menu/query/menu_query.go

94 lines
2.4 KiB
Go

package query
import (
"github.com/Caknoooo/go-gin-clean-starter/database/entities"
"github.com/Caknoooo/go-pagination"
"github.com/google/uuid"
"gorm.io/gorm"
)
type M_Menu struct {
ID uuid.UUID `json:"id" gorm:"column:id"`
Name string `json:"name" gorm:"column:name"`
IconUrl string `json:"icon_url,omitempty" gorm:"column:icon_url"`
Sequence int `json:"sequence,omitempty" gorm:"column:sequence"`
Url string `json:"url,omitempty" gorm:"column:url"`
Mode string `json:"mode,omitempty" gorm:"column:mode"`
Status string `json:"status,omitempty" gorm:"column:status"`
ParentID *uuid.UUID `json:"parent_id,omitempty" gorm:"column:parent_id"`
Parent *M_Menu `json:"parent,omitempty" gorm:"foreignKey:ParentID;references:ID"`
}
// MenuFilter defines filterable fields and includes for paginated menu queries.
type MenuFilter struct {
pagination.BaseFilter
Name string `form:"name"`
ParentID string `form:"parent_id"`
ClientID string `form:"client_id"`
Includes []string `form:"includes"`
}
func (f *MenuFilter) ApplyFilters(q *gorm.DB) *gorm.DB {
if f.Name != "" {
q = q.Where("name ILIKE ?", "%"+f.Name+"%")
}
if f.ParentID != "" {
q = q.Where("parent_id = ?", f.ParentID)
}
if f.ClientID != "" {
q = q.Where("client_id = ?", f.ClientID)
}
// allow selective preloads for performance
for _, include := range f.Includes {
if include == "Parent" {
// q = q.Model(entities.M_Menu{}).Preload("Parent", func(db *gorm.DB) *gorm.DB {
// return db.Select("id", "name")
// })
q = q.Model(entities.M_Menu{}).Preload("Parent", func(db *gorm.DB) *gorm.DB {
return db.Select("m_menus.id", "m_menus.name")
})
}
}
return q
}
func (f *MenuFilter) GetTableName() string {
return "m_menus"
}
func (f *MenuFilter) GetSearchFields() []string {
return []string{"name"}
}
func (f *MenuFilter) GetDefaultSort() string {
return "id asc"
}
func (f *MenuFilter) GetIncludes() []string {
return f.Includes
}
func (f *MenuFilter) GetPagination() pagination.PaginationRequest {
return f.Pagination
}
func (f *MenuFilter) Validate() {
var validIncludes []string
allowedIncludes := f.GetAllowedIncludes()
for _, include := range f.Includes {
if allowedIncludes[include] {
validIncludes = append(validIncludes, include)
}
}
f.Includes = validIncludes
}
func (f *MenuFilter) GetAllowedIncludes() map[string]bool {
return map[string]bool{
"Parent": true,
"Children": true,
}
}