diff --git a/app/jobs/models/sys_job.go b/app/jobs/models/sys_job.go index a8cc6bf9..9107465a 100644 --- a/app/jobs/models/sys_job.go +++ b/app/jobs/models/sys_job.go @@ -27,11 +27,6 @@ func (*SysJob) TableName() string { return "sys_job" } -func (e *SysJob) Generate() models.ActiveRecord { - o := *e - return &o -} - func (e *SysJob) GetId() interface{} { return e.JobId } diff --git a/app/jobs/router/sys_job.go b/app/jobs/router/sys_job.go index 090be794..3c6d44d5 100644 --- a/app/jobs/router/sys_job.go +++ b/app/jobs/router/sys_job.go @@ -19,17 +19,13 @@ func registerSysJobRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddlew r := v1.Group("/sysjob").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()) { - sysJob := &models2.SysJob{} - r.GET("", actions.PermissionAction(), actions.IndexAction(sysJob, new(dto2.SysJobSearch), func() interface{} { - list := make([]models2.SysJob, 0) - return &list - })) - r.GET("/:id", actions.PermissionAction(), actions.ViewAction(new(dto2.SysJobById), func() interface{} { - return &dto2.SysJobItem{} - })) - r.POST("", actions.CreateAction(new(dto2.SysJobControl))) - r.PUT("", actions.PermissionAction(), actions.UpdateAction(new(dto2.SysJobControl))) - r.DELETE("", actions.PermissionAction(), actions.DeleteAction(new(dto2.SysJobById))) + r.GET("", actions.PermissionAction(), actions.Index[models2.SysJob, dto2.SysJobSearch]()) + // The detail answers SysJobItem, whose entryId the edit form reads; + // the model itself marshals it as entry_id. + r.GET("/:id", actions.PermissionAction(), actions.ViewAs[models2.SysJob, dto2.SysJobById, dto2.SysJobItem]()) + r.POST("", actions.Create[models2.SysJob, dto2.SysJobControl]()) + r.PUT("", actions.PermissionAction(), actions.Update[models2.SysJob, dto2.SysJobControl]()) + r.DELETE("", actions.PermissionAction(), actions.Delete[models2.SysJob, dto2.SysJobById]()) } sysJob := apis.SysJob{} diff --git a/app/jobs/service/dto/sys_job.go b/app/jobs/service/dto/sys_job.go index f342f927..1ab9310f 100644 --- a/app/jobs/service/dto/sys_job.go +++ b/app/jobs/service/dto/sys_job.go @@ -6,7 +6,6 @@ import ( "go-admin/app/jobs/models" "go-admin/common/dto" - common "go-admin/common/models" ) type SysJobSearch struct { @@ -32,11 +31,6 @@ func (m *SysJobSearch) Bind(ctx *gin.Context) error { return err } -func (m *SysJobSearch) Generate() dto.Index { - o := *m - return &o -} - type SysJobControl struct { JobId int `json:"jobId"` JobName string `json:"jobName" validate:"required"` // 名称 @@ -55,12 +49,7 @@ func (s *SysJobControl) Bind(ctx *gin.Context) error { return ctx.ShouldBind(s) } -func (s *SysJobControl) Generate() dto.Control { - cp := *s - return &cp -} - -func (s *SysJobControl) GenerateM() (common.ActiveRecord, error) { +func (s *SysJobControl) ToModel() (*models.SysJob, error) { return &models.SysJob{ JobId: s.JobId, JobName: s.JobName, @@ -76,23 +65,10 @@ func (s *SysJobControl) GenerateM() (common.ActiveRecord, error) { }, nil } -func (s *SysJobControl) GetId() interface{} { - return s.JobId -} - type SysJobById struct { dto.ObjectById } -func (s *SysJobById) Generate() dto.Control { - cp := *s - return &cp -} - -func (s *SysJobById) GenerateM() (common.ActiveRecord, error) { - return &models.SysJob{}, nil -} - type SysJobItem struct { JobId int `json:"jobId"` JobName string `json:"jobName" validate:"required"` // 名称 diff --git a/common/actions/generic_compile_test.go b/common/actions/generic_compile_test.go new file mode 100644 index 00000000..d9838bc6 --- /dev/null +++ b/common/actions/generic_compile_test.go @@ -0,0 +1,36 @@ +package actions_test + +import ( + "os/exec" + "path/filepath" + "strings" + "testing" +) + +// A model paired with a request that builds a different model does not +// compile - the thing the older actions left to a type assertion at run +// time. Checked by building a package that does it, next to a control that +// is the same package with the pair corrected. +func TestGenericActionsRefuseAMismatchedPair(t *testing.T) { + root, err := filepath.Abs("../..") + if err != nil { + t.Fatal(err) + } + vet := func(pkg string) (string, error) { + cmd := exec.Command("go", "vet", "./common/actions/testdata/"+pkg) + cmd.Dir = root + out, err := cmd.CombinedOutput() + return string(out), err + } + + if out, err := vet("matched"); err != nil { + t.Fatalf("the control does not build, so the mismatch below proves nothing:\n%s", out) + } + out, err := vet("mismatch") + if err == nil { + t.Fatal("a model paired with another model's request compiled") + } + if !strings.Contains(out, "does not satisfy") || !strings.Contains(out, "ToModel") { + t.Fatalf("the build failed, but not on the pairing:\n%s", out) + } +} diff --git a/common/actions/testdata/matched/matched.go b/common/actions/testdata/matched/matched.go new file mode 100644 index 00000000..64d80265 --- /dev/null +++ b/common/actions/testdata/matched/matched.go @@ -0,0 +1,11 @@ +// Package matched is mismatch with the pair corrected: the control that +// shows mismatch fails for the pairing, not for how it is built. +package matched + +import ( + "go-admin/app/demo/models" + "go-admin/app/demo/service/dto" + "go-admin/common/actions" +) + +var _ = actions.Create[models.DemoProduct, dto.DemoProductControl] diff --git a/common/actions/testdata/mismatch/mismatch.go b/common/actions/testdata/mismatch/mismatch.go new file mode 100644 index 00000000..99eac73d --- /dev/null +++ b/common/actions/testdata/mismatch/mismatch.go @@ -0,0 +1,12 @@ +// Package mismatch pairs a model with another model's request, which must +// not compile. TestGenericActionsRefuseAMismatchedPair builds it and expects +// the build to fail; testdata keeps it out of ./... . +package mismatch + +import ( + "go-admin/app/demo/models" + jobdto "go-admin/app/jobs/service/dto" + "go-admin/common/actions" +) + +var _ = actions.Create[models.DemoProduct, jobdto.SysJobControl]