2024-05-06 13:43:35 +08:00
|
|
|
package support
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"reflect"
|
2024-05-07 10:16:25 +08:00
|
|
|
"strings"
|
2024-05-06 13:43:35 +08:00
|
|
|
|
|
|
|
"git.fsdpf.net/go/contracts"
|
2024-05-07 10:16:25 +08:00
|
|
|
"git.fsdpf.net/go/db"
|
|
|
|
"github.com/samber/do"
|
2024-05-06 14:27:16 +08:00
|
|
|
"github.com/samber/lo"
|
2024-05-06 13:43:35 +08:00
|
|
|
"github.com/spf13/cast"
|
|
|
|
)
|
|
|
|
|
2024-05-07 10:16:25 +08:00
|
|
|
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:"-"`
|
|
|
|
}
|
|
|
|
|
2024-05-06 13:43:35 +08:00
|
|
|
type OperationAccess struct {
|
|
|
|
typ reflect.Kind // 只能为 reflect.Int 和 reflect.String
|
|
|
|
data map[string][]any
|
|
|
|
}
|
|
|
|
|
2024-05-07 10:16:25 +08:00
|
|
|
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]
|
2024-05-06 13:43:35 +08:00
|
|
|
|
|
|
|
if !ok {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return items
|
|
|
|
}
|
|
|
|
|
2024-05-07 10:16:25 +08:00
|
|
|
func (oa *OperationAccess) Set(k string, v []any) error {
|
|
|
|
oa.data[k] = []any{}
|
|
|
|
return oa.Push(k, v...)
|
2024-05-06 13:43:35 +08:00
|
|
|
}
|
|
|
|
|
2024-05-07 10:16:25 +08:00
|
|
|
func (oa *OperationAccess) Push(k string, ids ...any) error {
|
|
|
|
if _, ok := oa.data[k]; !ok {
|
|
|
|
oa.Set(k, []any{})
|
2024-05-06 13:43:35 +08:00
|
|
|
}
|
|
|
|
|
2024-05-06 15:41:33 +08:00
|
|
|
for i := 0; i < len(ids); i++ {
|
2024-05-07 10:16:25 +08:00
|
|
|
if v, err := oa.Convert(ids[i]); err != nil {
|
2024-05-06 13:43:35 +08:00
|
|
|
return err
|
2024-05-07 10:16:25 +08:00
|
|
|
} else if !lo.Contains(oa.data[k], v) {
|
|
|
|
oa.data[k] = append(oa.data[k], v)
|
2024-05-06 13:43:35 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-05-07 10:16:25 +08:00
|
|
|
func (oa OperationAccess) Merge(item OperationAccess) error {
|
2024-05-06 14:27:16 +08:00
|
|
|
for k, v := range item.data {
|
2024-05-07 10:16:25 +08:00
|
|
|
oa.Push(k, v...)
|
2024-05-06 14:27:16 +08:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-05-07 10:16:25 +08:00
|
|
|
func (oa OperationAccess) Convert(v any) (any, error) {
|
|
|
|
if oa.typ == reflect.Int {
|
2024-05-06 13:43:35 +08:00
|
|
|
return cast.ToIntE(v)
|
|
|
|
}
|
|
|
|
return cast.ToStringE(v)
|
|
|
|
}
|
|
|
|
|
2024-05-07 10:16:25 +08:00
|
|
|
func (oa OperationAccess) Exist(k string, v any) bool {
|
|
|
|
items, ok := oa.data[k]
|
2024-05-06 13:43:35 +08:00
|
|
|
|
|
|
|
if !ok {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2024-05-07 10:16:25 +08:00
|
|
|
flag, err := oa.Convert(v)
|
2024-05-06 13:43:35 +08:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2024-05-06 14:27:16 +08:00
|
|
|
return lo.Contains(items, flag)
|
2024-05-06 13:43:35 +08:00
|
|
|
}
|
|
|
|
|
2024-05-07 10:16:25 +08:00
|
|
|
func (oa OperationAccess) MarshalJSON() ([]byte, error) {
|
2024-05-06 13:43:35 +08:00
|
|
|
temp := [][2]any{}
|
|
|
|
|
2024-05-07 10:16:25 +08:00
|
|
|
for k, v := range oa.data {
|
2024-05-06 13:43:35 +08:00
|
|
|
temp = append(temp, [2]any{k, v})
|
|
|
|
}
|
|
|
|
|
|
|
|
return json.Marshal(temp)
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewOperationAccess(m contracts.Model) OperationAccess {
|
|
|
|
// 主键类型
|
|
|
|
tPkType := reflect.String
|
|
|
|
|
|
|
|
if tPk, ok := GetStructField(m.GetQueryFieldsStruct(), m.GetPrimaryKey()); ok {
|
|
|
|
switch tPk.Type.Kind() {
|
|
|
|
case reflect.Int, reflect.Int32, reflect.Int64,
|
|
|
|
reflect.Uint, reflect.Uint32, reflect.Uint64:
|
|
|
|
tPkType = reflect.Int
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return OperationAccess{typ: tPkType, data: map[string][]any{}}
|
|
|
|
}
|