[feat] 新增 Operation 按钮支持

This commit is contained in:
what 2024-05-07 10:16:25 +08:00
parent 6b87809781
commit 69efb787bb

View File

@ -3,19 +3,79 @@ package support
import (
"encoding/json"
"reflect"
"strings"
"git.fsdpf.net/go/contracts"
"git.fsdpf.net/go/db"
"github.com/samber/do"
"github.com/samber/lo"
"github.com/spf13/cast"
)
type Operation struct {
Uuid string `json:"uuid"`
Name string `json:"name"`
Code string `json:"code"`
Icon string `json:"icon"`
Size string `json:"size"`
Block bool `json:"block"`
Ghost bool `json:"ghost"`
Shape string `json:"shape"`
Type string `json:"type"`
PopConfirm any `json:"popConfirm,omitempty"`
Widget string `json:"widget"`
WidgetType string `json:"widgetType"`
WidgetProps any `json:"widgetProps"`
WidgetSetting any `json:"widgetSetting"`
WidgetContainerSetting any `json:"widgetContainerSetting"`
IsRefresh int `json:"isRefresh"`
NoAuthType string `json:"noAuthType"`
Roles []string `json:"-"`
Children []Operation `json:"children,omitempty"`
AccessCondition contracts.Condition `json:"-"`
}
type OperationAccess struct {
typ reflect.Kind // 只能为 reflect.Int 和 reflect.String
data map[string][]any
}
func (this OperationAccess) Get(k string) []any {
items, ok := this.data[k]
func (o Operation) ToDBColumn(model contracts.Model, container *do.Injector) (column db.Expression, field reflect.StructField) {
GetOrmConditionByRes := do.MustInvoke[contracts.GetOrmConditionByRes](container)
NewOrmCondition := do.MustInvoke[contracts.NewOrmCondition](container)
uuid := strings.ReplaceAll(o.Uuid, "-", "_")
// 主键
pk := model.GetCode() + "." + model.GetPrimaryKey()
cond := lo.Ternary(o.AccessCondition != nil, o.AccessCondition, NewOrmCondition(contracts.ConditionType_AND, "operation access condition "+uuid))
if c := GetOrmConditionByRes(o.Uuid, "operation access condition "+uuid); c.IsNotEmpty() {
cond.SetCondition(c)
}
if cond.IsEmpty() {
column = db.Raw(pk + " as `u_" + uuid + "`")
} else {
column = db.Raw("if(" + string(cond.ToSql(model)) + ", " + pk + ", 0) as `u_" + uuid + "`")
}
// 主键类型
tPkType := reflect.TypeOf("")
if tPk, ok := GetStructField(model.GetQueryFieldsStruct(), model.GetPrimaryKey()); ok {
tPkType = tPk.Type
}
field = reflect.StructField{
Name: "U_" + uuid,
Tag: reflect.StructTag(`db:"u_` + uuid + `"`),
Type: tPkType,
}
return column, field
}
func (oa OperationAccess) Get(k string) []any {
items, ok := oa.data[k]
if !ok {
return nil
@ -24,49 +84,49 @@ func (this OperationAccess) Get(k string) []any {
return items
}
func (this *OperationAccess) Set(k string, v []any) error {
this.data[k] = []any{}
return this.Push(k, v...)
func (oa *OperationAccess) Set(k string, v []any) error {
oa.data[k] = []any{}
return oa.Push(k, v...)
}
func (this *OperationAccess) Push(k string, ids ...any) error {
if _, ok := this.data[k]; !ok {
this.Set(k, []any{})
func (oa *OperationAccess) Push(k string, ids ...any) error {
if _, ok := oa.data[k]; !ok {
oa.Set(k, []any{})
}
for i := 0; i < len(ids); i++ {
if v, err := this.Convert(ids[i]); err != nil {
if v, err := oa.Convert(ids[i]); err != nil {
return err
} else if !lo.Contains(this.data[k], v) {
this.data[k] = append(this.data[k], v)
} else if !lo.Contains(oa.data[k], v) {
oa.data[k] = append(oa.data[k], v)
}
}
return nil
}
func (this OperationAccess) Merge(item OperationAccess) error {
func (oa OperationAccess) Merge(item OperationAccess) error {
for k, v := range item.data {
this.Push(k, v...)
oa.Push(k, v...)
}
return nil
}
func (this OperationAccess) Convert(v any) (any, error) {
if this.typ == reflect.Int {
func (oa OperationAccess) Convert(v any) (any, error) {
if oa.typ == reflect.Int {
return cast.ToIntE(v)
}
return cast.ToStringE(v)
}
func (this OperationAccess) Exist(k string, v any) bool {
items, ok := this.data[k]
func (oa OperationAccess) Exist(k string, v any) bool {
items, ok := oa.data[k]
if !ok {
return false
}
flag, err := this.Convert(v)
flag, err := oa.Convert(v)
if err != nil {
return false
@ -75,10 +135,10 @@ func (this OperationAccess) Exist(k string, v any) bool {
return lo.Contains(items, flag)
}
func (this OperationAccess) MarshalJSON() ([]byte, error) {
func (oa OperationAccess) MarshalJSON() ([]byte, error) {
temp := [][2]any{}
for k, v := range this.data {
for k, v := range oa.data {
temp = append(temp, [2]any{k, v})
}