{{- $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}}
