All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
114 lines
2.4 KiB
Go
114 lines
2.4 KiB
Go
package datatable
|
|
|
|
import (
|
|
"cargo-erp-backend/internal/handlers/dto"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
var allowedDirections = map[string]bool{
|
|
"ASC": true,
|
|
"DESC": true,
|
|
}
|
|
|
|
type DatatableInterface interface {
|
|
Render(coldef []dto.DataTableColDef) dto.DataTableResponse
|
|
}
|
|
type Datatable struct {
|
|
DB *gorm.DB
|
|
Req dto.DataTableRequest
|
|
}
|
|
|
|
func NewDatatable(db *gorm.DB, table_request dto.DataTableRequest) DatatableInterface {
|
|
return &Datatable{
|
|
DB: db,
|
|
Req: table_request,
|
|
}
|
|
}
|
|
func (d *Datatable) SetTable(db *gorm.DB) {
|
|
d.DB = db
|
|
}
|
|
func (d *Datatable) Render(coldef []dto.DataTableColDef) dto.DataTableResponse {
|
|
var totaldata int64 = 0
|
|
d.DB.Count(&totaldata)
|
|
//select
|
|
selectAlias := make([]string, 0)
|
|
for _, v := range coldef {
|
|
selectAlias = append(selectAlias, fmt.Sprintf("%v AS %v", v.Field, v.Alias))
|
|
}
|
|
d.DB.Select(selectAlias)
|
|
//global filter
|
|
if len(d.Req.Search.Value) > 0 {
|
|
g := d.DB.Session(&gorm.Session{})
|
|
for _, vcol := range d.Req.Columns {
|
|
if vcol.Searchable {
|
|
for _, v := range coldef {
|
|
if v.Alias == vcol.Data {
|
|
g = g.Or(fmt.Sprintf("%v::TEXT ILIKE ?", v.Field), "%"+d.Req.Search.Value+"%")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
d.DB.Where(g)
|
|
}
|
|
//order
|
|
if len(d.Req.Order) > 0 {
|
|
for _, vOrder := range d.Req.Order {
|
|
dir := strings.ToUpper(vOrder.Dir)
|
|
if !allowedDirections[dir] {
|
|
dir = "ASC"
|
|
}
|
|
for _, vcol := range d.Req.Columns {
|
|
if vcol.Orderable && vOrder.Column == vcol.Data {
|
|
for _, v := range coldef {
|
|
if v.Alias == vcol.Data {
|
|
d.DB.Order(fmt.Sprintf("%v %v", v.Field, dir))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//additional filter
|
|
if len(d.Req.AdditionalFilter) > 0 {
|
|
for k, vFilter := range d.Req.AdditionalFilter {
|
|
for _, v := range coldef {
|
|
if v.Alias == k {
|
|
d.DB.Where(fmt.Sprintf("%v=?", v.Field), vFilter)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var totalFiltered int64 = 0
|
|
d.DB.Count(&totalFiltered)
|
|
start := d.Req.Start
|
|
if start == 0 {
|
|
start = 1
|
|
}
|
|
limit := d.Req.Length
|
|
d.DB.Limit(limit).Offset(start*limit - limit)
|
|
output := make([]map[string]interface{}, 0)
|
|
d.DB.Scan(&output)
|
|
for _, voutput := range output {
|
|
for kv, vv := range voutput {
|
|
for _, v := range coldef {
|
|
if v.Alias == kv {
|
|
if v.Formatter != nil {
|
|
voutput[kv] = v.Formatter(voutput, vv)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
result := dto.DataTableResponse{
|
|
Draw: 1,
|
|
RecordsTotal: totaldata,
|
|
RecordsFiltered: totalFiltered,
|
|
Data: output,
|
|
}
|
|
return result
|
|
}
|