后端重构

This commit is contained in:
Yvan
2026-01-14 14:34:49 +08:00
parent f5f77b32fe
commit 30842b42e5
274 changed files with 39754 additions and 1005 deletions
+251
View File
@@ -0,0 +1,251 @@
package {{.Package}}
import (
{{if not .OnlyTemplate}}
"{{.Module}}/pkg/response"
"{{.Module}}/internal/biz/{{.Package}}"
model "{{.Module}}/internal/data/model/{{.Package}}"
{{- if not .IsTree}}
{{.Package}}Req "{{.Module}}/internal/service/types/{{.Package}}/request"
{{- end }}
"github.com/gin-gonic/gin"
"github.com/go-kratos/kratos/v2/log"
{{- if .AutoCreateResource}}
"{{.Module}}/pkg/utils"
{{- end }}
{{- else}}
"{{.Module}}/pkg/response"
"github.com/gin-gonic/gin"
{{- end}}
)
type {{.StructName}}Handler struct {
uc *{{.Package}}.{{.StructName}}Usecase
log *log.Helper
}
func New{{.StructName}}Handler(uc *{{.Package}}.{{.StructName}}Usecase, logger log.Logger) *{{.StructName}}Handler {
return &{{.StructName}}Handler{
uc: uc,
log: log.NewHelper(logger),
}
}
{{if not .OnlyTemplate}}
// Create{{.StructName}} 创建{{.Description}}
// @Tags {{.StructName}}
// @Summary 创建{{.Description}}
// @Security ApiKeyAuth
// @Accept application/json
// @Produce application/json
// @Param data body model.{{.StructName}} true "创建{{.Description}}"
// @Success 200 {object} response.Response{msg=string} "创建成功"
// @Router /{{.Abbreviation}}/create{{.StructName}} [post]
func (h *{{.StructName}}Handler) Create{{.StructName}}(c *gin.Context) {
ctx := c.Request.Context()
var {{.Abbreviation}} model.{{.StructName}}
if err := c.ShouldBindJSON(&{{.Abbreviation}}); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
{{- if .AutoCreateResource }}
{{.Abbreviation}}.CreatedBy = utils.GetUserID(c)
{{- end }}
if err := h.uc.Create(ctx, &{{.Abbreviation}}); err != nil {
h.log.WithContext(ctx).Errorf("创建失败: %v", err)
response.FailWithMessage("创建失败: "+err.Error(), c)
return
}
response.OkWithMessage("创建成功", c)
}
// Delete{{.StructName}} 删除{{.Description}}
// @Tags {{.StructName}}
// @Summary 删除{{.Description}}
// @Security ApiKeyAuth
// @Accept application/json
// @Produce application/json
// @Param data body model.{{.StructName}} true "删除{{.Description}}"
// @Success 200 {object} response.Response{msg=string} "删除成功"
// @Router /{{.Abbreviation}}/delete{{.StructName}} [delete]
func (h *{{.StructName}}Handler) Delete{{.StructName}}(c *gin.Context) {
ctx := c.Request.Context()
{{.PrimaryField.FieldJson}} := c.Query("{{.PrimaryField.FieldJson}}")
{{- if .AutoCreateResource }}
userID := utils.GetUserID(c)
{{- end }}
if err := h.uc.Delete(ctx, {{.PrimaryField.FieldJson}}{{- if .AutoCreateResource -}}, userID{{- end -}}); err != nil {
h.log.WithContext(ctx).Errorf("删除失败: %v", err)
response.FailWithMessage("删除失败: "+err.Error(), c)
return
}
response.OkWithMessage("删除成功", c)
}
// Delete{{.StructName}}ByIds 批量删除{{.Description}}
// @Tags {{.StructName}}
// @Summary 批量删除{{.Description}}
// @Security ApiKeyAuth
// @Accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{msg=string} "批量删除成功"
// @Router /{{.Abbreviation}}/delete{{.StructName}}ByIds [delete]
func (h *{{.StructName}}Handler) Delete{{.StructName}}ByIds(c *gin.Context) {
ctx := c.Request.Context()
{{.PrimaryField.FieldJson}}s := c.QueryArray("{{.PrimaryField.FieldJson}}s[]")
{{- if .AutoCreateResource }}
userID := utils.GetUserID(c)
{{- end }}
if err := h.uc.DeleteByIds(ctx, {{.PrimaryField.FieldJson}}s{{- if .AutoCreateResource }}, userID{{- end }}); err != nil {
h.log.WithContext(ctx).Errorf("批量删除失败: %v", err)
response.FailWithMessage("批量删除失败: "+err.Error(), c)
return
}
response.OkWithMessage("批量删除成功", c)
}
// Update{{.StructName}} 更新{{.Description}}
// @Tags {{.StructName}}
// @Summary 更新{{.Description}}
// @Security ApiKeyAuth
// @Accept application/json
// @Produce application/json
// @Param data body model.{{.StructName}} true "更新{{.Description}}"
// @Success 200 {object} response.Response{msg=string} "更新成功"
// @Router /{{.Abbreviation}}/update{{.StructName}} [put]
func (h *{{.StructName}}Handler) Update{{.StructName}}(c *gin.Context) {
ctx := c.Request.Context()
var {{.Abbreviation}} model.{{.StructName}}
if err := c.ShouldBindJSON(&{{.Abbreviation}}); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
{{- if .AutoCreateResource }}
{{.Abbreviation}}.UpdatedBy = utils.GetUserID(c)
{{- end }}
if err := h.uc.Update(ctx, &{{.Abbreviation}}); err != nil {
h.log.WithContext(ctx).Errorf("更新失败: %v", err)
response.FailWithMessage("更新失败: "+err.Error(), c)
return
}
response.OkWithMessage("更新成功", c)
}
// Find{{.StructName}} 用id查询{{.Description}}
// @Tags {{.StructName}}
// @Summary 用id查询{{.Description}}
// @Security ApiKeyAuth
// @Accept application/json
// @Produce application/json
// @Param {{.PrimaryField.FieldJson}} query {{.PrimaryField.FieldType}} true "用id查询{{.Description}}"
// @Success 200 {object} response.Response{data=model.{{.StructName}},msg=string} "查询成功"
// @Router /{{.Abbreviation}}/find{{.StructName}} [get]
func (h *{{.StructName}}Handler) Find{{.StructName}}(c *gin.Context) {
ctx := c.Request.Context()
{{.PrimaryField.FieldJson}} := c.Query("{{.PrimaryField.FieldJson}}")
re{{.Abbreviation}}, err := h.uc.FindByID(ctx, {{.PrimaryField.FieldJson}})
if err != nil {
h.log.WithContext(ctx).Errorf("查询失败: %v", err)
response.FailWithMessage("查询失败: "+err.Error(), c)
return
}
response.OkWithData(re{{.Abbreviation}}, c)
}
{{- if .IsTree }}
// Get{{.StructName}}List 分页获取{{.Description}}列表,Tree模式下不接受参数
// @Tags {{.StructName}}
// @Summary 分页获取{{.Description}}列表
// @Security ApiKeyAuth
// @Accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "获取成功"
// @Router /{{.Abbreviation}}/get{{.StructName}}List [get]
func (h *{{.StructName}}Handler) Get{{.StructName}}List(c *gin.Context) {
ctx := c.Request.Context()
list, err := h.uc.List(ctx)
if err != nil {
h.log.WithContext(ctx).Errorf("获取失败: %v", err)
response.FailWithMessage("获取失败: "+err.Error(), c)
return
}
response.OkWithDetailed(list, "获取成功", c)
}
{{- else }}
// Get{{.StructName}}List 分页获取{{.Description}}列表
// @Tags {{.StructName}}
// @Summary 分页获取{{.Description}}列表
// @Security ApiKeyAuth
// @Accept application/json
// @Produce application/json
// @Param data query {{.Package}}Req.{{.StructName}}Search true "分页获取{{.Description}}列表"
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "获取成功"
// @Router /{{.Abbreviation}}/get{{.StructName}}List [get]
func (h *{{.StructName}}Handler) Get{{.StructName}}List(c *gin.Context) {
ctx := c.Request.Context()
var pageInfo {{.Package}}Req.{{.StructName}}Search
if err := c.ShouldBindQuery(&pageInfo); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
list, total, err := h.uc.List(ctx, &pageInfo)
if err != nil {
h.log.WithContext(ctx).Errorf("获取失败: %v", err)
response.FailWithMessage("获取失败: "+err.Error(), c)
return
}
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
}
{{- end }}
{{- if .HasDataSource }}
// Get{{.StructName}}DataSource 获取{{.StructName}}的数据源
// @Tags {{.StructName}}
// @Summary 获取{{.StructName}}的数据源
// @Accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=object,msg=string} "查询成功"
// @Router /{{.Abbreviation}}/get{{.StructName}}DataSource [get]
func (h *{{.StructName}}Handler) Get{{.StructName}}DataSource(c *gin.Context) {
ctx := c.Request.Context()
dataSource, err := h.uc.GetDataSource(ctx)
if err != nil {
h.log.WithContext(ctx).Errorf("查询失败: %v", err)
response.FailWithMessage("查询失败: "+err.Error(), c)
return
}
response.OkWithData(dataSource, c)
}
{{- end }}
{{- end }}
// Get{{.StructName}}Public 不需要鉴权的{{.Description}}接口
// @Tags {{.StructName}}
// @Summary 不需要鉴权的{{.Description}}接口
// @Accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=object,msg=string} "获取成功"
// @Router /{{.Abbreviation}}/get{{.StructName}}Public [get]
func (h *{{.StructName}}Handler) Get{{.StructName}}Public(c *gin.Context) {
ctx := c.Request.Context()
h.uc.GetPublic(ctx)
response.OkWithDetailed(gin.H{
"info": "不需要鉴权的{{.Description}}接口信息",
}, "获取成功", c)
}
+12
View File
@@ -0,0 +1,12 @@
{{- if .IsAdd }}
// 请在 {{.Package}} 包的 enter.go 文件中的 ProviderSet 添加以下内容:
// New{{.StructName}}Handler,
{{- else }}
package {{ .Package }}
import "github.com/google/wire"
// ProviderSet is {{.Package}} handler providers.
// 包含 {{.Description}} 相关的 HTTP 处理器
var ProviderSet = wire.NewSet(New{{.StructName}}Handler)
{{- end }}
+217
View File
@@ -0,0 +1,217 @@
{{- if .IsAdd}}
// 在 {{.StructName}}Repo 接口中新增如下方法
// 请根据实际需求添加
{{- else}}
package {{.Package}}
import (
{{- if not .OnlyTemplate }}
"context"
{{- if .IsTree }}
"errors"
{{- end }}
"{{.Module}}/internal/data/model/{{.Package}}"
{{- if not .IsTree}}
{{.Package}}Req "{{.Module}}/internal/service/types/{{.Package}}/request"
{{- end }}
"github.com/go-kratos/kratos/v2/log"
"gorm.io/gorm"
{{- end }}
)
// {{.StructName}}Repo {{.Description}}仓储接口
type {{.StructName}}Repo interface {
{{- if not .OnlyTemplate }}
Create(ctx context.Context, {{.Abbreviation}} *{{.Package}}.{{.StructName}}) error
Delete(ctx context.Context, {{.PrimaryField.FieldJson}} {{.PrimaryField.FieldType}}{{- if .AutoCreateResource -}}, userID uint{{- end -}}) error
DeleteByIds(ctx context.Context, {{.PrimaryField.FieldJson}}s []{{.PrimaryField.FieldType}}{{- if .AutoCreateResource -}}, deletedBy uint{{- end -}}) error
{{- if .AutoCreateResource }}
// DeleteWithTx 在事务中删除记录(用于 AutoCreateResource 场景)
DeleteWithTx(ctx context.Context, tx *gorm.DB, {{.PrimaryField.FieldJson}} {{.PrimaryField.FieldType}}) error
// DeleteByIdsWithTx 在事务中批量删除记录(用于 AutoCreateResource 场景)
DeleteByIdsWithTx(ctx context.Context, tx *gorm.DB, {{.PrimaryField.FieldJson}}s []{{.PrimaryField.FieldType}}) error
{{- end }}
Update(ctx context.Context, {{.Abbreviation}} *{{.Package}}.{{.StructName}}) error
FindByID(ctx context.Context, {{.PrimaryField.FieldJson}} {{.PrimaryField.FieldType}}) (*{{.Package}}.{{.StructName}}, error)
{{- if .IsTree }}
List(ctx context.Context) ([]*{{.Package}}.{{.StructName}}, error)
HasChildren(ctx context.Context, {{.PrimaryField.FieldJson}} {{.PrimaryField.FieldType}}) (bool, error)
{{- else }}
List(ctx context.Context, req *{{.Package}}Req.{{.StructName}}Search) ([]*{{.Package}}.{{.StructName}}, int64, error)
{{- end }}
{{- if .HasDataSource }}
GetDataSource(ctx context.Context) (map[string][]map[string]any, error)
{{- end }}
{{- end }}
{{- if .HasCustomMethods }}
{{ GenerateCustomMethodInterface .CustomMethods .StructName .Package }}
{{- end }}
}
// {{.StructName}}Usecase {{.Description}}用例
type {{.StructName}}Usecase struct {
repo {{.StructName}}Repo
log *log.Helper
}
// New{{.StructName}}Usecase 创建{{.Description}}用例
func New{{.StructName}}Usecase(repo {{.StructName}}Repo, logger log.Logger) *{{.StructName}}Usecase {
return &{{.StructName}}Usecase{
repo: repo,
log: log.NewHelper(logger),
}
}
{{- if not .OnlyTemplate }}
// Create 创建{{.Description}}
func (uc *{{.StructName}}Usecase) Create(ctx context.Context, {{.Abbreviation}} *{{.Package}}.{{.StructName}}) error {
uc.log.WithContext(ctx).Infof("创建{{.Description}}")
if err := uc.repo.Create(ctx, {{.Abbreviation}}); err != nil {
uc.log.WithContext(ctx).Errorf("创建{{.Description}}失败: %v", err)
return err
}
return nil
}
// Delete 删除{{.Description}}
func (uc *{{.StructName}}Usecase) Delete(ctx context.Context, {{.PrimaryField.FieldJson}} {{.PrimaryField.FieldType}}{{- if .AutoCreateResource -}}, userID uint{{- end -}}) error {
uc.log.WithContext(ctx).Infof("删除{{.Description}}, {{.PrimaryField.FieldJson}}: %v", {{.PrimaryField.FieldJson}})
{{- if .IsTree }}
// 检查是否有子节点
hasChildren, err := uc.repo.HasChildren(ctx, {{.PrimaryField.FieldJson}})
if err != nil {
uc.log.WithContext(ctx).Errorf("检查子节点失败: %v", err)
return err
}
if hasChildren {
uc.log.WithContext(ctx).Warn("此节点存在子节点不允许删除")
return errors.New("此节点存在子节点不允许删除")
}
{{- end }}
if err := uc.repo.Delete(ctx, {{.PrimaryField.FieldJson}}{{- if .AutoCreateResource -}}, userID{{- end -}}); err != nil {
uc.log.WithContext(ctx).Errorf("删除{{.Description}}失败: %v", err)
return err
}
return nil
}
// DeleteByIds 批量删除{{.Description}}
func (uc *{{.StructName}}Usecase) DeleteByIds(ctx context.Context, {{.PrimaryField.FieldJson}}s []{{.PrimaryField.FieldType}}{{- if .AutoCreateResource -}}, deletedBy uint{{- end -}}) error {
uc.log.WithContext(ctx).Infof("批量删除{{.Description}}, 数量: %d", len({{.PrimaryField.FieldJson}}s))
if err := uc.repo.DeleteByIds(ctx, {{.PrimaryField.FieldJson}}s{{- if .AutoCreateResource -}}, deletedBy{{- end -}}); err != nil {
uc.log.WithContext(ctx).Errorf("批量删除{{.Description}}失败: %v", err)
return err
}
return nil
}
{{- if .AutoCreateResource }}
// DeleteWithTx 在事务中删除{{.Description}}(用于 AutoCreateResource 场景)
// @param ctx 上下文
// @param tx 事务对象
// @param {{.PrimaryField.FieldJson}} 主键ID
// @return error 删除失败时返回错误
func (uc *{{.StructName}}Usecase) DeleteWithTx(ctx context.Context, tx *gorm.DB, {{.PrimaryField.FieldJson}} {{.PrimaryField.FieldType}}) error {
uc.log.WithContext(ctx).Infof("事务删除{{.Description}}, {{.PrimaryField.FieldJson}}: %v", {{.PrimaryField.FieldJson}})
{{- if .IsTree }}
// 检查是否有子节点
hasChildren, err := uc.repo.HasChildren(ctx, {{.PrimaryField.FieldJson}})
if err != nil {
uc.log.WithContext(ctx).Errorf("检查子节点失败: %v", err)
return err
}
if hasChildren {
uc.log.WithContext(ctx).Warn("此节点存在子节点不允许删除")
return errors.New("此节点存在子节点不允许删除")
}
{{- end }}
if err := uc.repo.DeleteWithTx(ctx, tx, {{.PrimaryField.FieldJson}}); err != nil {
uc.log.WithContext(ctx).Errorf("事务删除{{.Description}}失败: %v", err)
return err
}
return nil
}
// DeleteByIdsWithTx 在事务中批量删除{{.Description}}(用于 AutoCreateResource 场景)
// @param ctx 上下文
// @param tx 事务对象
// @param {{.PrimaryField.FieldJson}}s 主键ID列表
// @return error 删除失败时返回错误
func (uc *{{.StructName}}Usecase) DeleteByIdsWithTx(ctx context.Context, tx *gorm.DB, {{.PrimaryField.FieldJson}}s []{{.PrimaryField.FieldType}}) error {
uc.log.WithContext(ctx).Infof("事务批量删除{{.Description}}, 数量: %d", len({{.PrimaryField.FieldJson}}s))
if err := uc.repo.DeleteByIdsWithTx(ctx, tx, {{.PrimaryField.FieldJson}}s); err != nil {
uc.log.WithContext(ctx).Errorf("事务批量删除{{.Description}}失败: %v", err)
return err
}
return nil
}
{{- end }}
// Update 更新{{.Description}}
func (uc *{{.StructName}}Usecase) Update(ctx context.Context, {{.Abbreviation}} *{{.Package}}.{{.StructName}}) error {
uc.log.WithContext(ctx).Infof("更新{{.Description}}")
if err := uc.repo.Update(ctx, {{.Abbreviation}}); err != nil {
uc.log.WithContext(ctx).Errorf("更新{{.Description}}失败: %v", err)
return err
}
return nil
}
// FindByID 根据ID获取{{.Description}}
func (uc *{{.StructName}}Usecase) FindByID(ctx context.Context, {{.PrimaryField.FieldJson}} {{.PrimaryField.FieldType}}) (*{{.Package}}.{{.StructName}}, error) {
uc.log.WithContext(ctx).Debugf("查询{{.Description}}, {{.PrimaryField.FieldJson}}: %v", {{.PrimaryField.FieldJson}})
result, err := uc.repo.FindByID(ctx, {{.PrimaryField.FieldJson}})
if err != nil {
uc.log.WithContext(ctx).Errorf("查询{{.Description}}失败: %v", err)
return nil, err
}
return result, nil
}
{{- if .IsTree }}
// List 获取{{.Description}}列表(树形)
func (uc *{{.StructName}}Usecase) List(ctx context.Context) ([]*{{.Package}}.{{.StructName}}, error) {
uc.log.WithContext(ctx).Debug("获取{{.Description}}树形列表")
result, err := uc.repo.List(ctx)
if err != nil {
uc.log.WithContext(ctx).Errorf("获取{{.Description}}列表失败: %v", err)
return nil, err
}
return result, nil
}
{{- else }}
// List 分页获取{{.Description}}列表
func (uc *{{.StructName}}Usecase) List(ctx context.Context, req *{{.Package}}Req.{{.StructName}}Search) ([]*{{.Package}}.{{.StructName}}, int64, error) {
uc.log.WithContext(ctx).Debugf("获取{{.Description}}列表, 页码: %d, 每页: %d", req.Page, req.PageSize)
list, total, err := uc.repo.List(ctx, req)
if err != nil {
uc.log.WithContext(ctx).Errorf("获取{{.Description}}列表失败: %v", err)
return nil, 0, err
}
return list, total, nil
}
{{- end }}
{{- if .HasDataSource }}
// GetDataSource 获取{{.Description}}数据源
func (uc *{{.StructName}}Usecase) GetDataSource(ctx context.Context) (map[string][]map[string]any, error) {
uc.log.WithContext(ctx).Debug("获取{{.Description}}数据源")
result, err := uc.repo.GetDataSource(ctx)
if err != nil {
uc.log.WithContext(ctx).Errorf("获取{{.Description}}数据源失败: %v", err)
return nil, err
}
return result, nil
}
{{- end }}
{{- end }}
// GetPublic 获取{{.Description}}公开数据
func (uc *{{.StructName}}Usecase) GetPublic(ctx context.Context) {
// 此方法为获取公开数据
// 请自行实现
}
{{- end }}
+14
View File
@@ -0,0 +1,14 @@
{{- if .IsAdd }}
// 请在 {{.Package}} 包的 enter.go 文件中的 ProviderSet 添加以下内容:
// New{{.StructName}}Usecase,
{{- else }}
package {{.Package}}
import "github.com/google/wire"
// ProviderSet is {{.Package}} biz providers.
// 包含 {{.Description}} 相关的业务逻辑用例
var ProviderSet = wire.NewSet(
New{{.StructName}}Usecase,
)
{{- end }}
+322
View File
@@ -0,0 +1,322 @@
{{- $db := "r.data.db" }}
{{- if .IsAdd}}
// Get{{.StructName}}List 新增搜索语句 (GORM Gen 风格)
// 在 List 方法中添加以下条件:
{{ GenerateGormGenSearchConditions .Fields .StructName }}
// Get{{.StructName}}List 新增排序语句
// 在 List 方法中添加以下排序字段到 orderMap:
{{- range .Fields}}
{{- if .Sort}}
// orderMap["{{.ColumnName}}"] = t.{{.FieldName}}
{{- end}}
{{- end}}
{{- if .HasDataSource }}
// GetDataSource 方法新增关联语句
{{range $key, $value := .DataSourceMap}}
{{$key}} := make([]map[string]any, 0)
{{ $dataDB := "r.data.db" }}
{{$dataDB}}.Table("{{$value.Table}}"){{- if $value.HasDeletedAt}}.Where("deleted_at IS NULL"){{ end }}.Select("{{$value.Label}} as label,{{$value.Value}} as value").Scan(&{{$key}})
res["{{$key}}"] = {{$key}}
{{- end }}
{{- end }}
{{- else}}
package {{.Package}}
import (
{{- if not .OnlyTemplate }}
"context"
"{{.Module}}/internal/biz/{{.Package}}"
"{{.Module}}/internal/data/model"
"{{.Module}}/internal/data/query"
{{- if not .IsTree}}
{{.Package}}Req "{{.Module}}/internal/service/types/{{.Package}}/request"
{{- else }}
"{{.Module}}/pkg/utils"
{{- end }}
{{- if .AutoCreateResource }}
"gorm.io/gorm"
{{- end}}
{{- if .NeedSort}}
"gorm.io/gen/field"
{{- end}}
"github.com/go-kratos/kratos/v2/log"
{{- end }}
)
type {{.Abbreviation}}Repo struct {
data *Data
log *log.Helper
}
// New{{.StructName}}Repo 创建{{.Description}}仓储
// 实现 {{.Package}}.{{.StructName}}Repo 接口
func New{{.StructName}}Repo(data *Data, logger log.Logger) {{.Package}}.{{.StructName}}Repo {
return &{{.Abbreviation}}Repo{
data: data,
log: log.NewHelper(logger),
}
}
// Create 创建{{.Description}}
func (r *{{.Abbreviation}}Repo) Create(ctx context.Context, {{.Abbreviation}} *{{.Package}}.{{.StructName}}) error {
m := toModel{{.StructName}}({{.Abbreviation}})
if err := query.{{.StructName}}.WithContext(ctx).Create(m); err != nil {
return err
}
// 回写生成的ID
{{.Abbreviation}}.{{.PrimaryField.FieldName}} = {{- if eq .PrimaryField.FieldType "uint"}} uint(m.{{.PrimaryField.FieldName}}){{- else if eq .PrimaryField.FieldType "int"}} int(m.{{.PrimaryField.FieldName}}){{- else if eq .PrimaryField.FieldType "int64"}} m.{{.PrimaryField.FieldName}}{{- else}} m.{{.PrimaryField.FieldName}}{{- end}}
return nil
}
// Delete 删除{{.Description}}
func (r *{{.Abbreviation}}Repo) Delete(ctx context.Context, {{.PrimaryField.FieldJson}} {{.PrimaryField.FieldType}}{{- if .AutoCreateResource -}}, userID uint{{- end -}}) error {
t := query.{{.StructName}}
{{- if .AutoCreateResource }}
return {{$db}}.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
q := query.Use(tx).{{.StructName}}
if _, err := q.WithContext(ctx).Where(t.{{.PrimaryField.FieldName}}.Eq({{- if eq .PrimaryField.FieldType "uint"}}int64({{.PrimaryField.FieldJson}}){{- else if eq .PrimaryField.FieldType "int"}}int64({{.PrimaryField.FieldJson}}){{- else}}{{.PrimaryField.FieldJson}}{{- end}})).Update(t.DeletedBy, userID); err != nil {
return err
}
if _, err := q.WithContext(ctx).Where(t.{{.PrimaryField.FieldName}}.Eq({{- if eq .PrimaryField.FieldType "uint"}}int64({{.PrimaryField.FieldJson}}){{- else if eq .PrimaryField.FieldType "int"}}int64({{.PrimaryField.FieldJson}}){{- else}}{{.PrimaryField.FieldJson}}{{- end}})).Delete(); err != nil {
return err
}
return nil
})
{{- else }}
_, err := t.WithContext(ctx).Where(t.{{.PrimaryField.FieldName}}.Eq({{- if eq .PrimaryField.FieldType "uint"}}int64({{.PrimaryField.FieldJson}}){{- else if eq .PrimaryField.FieldType "int"}}int64({{.PrimaryField.FieldJson}}){{- else}}{{.PrimaryField.FieldJson}}{{- end}})).Delete()
return err
{{- end }}
}
// DeleteByIds 批量删除{{.Description}}
func (r *{{.Abbreviation}}Repo) DeleteByIds(ctx context.Context, {{.PrimaryField.FieldJson}}s []{{.PrimaryField.FieldType}}{{- if .AutoCreateResource -}}, deletedBy uint{{- end -}}) error {
t := query.{{.StructName}}
// 转换 ID 类型
int64Ids := make([]int64, len({{.PrimaryField.FieldJson}}s))
for i, id := range {{.PrimaryField.FieldJson}}s {
int64Ids[i] = int64(id)
}
{{- if .AutoCreateResource }}
return {{$db}}.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
q := query.Use(tx).{{.StructName}}
if _, err := q.WithContext(ctx).Where(t.{{.PrimaryField.FieldName}}.In(int64Ids...)).Update(t.DeletedBy, deletedBy); err != nil {
return err
}
if _, err := q.WithContext(ctx).Where(t.{{.PrimaryField.FieldName}}.In(int64Ids...)).Delete(); err != nil {
return err
}
return nil
})
{{- else}}
_, err := t.WithContext(ctx).Where(t.{{.PrimaryField.FieldName}}.In(int64Ids...)).Delete()
return err
{{- end}}
}
{{- if .AutoCreateResource }}
// DeleteWithTx 在事务中删除{{.Description}}(用于 Service 层事务管理)
// @param ctx 上下文
// @param tx 事务对象(由 Service 层传入)
// @param {{.PrimaryField.FieldJson}} 主键ID
// @return error 删除失败时返回错误
func (r *{{.Abbreviation}}Repo) DeleteWithTx(ctx context.Context, tx *gorm.DB, {{.PrimaryField.FieldJson}} {{.PrimaryField.FieldType}}) error {
t := query.{{.StructName}}
q := query.Use(tx).{{.StructName}}
_, err := q.WithContext(ctx).Where(t.{{.PrimaryField.FieldName}}.Eq({{- if eq .PrimaryField.FieldType "uint"}}int64({{.PrimaryField.FieldJson}}){{- else if eq .PrimaryField.FieldType "int"}}int64({{.PrimaryField.FieldJson}}){{- else}}{{.PrimaryField.FieldJson}}{{- end}})).Delete()
return err
}
// DeleteByIdsWithTx 在事务中批量删除{{.Description}}(用于 Service 层事务管理)
// @param ctx 上下文
// @param tx 事务对象(由 Service 层传入)
// @param {{.PrimaryField.FieldJson}}s 主键ID列表
// @return error 删除失败时返回错误
func (r *{{.Abbreviation}}Repo) DeleteByIdsWithTx(ctx context.Context, tx *gorm.DB, {{.PrimaryField.FieldJson}}s []{{.PrimaryField.FieldType}}) error {
t := query.{{.StructName}}
// 转换 ID 类型
int64Ids := make([]int64, len({{.PrimaryField.FieldJson}}s))
for i, id := range {{.PrimaryField.FieldJson}}s {
int64Ids[i] = int64(id)
}
q := query.Use(tx).{{.StructName}}
_, err := q.WithContext(ctx).Where(t.{{.PrimaryField.FieldName}}.In(int64Ids...)).Delete()
return err
}
{{- end }}
// Update 更新{{.Description}}
func (r *{{.Abbreviation}}Repo) Update(ctx context.Context, {{.Abbreviation}} *{{.Package}}.{{.StructName}}) error {
t := query.{{.StructName}}
m := toModel{{.StructName}}({{.Abbreviation}})
_, err := t.WithContext(ctx).Where(t.{{.PrimaryField.FieldName}}.Eq(m.{{.PrimaryField.FieldName}})).Updates(m)
return err
}
// FindByID 根据ID获取{{.Description}}
func (r *{{.Abbreviation}}Repo) FindByID(ctx context.Context, {{.PrimaryField.FieldJson}} {{.PrimaryField.FieldType}}) (*{{.Package}}.{{.StructName}}, error) {
t := query.{{.StructName}}
m, err := t.WithContext(ctx).Where(t.{{.PrimaryField.FieldName}}.Eq({{- if eq .PrimaryField.FieldType "uint"}}int64({{.PrimaryField.FieldJson}}){{- else if eq .PrimaryField.FieldType "int"}}int64({{.PrimaryField.FieldJson}}){{- else}}{{.PrimaryField.FieldJson}}{{- end}})).First()
if err != nil {
return nil, err
}
return toBiz{{.StructName}}(m), nil
}
{{- if .IsTree }}
// List 获取{{.Description}}列表(树形)
func (r *{{.Abbreviation}}Repo) List(ctx context.Context) ([]*{{.Package}}.{{.StructName}}, error) {
t := query.{{.StructName}}
models, err := t.WithContext(ctx).Find()
if err != nil {
return nil, err
}
// 转换为 biz 类型
result := make([]*{{.Package}}.{{.StructName}}, len(models))
for i, m := range models {
result[i] = toBiz{{.StructName}}(m)
}
return utils.BuildTree(result), nil
}
// HasChildren 检查是否有子节点
func (r *{{.Abbreviation}}Repo) HasChildren(ctx context.Context, {{.PrimaryField.FieldJson}} {{.PrimaryField.FieldType}}) (bool, error) {
t := query.{{.StructName}}
count, err := t.WithContext(ctx).Where(t.ParentID.Eq({{- if eq .PrimaryField.FieldType "uint"}}int64({{.PrimaryField.FieldJson}}){{- else if eq .PrimaryField.FieldType "int"}}int64({{.PrimaryField.FieldJson}}){{- else}}{{.PrimaryField.FieldJson}}{{- end}})).Count()
return count > 0, err
}
{{- else }}
// List 分页获取{{.Description}}列表
func (r *{{.Abbreviation}}Repo) List(ctx context.Context, req *{{.Package}}Req.{{.StructName}}Search) ([]*{{.Package}}.{{.StructName}}, int64, error) {
t := query.{{.StructName}}
q := t.WithContext(ctx)
// 条件搜索 (使用 GORM Gen 类型安全查询)
{{- if .GvaModel }}
if len(req.CreatedAtRange) == 2 {
q = q.Where(t.CreatedAt.Between(req.CreatedAtRange[0], req.CreatedAtRange[1]))
}
{{- end }}
{{ GenerateGormGenSearchConditions .Fields .StructName }}
// 统计总数
total, err := q.Count()
if err != nil {
return nil, 0, err
}
{{- if .NeedSort}}
// 排序 (使用 GORM Gen 类型安全排序)
orderMap := make(map[string]func() field.OrderExpr)
{{- if .GvaModel }}
orderMap["id"] = func() field.OrderExpr { return t.ID }
orderMap["created_at"] = func() field.OrderExpr { return t.CreatedAt }
{{- end }}
{{- range .Fields}}
{{- if .Sort}}
orderMap["{{.ColumnName}}"] = func() field.OrderExpr { return t.{{.FieldName}} }
{{- end}}
{{- end}}
if orderFn, ok := orderMap[req.Sort]; ok {
if req.Order == "descending" {
q = q.Order(orderFn().Desc())
} else {
q = q.Order(orderFn())
}
}
{{- end}}
// 分页
limit := req.PageSize
offset := req.PageSize * (req.Page - 1)
if limit != 0 {
q = q.Limit(limit).Offset(offset)
}
models, err := q.Find()
if err != nil {
return nil, 0, err
}
// 转换为 biz 类型
result := make([]*{{.Package}}.{{.StructName}}, len(models))
for i, m := range models {
result[i] = toBiz{{.StructName}}(m)
}
return result, total, nil
}
{{- end }}
{{- if .HasDataSource }}
// GetDataSource 获取{{.Description}}数据源
func (r *{{.Abbreviation}}Repo) GetDataSource(ctx context.Context) (map[string][]map[string]any, error) {
res := make(map[string][]map[string]any)
{{range $key, $value := .DataSourceMap}}
{{$key}} := make([]map[string]any, 0)
if err := r.data.db.WithContext(ctx).Table("{{$value.Table}}"){{- if $value.HasDeletedAt}}.Where("deleted_at IS NULL"){{ end }}.Select("{{$value.Label}} as label, {{$value.Value}} as value").Scan(&{{$key}}).Error; err != nil {
return nil, err
}
res["{{$key}}"] = {{$key}}
{{- end }}
return res, nil
}
{{- end }}
// toModel{{.StructName}} 将 biz 层对象转换为 model 层对象
func toModel{{.StructName}}(b *{{.Package}}.{{.StructName}}) *model.{{.StructName}} {
if b == nil {
return nil
}
return &model.{{.StructName}}{
{{- if .GvaModel }}
GVA_MODEL: model.GVA_MODEL{
ID: int64(b.ID),
CreatedAt: b.CreatedAt,
UpdatedAt: b.UpdatedAt,
},
{{- else }}
{{.PrimaryField.FieldName}}: {{- if eq .PrimaryField.FieldType "uint"}} int64(b.{{.PrimaryField.FieldName}}){{- else if eq .PrimaryField.FieldType "int"}} int64(b.{{.PrimaryField.FieldName}}){{- else}} b.{{.PrimaryField.FieldName}}{{- end}},
{{- end }}
{{- range .Fields}}
{{- if not .PrimaryKey}}
{{.FieldName}}: b.{{.FieldName}},
{{- end}}
{{- end}}
}
}
// toBiz{{.StructName}} 将 model 层对象转换为 biz 层对象
func toBiz{{.StructName}}(m *model.{{.StructName}}) *{{.Package}}.{{.StructName}} {
if m == nil {
return nil
}
return &{{.Package}}.{{.StructName}}{
{{- if .GvaModel }}
ID: uint(m.ID),
CreatedAt: m.CreatedAt,
UpdatedAt: m.UpdatedAt,
{{- else }}
{{.PrimaryField.FieldName}}: {{- if eq .PrimaryField.FieldType "uint"}} uint(m.{{.PrimaryField.FieldName}}){{- else if eq .PrimaryField.FieldType "int"}} int(m.{{.PrimaryField.FieldName}}){{- else}} m.{{.PrimaryField.FieldName}}{{- end}},
{{- end }}
{{- range .Fields}}
{{- if not .PrimaryKey}}
{{.FieldName}}: m.{{.FieldName}},
{{- end}}
{{- end}}
}
}
{{- if .HasCustomMethods }}
{{ GenerateCustomMethodImpl .CustomMethods .StructName .Package .Abbreviation }}
{{- end }}
{{- end}}
+14
View File
@@ -0,0 +1,14 @@
{{- if .IsAdd }}
// 请在 {{.Package}} 包的 enter.go 文件中的 ProviderSet 添加以下内容:
// New{{.StructName}}Repo,
{{- else }}
package {{.Package}}
import "github.com/google/wire"
// ProviderSet is {{.Package}} data providers.
// 包含 {{.Description}} 相关的数据访问层实现
var ProviderSet = wire.NewSet(
New{{.StructName}}Repo,
)
{{- end }}
+86
View File
@@ -0,0 +1,86 @@
{{- if .IsAdd}}
// 在 model.{{.StructName}} 结构体中新增如下字段
{{- range .Fields}}
{{ GenerateModelField . }}
{{- end }}
{{ else }}
// Code generated by KRA AutoCode. DO NOT EDIT.
// 自动生成模板 {{.StructName}}
package model
import (
{{- if .GvaModel }}
"time"
"gorm.io/gorm"
{{- else }}
{{- if or .HasTimer }}
"time"
{{- end }}
{{- if .NeedJSON }}
"gorm.io/datatypes"
{{- end }}
{{- end }}
)
const TableName{{.StructName}} = "{{.TableName}}"
// {{.StructName}} {{.Description}}
// mapped from table <{{.TableName}}>
type {{.StructName}} struct {
{{- if .GvaModel }}
ID int64 `gorm:"column:id;type:bigint(20) unsigned;primaryKey;autoIncrement:true" json:"id"`
CreatedAt time.Time `gorm:"column:created_at;type:datetime(3)" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at;type:datetime(3)" json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;type:datetime(3);index:idx_{{.TableName}}_deleted_at,priority:1" json:"deleted_at"`
{{- else }}
{{- with .PrimaryField}}
{{.FieldName}} int64 `gorm:"column:{{.ColumnName}};type:bigint(20) unsigned;primaryKey;autoIncrement:true" json:"{{.FieldJson}}"` // {{.FieldDesc}}
{{- end}}
{{- end }}
{{- range .Fields}}
{{- if not .PrimaryKey}}
{{ GenerateModelField . }}
{{- end}}
{{- end }}
{{- if .AutoCreateResource }}
CreatedBy int64 `gorm:"column:created_by;type:bigint(20) unsigned;comment:创建者" json:"created_by"` // 创建者
UpdatedBy int64 `gorm:"column:updated_by;type:bigint(20) unsigned;comment:更新者" json:"updated_by"` // 更新者
DeletedBy int64 `gorm:"column:deleted_by;type:bigint(20) unsigned;comment:删除者" json:"deleted_by"` // 删除者
{{- end }}
{{- if .IsTree }}
ParentID int64 `gorm:"column:parent_id;type:bigint(20);comment:父节点ID" json:"parent_id"` // 父节点ID
Children []*{{.StructName}} `gorm:"-" json:"children"` // 子节点
{{- end }}
}
// TableName {{.StructName}}'s table name
func (*{{.StructName}}) TableName() string {
return TableName{{.StructName}}
}
{{- if .IsTree }}
// GetChildren 实现 TreeNode 接口
func (s *{{.StructName}}) GetChildren() []*{{.StructName}} {
return s.Children
}
// SetChildren 实现 TreeNode 接口
func (s *{{.StructName}}) SetChildren(child *{{.StructName}}) {
s.Children = append(s.Children, child)
}
// GetID 实现 TreeNode 接口
func (s *{{.StructName}}) GetID() int {
return int(s.{{- if .GvaModel}}ID{{- else}}{{.PrimaryField.FieldName}}{{- end}})
}
// GetParentID 实现 TreeNode 接口
func (s *{{.StructName}}) GetParentID() int {
return int(s.ParentID)
}
{{- end }}
{{ end }}
@@ -0,0 +1,13 @@
{{- if .IsAdd }}
// 请在 {{.Package}} 包的 enter.go 文件中的 ProviderSet 添加以下内容:
// New{{.StructName}}Handler,
{{- else }}
package {{ .Package }}
import "github.com/google/wire"
// ProviderSet is {{.Package}} handler providers.
// 包含 {{.Description}} 相关的 HTTP 处理器
// Handler 层负责处理 HTTP 请求,调用 Biz 层 Usecase 完成业务逻辑
var ProviderSet = wire.NewSet(New{{.StructName}}Handler)
{{- end }}
@@ -0,0 +1,272 @@
{{- if .IsAdd}}
// 在 {{.StructName}}Handler 中新增如下方法
// 请根据实际需求添加
{{- else}}
package {{.Package}}
import (
{{if not .OnlyTemplate}}
"{{.Module}}/pkg/response"
"{{.Module}}/internal/biz/{{.Package}}"
model "{{.Module}}/internal/data/model/{{.Package}}"
{{- if not .IsTree}}
{{.Package}}Req "{{.Module}}/internal/service/types/{{.Package}}/request"
{{- end }}
"github.com/gin-gonic/gin"
"github.com/go-kratos/kratos/v2/log"
{{- if .AutoCreateResource}}
"{{.Module}}/pkg/utils"
{{- end }}
{{- else}}
"{{.Module}}/pkg/response"
"github.com/gin-gonic/gin"
{{- end}}
)
// {{.StructName}}Handler {{.Description}}处理器
// 负责处理 HTTP 请求,调用 Biz 层 Usecase 完成业务逻辑
type {{.StructName}}Handler struct {
uc *{{.Package}}.{{.StructName}}Usecase
log *log.Helper
}
// New{{.StructName}}Handler 创建{{.Description}}处理器
// @param uc Biz 层 Usecase,包含业务逻辑
// @param logger 日志记录器
func New{{.StructName}}Handler(uc *{{.Package}}.{{.StructName}}Usecase, logger log.Logger) *{{.StructName}}Handler {
return &{{.StructName}}Handler{
uc: uc,
log: log.NewHelper(logger),
}
}
{{if not .OnlyTemplate}}
// Create{{.StructName}} 创建{{.Description}}
// @Tags {{.StructName}}
// @Summary 创建{{.Description}}
// @Security ApiKeyAuth
// @Accept application/json
// @Produce application/json
// @Param data body model.{{.StructName}} true "创建{{.Description}}"
// @Success 200 {object} response.Response{msg=string} "创建成功"
// @Router /{{.Abbreviation}}/create{{.StructName}} [post]
func (h *{{.StructName}}Handler) Create{{.StructName}}(c *gin.Context) {
ctx := c.Request.Context()
var {{.Abbreviation}} model.{{.StructName}}
if err := c.ShouldBindJSON(&{{.Abbreviation}}); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
{{- if .AutoCreateResource }}
{{.Abbreviation}}.CreatedBy = utils.GetUserID(c)
{{- end }}
// 调用 Biz 层 Usecase 创建实体
if err := h.uc.Create(ctx, &{{.Abbreviation}}); err != nil {
h.log.WithContext(ctx).Errorf("创建失败: %v", err)
response.FailWithMessage("创建失败: "+err.Error(), c)
return
}
response.OkWithMessage("创建成功", c)
}
// Delete{{.StructName}} 删除{{.Description}}
// @Tags {{.StructName}}
// @Summary 删除{{.Description}}
// @Security ApiKeyAuth
// @Accept application/json
// @Produce application/json
// @Param data body model.{{.StructName}} true "删除{{.Description}}"
// @Success 200 {object} response.Response{msg=string} "删除成功"
// @Router /{{.Abbreviation}}/delete{{.StructName}} [delete]
func (h *{{.StructName}}Handler) Delete{{.StructName}}(c *gin.Context) {
ctx := c.Request.Context()
{{.PrimaryField.FieldJson}} := c.Query("{{.PrimaryField.FieldJson}}")
{{- if .AutoCreateResource }}
userID := utils.GetUserID(c)
{{- end }}
// 调用 Biz 层 Usecase 删除实体
if err := h.uc.Delete(ctx, {{.PrimaryField.FieldJson}}{{- if .AutoCreateResource -}}, userID{{- end -}}); err != nil {
h.log.WithContext(ctx).Errorf("删除失败: %v", err)
response.FailWithMessage("删除失败: "+err.Error(), c)
return
}
response.OkWithMessage("删除成功", c)
}
// Delete{{.StructName}}ByIds 批量删除{{.Description}}
// @Tags {{.StructName}}
// @Summary 批量删除{{.Description}}
// @Security ApiKeyAuth
// @Accept application/json
// @Produce application/json
// @Param {{.PrimaryField.FieldJson}}s query []{{.PrimaryField.FieldType}} true "批量删除{{.Description}}"
// @Success 200 {object} response.Response{msg=string} "批量删除成功"
// @Router /{{.Abbreviation}}/delete{{.StructName}}ByIds [delete]
func (h *{{.StructName}}Handler) Delete{{.StructName}}ByIds(c *gin.Context) {
ctx := c.Request.Context()
{{.PrimaryField.FieldJson}}s := c.QueryArray("{{.PrimaryField.FieldJson}}s[]")
{{- if .AutoCreateResource }}
userID := utils.GetUserID(c)
{{- end }}
// 调用 Biz 层 Usecase 批量删除实体
if err := h.uc.DeleteByIds(ctx, {{.PrimaryField.FieldJson}}s{{- if .AutoCreateResource }}, userID{{- end }}); err != nil {
h.log.WithContext(ctx).Errorf("批量删除失败: %v", err)
response.FailWithMessage("批量删除失败: "+err.Error(), c)
return
}
response.OkWithMessage("批量删除成功", c)
}
// Update{{.StructName}} 更新{{.Description}}
// @Tags {{.StructName}}
// @Summary 更新{{.Description}}
// @Security ApiKeyAuth
// @Accept application/json
// @Produce application/json
// @Param data body model.{{.StructName}} true "更新{{.Description}}"
// @Success 200 {object} response.Response{msg=string} "更新成功"
// @Router /{{.Abbreviation}}/update{{.StructName}} [put]
func (h *{{.StructName}}Handler) Update{{.StructName}}(c *gin.Context) {
ctx := c.Request.Context()
var {{.Abbreviation}} model.{{.StructName}}
if err := c.ShouldBindJSON(&{{.Abbreviation}}); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
{{- if .AutoCreateResource }}
{{.Abbreviation}}.UpdatedBy = utils.GetUserID(c)
{{- end }}
// 调用 Biz 层 Usecase 更新实体
if err := h.uc.Update(ctx, &{{.Abbreviation}}); err != nil {
h.log.WithContext(ctx).Errorf("更新失败: %v", err)
response.FailWithMessage("更新失败: "+err.Error(), c)
return
}
response.OkWithMessage("更新成功", c)
}
// Find{{.StructName}} 用id查询{{.Description}}
// @Tags {{.StructName}}
// @Summary 用id查询{{.Description}}
// @Security ApiKeyAuth
// @Accept application/json
// @Produce application/json
// @Param {{.PrimaryField.FieldJson}} query {{.PrimaryField.FieldType}} true "用id查询{{.Description}}"
// @Success 200 {object} response.Response{data=model.{{.StructName}},msg=string} "查询成功"
// @Router /{{.Abbreviation}}/find{{.StructName}} [get]
func (h *{{.StructName}}Handler) Find{{.StructName}}(c *gin.Context) {
ctx := c.Request.Context()
{{.PrimaryField.FieldJson}} := c.Query("{{.PrimaryField.FieldJson}}")
// 调用 Biz 层 Usecase 查询实体
re{{.Abbreviation}}, err := h.uc.FindByID(ctx, {{.PrimaryField.FieldJson}})
if err != nil {
h.log.WithContext(ctx).Errorf("查询失败: %v", err)
response.FailWithMessage("查询失败: "+err.Error(), c)
return
}
response.OkWithData(re{{.Abbreviation}}, c)
}
{{- if .IsTree }}
// Get{{.StructName}}List 获取{{.Description}}列表(树形结构)
// @Tags {{.StructName}}
// @Summary 获取{{.Description}}列表(树形结构)
// @Security ApiKeyAuth
// @Accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "获取成功"
// @Router /{{.Abbreviation}}/get{{.StructName}}List [get]
func (h *{{.StructName}}Handler) Get{{.StructName}}List(c *gin.Context) {
ctx := c.Request.Context()
// 调用 Biz 层 Usecase 获取树形列表
list, err := h.uc.List(ctx)
if err != nil {
h.log.WithContext(ctx).Errorf("获取失败: %v", err)
response.FailWithMessage("获取失败: "+err.Error(), c)
return
}
response.OkWithDetailed(list, "获取成功", c)
}
{{- else }}
// Get{{.StructName}}List 分页获取{{.Description}}列表
// @Tags {{.StructName}}
// @Summary 分页获取{{.Description}}列表
// @Security ApiKeyAuth
// @Accept application/json
// @Produce application/json
// @Param data query {{.Package}}Req.{{.StructName}}Search true "分页获取{{.Description}}列表"
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "获取成功"
// @Router /{{.Abbreviation}}/get{{.StructName}}List [get]
func (h *{{.StructName}}Handler) Get{{.StructName}}List(c *gin.Context) {
ctx := c.Request.Context()
var pageInfo {{.Package}}Req.{{.StructName}}Search
if err := c.ShouldBindQuery(&pageInfo); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
// 调用 Biz 层 Usecase 获取分页列表
list, total, err := h.uc.List(ctx, &pageInfo)
if err != nil {
h.log.WithContext(ctx).Errorf("获取失败: %v", err)
response.FailWithMessage("获取失败: "+err.Error(), c)
return
}
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
}
{{- end }}
{{- if .HasDataSource }}
// Get{{.StructName}}DataSource 获取{{.StructName}}的数据源
// @Tags {{.StructName}}
// @Summary 获取{{.StructName}}的数据源
// @Accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=object,msg=string} "查询成功"
// @Router /{{.Abbreviation}}/get{{.StructName}}DataSource [get]
func (h *{{.StructName}}Handler) Get{{.StructName}}DataSource(c *gin.Context) {
ctx := c.Request.Context()
// 调用 Biz 层 Usecase 获取数据源
dataSource, err := h.uc.GetDataSource(ctx)
if err != nil {
h.log.WithContext(ctx).Errorf("查询失败: %v", err)
response.FailWithMessage("查询失败: "+err.Error(), c)
return
}
response.OkWithData(dataSource, c)
}
{{- end }}
{{- end }}
// Get{{.StructName}}Public 不需要鉴权的{{.Description}}接口
// @Tags {{.StructName}}
// @Summary 不需要鉴权的{{.Description}}接口
// @Accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=object,msg=string} "获取成功"
// @Router /{{.Abbreviation}}/get{{.StructName}}Public [get]
func (h *{{.StructName}}Handler) Get{{.StructName}}Public(c *gin.Context) {
ctx := c.Request.Context()
// 调用 Biz 层 Usecase 获取公开数据
h.uc.GetPublic(ctx)
response.OkWithDetailed(gin.H{
"info": "不需要鉴权的{{.Description}}接口信息",
}, "获取成功", c)
}
{{- end }}
@@ -0,0 +1,75 @@
{{- if .IsAdd}}
// 在结构体中新增如下字段
{{- range .Fields}}
{{ GenerateField . }}
{{- end }}
{{ else }}
// 自动生成模板{{.StructName}}
package {{.Package}}
{{- if not .OnlyTemplate}}
import (
{{- if .GvaModel }}
"{{.Module}}/internal/data/model"
{{- end }}
{{- if or .HasTimer }}
"time"
{{- end }}
{{- if .NeedJSON }}
"gorm.io/datatypes"
{{- end }}
)
{{- end }}
// {{.Description}} 结构体 {{.StructName}}
type {{.StructName}} struct {
{{- if not .OnlyTemplate}}
{{- if .GvaModel }}
model.KRA_MODEL
{{- end }}
{{- range .Fields}}
{{ GenerateField . }}
{{- end }}
{{- if .AutoCreateResource }}
CreatedBy uint `gorm:"column:created_by;comment:创建者"`
UpdatedBy uint `gorm:"column:updated_by;comment:更新者"`
DeletedBy uint `gorm:"column:deleted_by;comment:删除者"`
{{- end }}
{{- if .IsTree }}
Children []*{{.StructName}} `json:"children" gorm:"-"` //子节点
ParentID int `json:"parentID" gorm:"column:parent_id;comment:父节点"`
{{- end }}
{{- end }}
}
{{ if .TableName }}
// TableName {{.Description}} {{.StructName}}自定义表名 {{.TableName}}
func ({{.StructName}}) TableName() string {
return "{{.TableName}}"
}
{{ end }}
{{if .IsTree }}
// GetChildren 实现TreeNode接口
func (s *{{.StructName}}) GetChildren() []*{{.StructName}} {
return s.Children
}
// SetChildren 实现TreeNode接口
func (s *{{.StructName}}) SetChildren(children *{{.StructName}}) {
s.Children = append(s.Children, children)
}
// GetID 实现TreeNode接口
func (s *{{.StructName}}) GetID() int {
return int({{if not .GvaModel}}*{{- end }}s.{{.PrimaryField.FieldName}})
}
// GetParentID 实现TreeNode接口
func (s *{{.StructName}}) GetParentID() int {
return s.ParentID
}
{{ end }}
{{ end }}
@@ -0,0 +1,39 @@
{{- if .IsAdd}}
// 在结构体中新增如下字段
{{- range .Fields}}
{{- if ne .FieldSearchType ""}}
{{ GenerateSearchField . }}
{{- end}}
{{- end }}
{{- if .NeedSort}}
Sort string `json:"sort" form:"sort"`
Order string `json:"order" form:"order"`
{{- end}}
{{- else }}
package request
import (
{{- if not .OnlyTemplate }}
"{{.Module}}/internal/service/types/common"
{{ if or .HasSearchTimer .GvaModel }}"time"{{ end }}
{{- end }}
)
type {{.StructName}}Search struct{
{{- if not .OnlyTemplate}}
{{- if .GvaModel }}
CreatedAtRange []time.Time `json:"createdAtRange" form:"createdAtRange[]"`
{{- end }}
{{- range .Fields}}
{{- if ne .FieldSearchType ""}}
{{ GenerateSearchField . }}
{{- end}}
{{- end }}
common.PageInfo
{{- if .NeedSort}}
Sort string `json:"sort" form:"sort"`
Order string `json:"order" form:"order"`
{{- end}}
{{- end}}
}
{{- end }}
@@ -0,0 +1,26 @@
{{- if .IsAdd }}
// ==================== Wire Provider 注入说明 ====================
// 请在 {{.Package}} 包的 enter.go 文件中的 ProviderSet 添加以下内容:
// New{{.StructName}}Router,
//
// 同时在 RouterGroup 结构体中添加:
// {{.StructName}}Router
//
// 并在 var 块中添加 handler 引用:
// {{.Abbreviation}}Handler = handler.{{.StructName}}Handler{}
{{- else }}
package {{ .Package }}
import "github.com/google/wire"
// ProviderSet is {{.Package}} router providers.
// 包含 {{.Description}} 相关的路由配置
// 使用 Wire 进行依赖注入
var ProviderSet = wire.NewSet(New{{.StructName}}Router)
// RouterGroup {{.Package}} 路由组
// 包含该包下所有路由的集合
type RouterGroup struct {
{{.StructName}}Router
}
{{- end }}
@@ -0,0 +1,75 @@
package {{.Package}}
import (
{{- if not .OnlyTemplate}}
"{{.Module}}/internal/server/middleware"
{{- else}}
// "{{.Module}}/internal/server/middleware"
{{- end}}
"{{.Module}}/internal/server/handler/{{.Package}}"
"github.com/gin-gonic/gin"
)
// {{.StructName}}Router {{.Description}}路由
// 负责注册 {{.Description}} 相关的 HTTP 路由
type {{.StructName}}Router struct {
handler *{{.Package}}.{{.StructName}}Handler
}
// New{{.StructName}}Router 创建{{.Description}}路由
// @param handler {{.Description}}处理器
func New{{.StructName}}Router(handler *{{.Package}}.{{.StructName}}Handler) *{{.StructName}}Router {
return &{{.StructName}}Router{handler: handler}
}
// Init{{.StructName}}Router 初始化 {{.Description}} 路由信息
// @param Router 需要认证的路由组
// @param PublicRouter 公开路由组(不需要认证)
func (r *{{.StructName}}Router) Init{{.StructName}}Router(Router *gin.RouterGroup, PublicRouter *gin.RouterGroup) {
{{- if not .OnlyTemplate}}
// 需要认证 + 操作记录的路由组(用于写操作:创建、更新、删除)
{{.Abbreviation}}Router := Router.Group("{{.Abbreviation}}").Use(middleware.OperationRecord())
// 需要认证但不记录操作的路由组(用于读操作:查询、列表)
{{.Abbreviation}}RouterWithoutRecord := Router.Group("{{.Abbreviation}}")
{{- else}}
// {{.Abbreviation}}Router := Router.Group("{{.Abbreviation}}").Use(middleware.OperationRecord())
// {{.Abbreviation}}RouterWithoutRecord := Router.Group("{{.Abbreviation}}")
{{- end}}
// 公开路由组(不需要认证)
{{.Abbreviation}}RouterWithoutAuth := PublicRouter.Group("{{.Abbreviation}}")
{{- if not .OnlyTemplate}}
// ==================== 需要认证 + 操作记录的路由 ====================
// 这些路由会记录操作日志,用于审计和追踪
{
{{.Abbreviation}}Router.POST("create{{.StructName}}", r.handler.Create{{.StructName}}) // 新建{{.Description}}
{{.Abbreviation}}Router.DELETE("delete{{.StructName}}", r.handler.Delete{{.StructName}}) // 删除{{.Description}}
{{.Abbreviation}}Router.DELETE("delete{{.StructName}}ByIds", r.handler.Delete{{.StructName}}ByIds) // 批量删除{{.Description}}
{{.Abbreviation}}Router.PUT("update{{.StructName}}", r.handler.Update{{.StructName}}) // 更新{{.Description}}
}
// ==================== 需要认证但不记录操作的路由 ====================
// 这些路由是只读操作,不需要记录操作日志
{
{{.Abbreviation}}RouterWithoutRecord.GET("find{{.StructName}}", r.handler.Find{{.StructName}}) // 根据ID获取{{.Description}}
{{.Abbreviation}}RouterWithoutRecord.GET("get{{.StructName}}List", r.handler.Get{{.StructName}}List) // 获取{{.Description}}列表
}
// ==================== 公开路由(不需要认证) ====================
// 这些路由可以被任何人访问,不需要登录
{
{{- if .HasDataSource}}
{{.Abbreviation}}RouterWithoutAuth.GET("get{{.StructName}}DataSource", r.handler.Get{{.StructName}}DataSource) // 获取{{.Description}}数据源
{{- end}}
{{.Abbreviation}}RouterWithoutAuth.GET("get{{.StructName}}Public", r.handler.Get{{.StructName}}Public) // {{.Description}}开放接口
}
{{- else}}
// ==================== 公开路由(不需要认证) ====================
{
{{- if .HasDataSource}}
{{.Abbreviation}}RouterWithoutAuth.GET("get{{.StructName}}DataSource", r.handler.Get{{.StructName}}DataSource) // 获取{{.Description}}数据源
{{- end}}
{{.Abbreviation}}RouterWithoutAuth.GET("get{{.StructName}}Public", r.handler.Get{{.StructName}}Public) // {{.Description}}开放接口
}
{{- end}}
}
@@ -0,0 +1,16 @@
{{- if .IsAdd }}
// 请在 {{.Package}} 包的 enter.go 文件中的 ProviderSet 添加以下内容:
// New{{.StructName}}Service,
{{- else }}
package {{ .Package }}
import "github.com/google/wire"
// ProviderSet is {{.Package}} service providers.
// 包含 {{.Description}} 相关的服务层实现
// Service 层负责:
// 1. 请求类型转换(Request -> Model)
// 2. 事务管理
// 3. 调用 Biz 层 Usecase 完成业务逻辑
var ProviderSet = wire.NewSet(New{{.StructName}}Service)
{{- end }}
@@ -0,0 +1,245 @@
{{- if .IsAdd}}
// Get{{.StructName}}InfoList 新增搜索语句
{{ GenerateSearchConditions .Fields }}
// Get{{.StructName}}InfoList 新增排序语句 请自行在搜索语句中添加orderMap内容
{{- range .Fields}}
{{- if .Sort}}
orderMap["{{.ColumnName}}"] = true
{{- end}}
{{- end}}
{{- if .HasDataSource }}
// Get{{.StructName}}DataSource()方法新增关联语句
{{range $key, $value := .DataSourceMap}}
{{$key}} := make([]map[string]any, 0)
s.data.DB().Table("{{$value.Table}}"){{- if $value.HasDeletedAt}}.Where("deleted_at IS NULL"){{ end }}.Select("{{$value.Label}} as label,{{$value.Value}} as value").Scan(&{{$key}})
res["{{$key}}"] = {{$key}}
{{- end }}
{{- end }}
{{- else}}
package {{.Package}}
import (
{{- if not .OnlyTemplate }}
"context"
"{{.Module}}/internal/biz/{{.Package}}"
model "{{.Module}}/internal/data/model/{{.Package}}"
{{- if not .IsTree}}
{{.Package}}Req "{{.Module}}/internal/service/types/{{.Package}}/request"
{{- end }}
"github.com/go-kratos/kratos/v2/log"
"gorm.io/gorm"
{{- end }}
)
// {{.StructName}}Service {{.Description}}服务层
// 负责处理请求类型转换、事务管理,并调用 Biz 层 Usecase 完成业务逻辑
type {{.StructName}}Service struct {
uc *{{.Package}}.{{.StructName}}Usecase
db *gorm.DB
log *log.Helper
}
// New{{.StructName}}Service 创建{{.Description}}服务
// @param uc Biz 层 Usecase,包含业务逻辑
// @param db 数据库连接,用于事务管理
// @param logger 日志记录器
func New{{.StructName}}Service(uc *{{.Package}}.{{.StructName}}Usecase, db *gorm.DB, logger log.Logger) *{{.StructName}}Service {
return &{{.StructName}}Service{
uc: uc,
db: db,
log: log.NewHelper(logger),
}
}
{{- if not .OnlyTemplate }}
// Create{{.StructName}} 创建{{.Description}}记录
// @param ctx 上下文
// @param req 创建请求,包含{{.Description}}信息
// @return error 创建失败时返回错误
func (s *{{.StructName}}Service) Create{{.StructName}}(ctx context.Context, req *{{.Package}}Req.{{.StructName}}Request) error {
s.log.WithContext(ctx).Infof("Service: 创建{{.Description}}")
// 请求类型转换:将 Request 转换为 Model
{{.Abbreviation}} := req.To{{.StructName}}()
return s.uc.Create(ctx, {{.Abbreviation}})
}
// Create{{.StructName}}WithModel 使用 Model 创建{{.Description}}记录(兼容 Handler 直接调用)
// @param ctx 上下文
// @param {{.Abbreviation}} {{.Description}}模型
// @return error 创建失败时返回错误
func (s *{{.StructName}}Service) Create{{.StructName}}WithModel(ctx context.Context, {{.Abbreviation}} *model.{{.StructName}}) error {
s.log.WithContext(ctx).Infof("Service: 创建{{.Description}}(Model)")
return s.uc.Create(ctx, {{.Abbreviation}})
}
// Delete{{.StructName}} 删除{{.Description}}记录
// @param ctx 上下文
// @param {{.PrimaryField.FieldJson}} 主键ID
{{- if .AutoCreateResource }}
// @param userID 操作用户ID
{{- end }}
// @return error 删除失败时返回错误
{{- if .AutoCreateResource }}
// 注意:当启用 AutoCreateResource 时,删除操作使用事务确保 deleted_by 字段更新和删除操作的原子性
{{- end }}
func (s *{{.StructName}}Service) Delete{{.StructName}}(ctx context.Context, {{.PrimaryField.FieldJson}} {{.PrimaryField.FieldType}}{{- if .AutoCreateResource -}}, userID uint{{- end -}}) error {
s.log.WithContext(ctx).Infof("Service: 删除{{.Description}}, {{.PrimaryField.FieldJson}}: %v", {{.PrimaryField.FieldJson}})
{{- if .AutoCreateResource }}
// 使用事务确保 deleted_by 更新和删除操作的原子性
return s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
// 先更新 deleted_by 字段
if err := tx.Model(&model.{{.StructName}}{}).Where("{{.PrimaryField.ColumnName}} = ?", {{.PrimaryField.FieldJson}}).Update("deleted_by", userID).Error; err != nil {
s.log.WithContext(ctx).Errorf("更新 deleted_by 失败: %v", err)
return err
}
// 再执行删除
return s.uc.DeleteWithTx(ctx, tx, {{.PrimaryField.FieldJson}})
})
{{- else }}
return s.uc.Delete(ctx, {{.PrimaryField.FieldJson}})
{{- end }}
}
// Delete{{.StructName}}ByIds 批量删除{{.Description}}记录
// @param ctx 上下文
// @param {{.PrimaryField.FieldJson}}s 主键ID列表
{{- if .AutoCreateResource }}
// @param deletedBy 操作用户ID
{{- end }}
// @return error 删除失败时返回错误
{{- if .AutoCreateResource }}
// 注意:当启用 AutoCreateResource 时,批量删除操作使用事务确保 deleted_by 字段更新和删除操作的原子性
{{- end }}
func (s *{{.StructName}}Service) Delete{{.StructName}}ByIds(ctx context.Context, {{.PrimaryField.FieldJson}}s []{{.PrimaryField.FieldType}}{{- if .AutoCreateResource }}, deletedBy uint{{- end}}) error {
s.log.WithContext(ctx).Infof("Service: 批量删除{{.Description}}, 数量: %d", len({{.PrimaryField.FieldJson}}s))
{{- if .AutoCreateResource }}
// 使用事务确保 deleted_by 更新和删除操作的原子性
return s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
// 先批量更新 deleted_by 字段
if err := tx.Model(&model.{{.StructName}}{}).Where("{{.PrimaryField.ColumnName}} in ?", {{.PrimaryField.FieldJson}}s).Update("deleted_by", deletedBy).Error; err != nil {
s.log.WithContext(ctx).Errorf("批量更新 deleted_by 失败: %v", err)
return err
}
// 再执行批量删除
return s.uc.DeleteByIdsWithTx(ctx, tx, {{.PrimaryField.FieldJson}}s)
})
{{- else }}
return s.uc.DeleteByIds(ctx, {{.PrimaryField.FieldJson}}s)
{{- end }}
}
// Update{{.StructName}} 更新{{.Description}}记录
// @param ctx 上下文
// @param req 更新请求,包含{{.Description}}信息
// @return error 更新失败时返回错误
func (s *{{.StructName}}Service) Update{{.StructName}}(ctx context.Context, req *{{.Package}}Req.{{.StructName}}Request) error {
s.log.WithContext(ctx).Infof("Service: 更新{{.Description}}")
// 请求类型转换:将 Request 转换为 Model
{{.Abbreviation}} := req.To{{.StructName}}()
return s.uc.Update(ctx, {{.Abbreviation}})
}
// Update{{.StructName}}WithModel 使用 Model 更新{{.Description}}记录(兼容 Handler 直接调用)
// @param ctx 上下文
// @param {{.Abbreviation}} {{.Description}}模型
// @return error 更新失败时返回错误
func (s *{{.StructName}}Service) Update{{.StructName}}WithModel(ctx context.Context, {{.Abbreviation}} *model.{{.StructName}}) error {
s.log.WithContext(ctx).Infof("Service: 更新{{.Description}}(Model)")
return s.uc.Update(ctx, {{.Abbreviation}})
}
// Get{{.StructName}} 根据{{.PrimaryField.FieldJson}}获取{{.Description}}记录
// @param ctx 上下文
// @param {{.PrimaryField.FieldJson}} 主键ID
// @return *model.{{.StructName}} {{.Description}}记录
// @return error 查询失败时返回错误
func (s *{{.StructName}}Service) Get{{.StructName}}(ctx context.Context, {{.PrimaryField.FieldJson}} {{.PrimaryField.FieldType}}) (*model.{{.StructName}}, error) {
s.log.WithContext(ctx).Debugf("Service: 查询{{.Description}}, {{.PrimaryField.FieldJson}}: %v", {{.PrimaryField.FieldJson}})
return s.uc.FindByID(ctx, {{.PrimaryField.FieldJson}})
}
{{- if .IsTree }}
// Get{{.StructName}}InfoList 获取{{.Description}}列表(树形结构)
// @param ctx 上下文
// @return []*model.{{.StructName}} {{.Description}}列表
// @return error 查询失败时返回错误
func (s *{{.StructName}}Service) Get{{.StructName}}InfoList(ctx context.Context) ([]*model.{{.StructName}}, error) {
s.log.WithContext(ctx).Debug("Service: 获取{{.Description}}树形列表")
return s.uc.List(ctx)
}
{{- else }}
// Get{{.StructName}}InfoList 分页获取{{.Description}}列表
// @param ctx 上下文
// @param info 搜索条件,包含分页和筛选参数
// @return []*model.{{.StructName}} {{.Description}}列表
// @return int64 总记录数
// @return error 查询失败时返回错误
func (s *{{.StructName}}Service) Get{{.StructName}}InfoList(ctx context.Context, info *{{.Package}}Req.{{.StructName}}Search) ([]*model.{{.StructName}}, int64, error) {
s.log.WithContext(ctx).Debugf("Service: 获取{{.Description}}列表, 页码: %d, 每页: %d", info.Page, info.PageSize)
return s.uc.List(ctx, info)
}
{{- end }}
{{- if .HasDataSource }}
// Get{{.StructName}}DataSource 获取{{.StructName}}的数据源
// @param ctx 上下文
// @return map[string][]map[string]any 数据源映射
// @return error 查询失败时返回错误
func (s *{{.StructName}}Service) Get{{.StructName}}DataSource(ctx context.Context) (map[string][]map[string]any, error) {
s.log.WithContext(ctx).Debug("Service: 获取{{.Description}}数据源")
return s.uc.GetDataSource(ctx)
}
{{- end }}
// BatchCreate{{.StructName}} 批量创建{{.Description}}记录(带事务)
// @param ctx 上下文
// @param reqs 创建请求列表
// @return error 创建失败时返回错误,事务会自动回滚
func (s *{{.StructName}}Service) BatchCreate{{.StructName}}(ctx context.Context, reqs []*{{.Package}}Req.{{.StructName}}Request) error {
s.log.WithContext(ctx).Infof("Service: 批量创建{{.Description}}, 数量: %d", len(reqs))
return s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
for _, req := range reqs {
{{.Abbreviation}} := req.To{{.StructName}}()
if err := s.uc.Create(ctx, {{.Abbreviation}}); err != nil {
s.log.WithContext(ctx).Errorf("批量创建{{.Description}}失败: %v", err)
return err
}
}
return nil
})
}
// BatchUpdate{{.StructName}} 批量更新{{.Description}}记录(带事务)
// @param ctx 上下文
// @param reqs 更新请求列表
// @return error 更新失败时返回错误,事务会自动回滚
func (s *{{.StructName}}Service) BatchUpdate{{.StructName}}(ctx context.Context, reqs []*{{.Package}}Req.{{.StructName}}Request) error {
s.log.WithContext(ctx).Infof("Service: 批量更新{{.Description}}, 数量: %d", len(reqs))
return s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
for _, req := range reqs {
{{.Abbreviation}} := req.To{{.StructName}}()
if err := s.uc.Update(ctx, {{.Abbreviation}}); err != nil {
s.log.WithContext(ctx).Errorf("批量更新{{.Description}}失败: %v", err)
return err
}
}
return nil
})
}
{{- end }}
// Get{{.StructName}}Public 获取公开数据
// @param ctx 上下文
func (s *{{.StructName}}Service) Get{{.StructName}}Public(ctx context.Context) {
s.log.WithContext(ctx).Debug("Service: 获取{{.Description}}公开数据")
s.uc.GetPublic(ctx)
}
{{- end }}
@@ -0,0 +1,214 @@
{{- if .IsAdd}}
// 在 {{.StructName}}Search 结构体中新增如下字段
{{- range .Fields}}
{{- if .FieldSearchType}}
{{ GenerateSearchField . }}
{{- end}}
{{- end}}
// 在 {{.StructName}}ListRequest 结构体中新增如下字段
{{- range .Fields}}
{{- if .FieldSearchType}}
{{ GenerateSearchField . }}
{{- end}}
{{- end}}
// 在 {{.StructName}}Request 结构体中新增如下字段
{{- range .Fields}}
{{- if not .PrimaryKey}}
{{.FieldName}} {{.FieldType}} `json:"{{.FieldJson}}"{{if .Require}} binding:"required"{{end}}` // {{.FieldDesc}}
{{- end}}
{{- end}}
// 在 To{{.StructName}}() 方法中新增如下字段映射
{{- range .Fields}}
{{- if not .PrimaryKey}}
// {{.FieldName}}: r.{{.FieldName}},
{{- end}}
{{- end}}
// 在 From{{.StructName}}() 函数中新增如下字段映射
{{- range .Fields}}
{{- if not .PrimaryKey}}
// {{.FieldName}}: m.{{.FieldName}},
{{- end}}
{{- end}}
{{- else}}
package request
import (
{{- if .HasTimer }}
"time"
{{- end }}
{{- if .NeedJSON }}
"gorm.io/datatypes"
{{- end }}
model "{{.Module}}/internal/data/model/{{.Package}}"
"{{.Module}}/internal/service/types/common"
)
// {{.StructName}}Request {{.Description}}创建/更新请求
type {{.StructName}}Request struct {
{{- if .GvaModel }}
ID uint `json:"id"` // 主键ID
{{- else }}
{{.PrimaryField.FieldName}} {{.PrimaryField.FieldType}} `json:"{{.PrimaryField.FieldJson}}"` // {{.PrimaryField.FieldDesc}}
{{- end }}
{{- range .Fields}}
{{- if not .PrimaryKey}}
{{.FieldName}} {{.FieldType}} `json:"{{.FieldJson}}"{{if .Require}} binding:"required"{{end}}` // {{.FieldDesc}}
{{- end}}
{{- end}}
{{- if .AutoCreateResource }}
CreatedBy uint `json:"createdBy"` // 创建者
UpdatedBy uint `json:"updatedBy"` // 更新者
{{- end }}
}
// To{{.StructName}} 将请求转换为{{.Description}}模型
// 用于 Service 层进行请求类型转换
func (r *{{.StructName}}Request) To{{.StructName}}() *model.{{.StructName}} {
return &model.{{.StructName}}{
{{- if .GvaModel }}
KRA_MODEL: model.KRA_MODEL{ID: r.ID},
{{- else }}
{{.PrimaryField.FieldName}}: r.{{.PrimaryField.FieldName}},
{{- end }}
{{- range .Fields}}
{{- if not .PrimaryKey}}
{{.FieldName}}: r.{{.FieldName}},
{{- end}}
{{- end}}
{{- if .AutoCreateResource }}
CreatedBy: r.CreatedBy,
UpdatedBy: r.UpdatedBy,
{{- end }}
}
}
// From{{.StructName}} 从{{.Description}}模型创建请求
// 用于编辑场景,将数据库模型转换为请求格式
func From{{.StructName}}(m *model.{{.StructName}}) *{{.StructName}}Request {
if m == nil {
return nil
}
return &{{.StructName}}Request{
{{- if .GvaModel }}
ID: m.ID,
{{- else }}
{{.PrimaryField.FieldName}}: m.{{.PrimaryField.FieldName}},
{{- end }}
{{- range .Fields}}
{{- if not .PrimaryKey}}
{{.FieldName}}: m.{{.FieldName}},
{{- end}}
{{- end}}
{{- if .AutoCreateResource }}
CreatedBy: m.CreatedBy,
UpdatedBy: m.UpdatedBy,
{{- end }}
}
}
// {{.StructName}}IDRequest {{.Description}}ID请求
type {{.StructName}}IDRequest struct {
{{- if .GvaModel }}
ID int `json:"id" form:"id" binding:"required"` // 主键ID
{{- else }}
{{.PrimaryField.FieldName}} {{.PrimaryField.FieldType}} `json:"{{.PrimaryField.FieldJson}}" form:"{{.PrimaryField.FieldJson}}" binding:"required"` // {{.PrimaryField.FieldDesc}}
{{- end }}
}
// Uint 转换为uint类型
// 用于与数据库操作兼容
func (r *{{.StructName}}IDRequest) Uint() uint {
{{- if .GvaModel }}
return uint(r.ID)
{{- else }}
return uint(r.{{.PrimaryField.FieldName}})
{{- end }}
}
// {{.StructName}}IdsRequest {{.Description}}批量ID请求
type {{.StructName}}IdsRequest struct {
{{- if .GvaModel }}
Ids []int `json:"ids" form:"ids" binding:"required"` // 主键ID列表
{{- else }}
{{.PrimaryField.FieldName}}s []{{.PrimaryField.FieldType}} `json:"{{.PrimaryField.FieldJson}}s" form:"{{.PrimaryField.FieldJson}}s" binding:"required"` // {{.PrimaryField.FieldDesc}}列表
{{- end }}
}
// Uints 转换为[]uint类型
// 用于与数据库批量操作兼容
func (r *{{.StructName}}IdsRequest) Uints() []uint {
{{- if .GvaModel }}
result := make([]uint, len(r.Ids))
for i, id := range r.Ids {
result[i] = uint(id)
}
return result
{{- else }}
result := make([]uint, len(r.{{.PrimaryField.FieldName}}s))
for i, id := range r.{{.PrimaryField.FieldName}}s {
result[i] = uint(id)
}
return result
{{- end }}
}
// {{.StructName}}Search {{.Description}}搜索条件
// Deprecated: 请使用 {{.StructName}}ListRequest
type {{.StructName}}Search struct {
common.PageInfo
{{- if .GvaModel }}
CreatedAtRange []time.Time `json:"createdAtRange" form:"createdAtRange[]"` // 创建时间范围
{{- end }}
{{- range .Fields}}
{{- if .FieldSearchType}}
{{ GenerateSearchField . }}
{{- end}}
{{- end}}
{{- if .NeedSort}}
Sort string `json:"sort" form:"sort"` // 排序字段
Order string `json:"order" form:"order"` // 排序方式
{{- end}}
}
// {{.StructName}}ListRequest {{.Description}}列表请求(含分页)
type {{.StructName}}ListRequest struct {
common.PageInfo
{{- if .GvaModel }}
CreatedAtRange []time.Time `json:"createdAtRange" form:"createdAtRange[]"` // 创建时间范围
{{- end }}
{{- range .Fields}}
{{- if .FieldSearchType}}
{{ GenerateSearchField . }}
{{- end}}
{{- end}}
{{- if .NeedSort}}
Sort string `json:"sort" form:"sort"` // 排序字段
Order string `json:"order" form:"order"` // 排序方式
{{- end}}
}
// To{{.StructName}}Search 将列表请求转换为搜索条件
// 用于向后兼容
func (r *{{.StructName}}ListRequest) To{{.StructName}}Search() *{{.StructName}}Search {
return &{{.StructName}}Search{
PageInfo: r.PageInfo,
{{- if .GvaModel }}
CreatedAtRange: r.CreatedAtRange,
{{- end }}
{{- range .Fields}}
{{- if .FieldSearchType}}
{{.FieldName}}: r.{{.FieldName}},
{{- end}}
{{- end}}
{{- if .NeedSort}}
Sort: r.Sort,
Order: r.Order,
{{- end}}
}
}
{{- end }}