|
@@ -10,21 +10,31 @@ import (
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm"
|
|
"reflect"
|
|
"reflect"
|
|
|
|
+ "sort"
|
|
"sync"
|
|
"sync"
|
|
|
|
+ "sync/atomic"
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+const (
|
|
|
|
+ TypeModule = "module"
|
|
|
|
+ TypeTable = "table"
|
|
)
|
|
)
|
|
|
|
|
|
type (
|
|
type (
|
|
CRUD struct {
|
|
CRUD struct {
|
|
|
|
+ index int32
|
|
db *gorm.DB
|
|
db *gorm.DB
|
|
entities sync.Map
|
|
entities sync.Map
|
|
httpSvr *http.Server
|
|
httpSvr *http.Server
|
|
httpMiddleware []http.Middleware
|
|
httpMiddleware []http.Middleware
|
|
callback *Callback
|
|
callback *Callback
|
|
|
|
+ moduleLabels map[string]string
|
|
}
|
|
}
|
|
|
|
|
|
treeValue struct {
|
|
treeValue struct {
|
|
- Label string `json:"label"`
|
|
|
|
- Value string `json:"value"`
|
|
|
|
|
|
+ Label string `json:"label"` //标签
|
|
|
|
+ Value string `json:"value"` //值
|
|
|
|
+ Type string `json:"type"` //类型
|
|
Children []*treeValue `json:"children"`
|
|
Children []*treeValue `json:"children"`
|
|
}
|
|
}
|
|
|
|
|
|
@@ -57,22 +67,44 @@ func (crud *CRUD) Callback() *Callback {
|
|
return crud.callback
|
|
return crud.callback
|
|
}
|
|
}
|
|
|
|
|
|
-//handleQueryCrudModules 处理
|
|
|
|
|
|
+//handleQueryCrudModules 获取模块的信息
|
|
func (crud *CRUD) handleQueryCrudModules(ctx *http.Context) (err error) {
|
|
func (crud *CRUD) handleQueryCrudModules(ctx *http.Context) (err error) {
|
|
ts := make([]*treeValue, 0)
|
|
ts := make([]*treeValue, 0)
|
|
|
|
+ entities := make(Entities, 0)
|
|
crud.entities.Range(func(key, value interface{}) bool {
|
|
crud.entities.Range(func(key, value interface{}) bool {
|
|
- e := value.(*Entity)
|
|
|
|
|
|
+ entities = append(entities, value.(*Entity))
|
|
|
|
+ return true
|
|
|
|
+ })
|
|
|
|
+ sort.Sort(entities)
|
|
|
|
+ isHandled := false
|
|
|
|
+ for _, e := range entities {
|
|
|
|
+ isHandled = false
|
|
for _, tv := range ts {
|
|
for _, tv := range ts {
|
|
if tv.Value == e.model.ModuleName() {
|
|
if tv.Value == e.model.ModuleName() {
|
|
- tv.Append(&treeValue{Value: e.model.ModuleName() + "-" + e.model.TableName(), Label: e.model.TableName()})
|
|
|
|
- return true
|
|
|
|
|
|
+ if viewer, ok := e.model.(ModelViewer); ok {
|
|
|
|
+ tv.Append(&treeValue{Value: e.model.ModuleName() + "-" + e.model.TableName(), Label: viewer.TableLabel(), Type: TypeTable})
|
|
|
|
+ } else {
|
|
|
|
+ tv.Append(&treeValue{Value: e.model.ModuleName() + "-" + e.model.TableName(), Label: e.model.TableName(), Type: TypeTable})
|
|
|
|
+ }
|
|
|
|
+ isHandled = true
|
|
|
|
+ break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- tv := &treeValue{Label: e.model.ModuleName(), Value: e.model.ModuleName()}
|
|
|
|
- tv.Append(&treeValue{Value: e.model.ModuleName() + "-" + e.model.TableName(), Label: e.model.TableName()})
|
|
|
|
|
|
+ if isHandled {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ moduleLabel := crud.moduleLabels[e.model.ModuleName()]
|
|
|
|
+ if moduleLabel == "" {
|
|
|
|
+ moduleLabel = e.model.ModuleName()
|
|
|
|
+ }
|
|
|
|
+ tv := &treeValue{Label: moduleLabel, Value: e.model.ModuleName(), Type: TypeModule}
|
|
|
|
+ if viewer, ok := e.model.(ModelViewer); ok {
|
|
|
|
+ tv.Append(&treeValue{Value: e.model.ModuleName() + "-" + e.model.TableName(), Label: viewer.TableLabel(), Type: TypeTable})
|
|
|
|
+ } else {
|
|
|
|
+ tv.Append(&treeValue{Value: e.model.ModuleName() + "-" + e.model.TableName(), Label: e.model.TableName(), Type: TypeTable})
|
|
|
|
+ }
|
|
ts = append(ts, tv)
|
|
ts = append(ts, tv)
|
|
- return true
|
|
|
|
- })
|
|
|
|
|
|
+ }
|
|
return ctx.Success(ts)
|
|
return ctx.Success(ts)
|
|
}
|
|
}
|
|
|
|
|
|
@@ -208,11 +240,13 @@ func (crud *CRUD) Attach(model Model, ops ...Option) (err error) {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
//migrate table schema
|
|
//migrate table schema
|
|
- if err = migrateUp("", model); err != nil {
|
|
|
|
|
|
+ if err = migrateUp(opts.Namespace, model, opts.MigrateOptions); err != nil {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
scenarios := model.Scenario()
|
|
scenarios := model.Scenario()
|
|
|
|
+ atomic.AddInt32(&crud.index, 1)
|
|
entity := newEntity(model, opts)
|
|
entity := newEntity(model, opts)
|
|
|
|
+ entity.index = crud.index
|
|
entity.callback = crud.callback
|
|
entity.callback = crud.callback
|
|
if len(scenarios) == 0 {
|
|
if len(scenarios) == 0 {
|
|
entity.scenarios = []string{ScenarioList, ScenarioCreate, ScenarioUpdate, ScenarioDelete, ScenarioExport, ScenarioView}
|
|
entity.scenarios = []string{ScenarioList, ScenarioCreate, ScenarioUpdate, ScenarioDelete, ScenarioExport, ScenarioView}
|
|
@@ -260,7 +294,9 @@ func (crud *CRUD) Routes(svr *http.Server, ms ...http.Middleware) {
|
|
}
|
|
}
|
|
//注册获取键值对数据格式
|
|
//注册获取键值对数据格式
|
|
if entity.isKvMapping() {
|
|
if entity.isKvMapping() {
|
|
- crud.httpSvr.Handle("GET", entity.getScenarioUrl("mapping"), entity.getScenarioHandle("mapping"), entity.opts.Middleware...)
|
|
|
|
|
|
+ uri = entity.getScenarioUrl("mapping")
|
|
|
|
+ log.Debugf("CRUD: register %s %s", "GET", uri)
|
|
|
|
+ crud.httpSvr.Handle("GET", uri, entity.getScenarioHandle("mapping"), entity.opts.Middleware...)
|
|
}
|
|
}
|
|
return true
|
|
return true
|
|
})
|
|
})
|
|
@@ -286,15 +322,24 @@ func (crud *CRUD) IsNewRecord(value reflect.Value, stmt *gorm.Statement) bool {
|
|
return false
|
|
return false
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// SetModuleLabel 设置模块标签
|
|
|
|
+func (crud *CRUD) SetModuleLabel(moduleName string, moduleLabel string) {
|
|
|
|
+ if crud.moduleLabels == nil {
|
|
|
|
+ crud.moduleLabels = make(map[string]string)
|
|
|
|
+ }
|
|
|
|
+ crud.moduleLabels[moduleName] = moduleLabel
|
|
|
|
+}
|
|
|
|
+
|
|
//NewCRUD 创建一个新的CRUD模型
|
|
//NewCRUD 创建一个新的CRUD模型
|
|
func NewCRUD(db *gorm.DB, svr *http.Server) (crud *CRUD, err error) {
|
|
func NewCRUD(db *gorm.DB, svr *http.Server) (crud *CRUD, err error) {
|
|
if err = initSchema(db); err != nil {
|
|
if err = initSchema(db); err != nil {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
crud = &CRUD{
|
|
crud = &CRUD{
|
|
- db: db,
|
|
|
|
- callback: newCallback(),
|
|
|
|
- httpSvr: svr,
|
|
|
|
|
|
+ db: db,
|
|
|
|
+ callback: newCallback(),
|
|
|
|
+ httpSvr: svr,
|
|
|
|
+ moduleLabels: make(map[string]string),
|
|
}
|
|
}
|
|
return
|
|
return
|
|
}
|
|
}
|
|
@@ -324,8 +369,9 @@ func Dialer(cfg *Config) (crud *CRUD, err error) {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
crud = &CRUD{
|
|
crud = &CRUD{
|
|
- db: db,
|
|
|
|
- callback: newCallback(),
|
|
|
|
|
|
+ db: db,
|
|
|
|
+ moduleLabels: make(map[string]string),
|
|
|
|
+ callback: newCallback(),
|
|
}
|
|
}
|
|
return
|
|
return
|
|
}
|
|
}
|