From d53c8abc6c963d5e18d38d4fadc13e9509f8c4e2 Mon Sep 17 00:00:00 2001 From: zhangwenjian Date: Fri, 25 Sep 2026 19:59:59 +0800 Subject: [PATCH] =?UTF-8?q?fix=F0=9F=90=9B:=20generate=20a=20model=20and?= =?UTF-8?q?=20DTOs=20for=20any=20single-column=20primary=20key?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The model and DTO templates assumed every table's key is an int column named id. For any other key the generated backend did not compile - the model embedded models.Model, which supplies Id, skipped the real key column, and GetId then returned a field that did not exist ("e.Code undefined"). Past the compile error there was more of the same assumption: - GetReq and UpdateReq bound the key with uri:"", while every generated router registers it as :id, so any other name bound nothing; - InsertReq tagged the key json:"-", so a key the database does not assign, such as a string, could never be supplied; - DeleteReq took Ids []int, so a string key could not be deleted. models.Model now stands in for the key only when the key is exactly an int named Id; anything else is declared as its own primaryKey field. The key is bound from :id, accepted from the request body when it is not an int, and deleted by a list of its own type. A table keyed on an int id renders byte-for-byte as before. --- template/v4/dto.go.template | 21 +++++++++++++++++---- template/v4/model.go.template | 13 +++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/template/v4/dto.go.template b/template/v4/dto.go.template index 428b89ae..7619b066 100644 --- a/template/v4/dto.go.template +++ b/template/v4/dto.go.template @@ -1,6 +1,13 @@ package dto import ( + {{- /* + $embed: the key is models.Model's own Id, so the model embeds it. + $pkType: the key's Go type, for the delete request's id list. + */ -}} + {{- $embed := false -}} + {{- $pkType := "int" -}} + {{- range .Columns -}}{{- if .Pk -}}{{- $pkType = .GoType -}}{{- if and (eq .GoField "Id") (eq .GoType "int") -}}{{- $embed = true -}}{{- end -}}{{- end -}}{{- end -}} {{- $bb := false -}} {{- range .Columns -}} {{- $z := .IsQuery -}} @@ -52,7 +59,7 @@ type {{.ClassName}}InsertReq struct { {{- range .Columns -}} {{$x := .Pk}} {{- if ($x) }} - {{.GoField}} {{.GoType}} `json:"-" comment:"{{.ColumnComment}}"` // {{.ColumnComment}} + {{.GoField}} {{.GoType}} `json:"{{if eq .GoType "int"}}-{{else}}{{.JsonField}}{{end}}" comment:"{{.ColumnComment}}"` // {{.ColumnComment}} {{- else if eq .GoField "CreatedAt" -}} {{- else if eq .GoField "UpdatedAt" -}} {{- else if eq .GoField "DeletedAt" -}} @@ -69,9 +76,13 @@ func (s *{{.ClassName}}InsertReq) Generate(model *models.{{.ClassName}}) { {{- range .Columns -}} {{$x := .Pk}} {{- if ($x) }} + {{- if $embed }} if s.{{.GoField}} == 0 { model.Model = common.Model{ {{.GoField}}: s.{{.GoField}} } } + {{- else }} + model.{{.GoField}} = s.{{.GoField}} + {{- end }} {{- else if eq .GoField "CreatedAt" -}} {{- else if eq .GoField "UpdatedAt" -}} {{- else if eq .GoField "DeletedAt" -}} @@ -92,7 +103,7 @@ type {{.ClassName}}UpdateReq struct { {{- range .Columns -}} {{$x := .Pk}} {{- if ($x) }} - {{.GoField}} {{.GoType}} `uri:"{{.JsonField}}" comment:"{{.ColumnComment}}"` // {{.ColumnComment}} + {{.GoField}} {{.GoType}} `uri:"id" comment:"{{.ColumnComment}}"` // {{.ColumnComment}} {{- else if eq .GoField "CreatedAt" -}} {{- else if eq .GoField "UpdatedAt" -}} {{- else if eq .GoField "DeletedAt" -}} @@ -109,9 +120,11 @@ func (s *{{.ClassName}}UpdateReq) Generate(model *models.{{.ClassName}}) { {{- range .Columns -}} {{$x := .Pk}} {{- if ($x) }} + {{- if $embed }} if s.{{.GoField}} == 0 { model.Model = common.Model{ {{.GoField}}: s.{{.GoField}} } } + {{- end }} {{- else if eq .GoField "CreatedAt" -}} {{- else if eq .GoField "UpdatedAt" -}} {{- else if eq .GoField "DeletedAt" -}} @@ -133,7 +146,7 @@ type {{.ClassName}}GetReq struct { {{- range .Columns -}} {{$x := .Pk}} {{- if ($x) }} - {{.GoField}} {{.GoType}} `uri:"{{.JsonField}}"` + {{.GoField}} {{.GoType}} `uri:"id"` {{- end }} {{- end }} } @@ -143,7 +156,7 @@ func (s *{{.ClassName}}GetReq) GetId() interface{} { // {{.ClassName}}DeleteReq 功能删除请求参数 type {{.ClassName}}DeleteReq struct { - Ids []int `json:"ids"` + Ids []{{$pkType}} `json:"ids"` } func (s *{{.ClassName}}DeleteReq) GetId() interface{} { diff --git a/template/v4/model.go.template b/template/v4/model.go.template index 2f56123d..ad8f4360 100644 --- a/template/v4/model.go.template +++ b/template/v4/model.go.template @@ -24,11 +24,24 @@ import ( ) +{{/* + models.Model supplies an int primary key named Id, so it stands in for the + key column only when that is exactly the key the table has. Any other key - + a different name, or a string - is declared as its own field, or GetId below + would name a field that does not exist. +*/ -}} +{{- $embed := false -}} +{{- range .Columns -}}{{- if and .Pk (eq .GoField "Id") (eq .GoType "int") -}}{{- $embed = true -}}{{- end -}}{{- end -}} type {{.ClassName}} struct { + {{- if $embed }} models.Model + {{- end }} {{ range .Columns -}} {{$x := .Pk}} {{- if ($x) }} + {{- if not $embed }} + {{.GoField}} {{.GoType}} `json:"{{.JsonField}}" gorm:"primaryKey;type:{{.ColumnType}};comment:{{- if eq .ColumnComment "" -}}{{.GoField}}{{- else -}}{{.ColumnComment}}{{end -}}"` + {{- end }} {{- else if eq .GoField "CreatedAt" -}} {{- else if eq .GoField "UpdatedAt" -}} {{- else if eq .GoField "DeletedAt" -}}