拓展接口响应

This commit is contained in:
2025-11-21 17:23:57 +08:00
parent 4224be8567
commit 7829ac9931
8 changed files with 142 additions and 49 deletions

View File

@@ -1663,7 +1663,7 @@ const docTemplate = `{
"parameters": [ "parameters": [
{ {
"type": "string", "type": "string",
"description": "按名称模糊查询", "description": "按营养名称模糊查询",
"name": "name", "name": "name",
"in": "query" "in": "query"
}, },
@@ -1684,6 +1684,12 @@ const docTemplate = `{
"description": "每页数量", "description": "每页数量",
"name": "page_size", "name": "page_size",
"in": "query" "in": "query"
},
{
"type": "string",
"description": "按原料名称模糊查询",
"name": "raw_material_name",
"in": "query"
} }
], ],
"responses": { "responses": {
@@ -2665,10 +2671,16 @@ const docTemplate = `{
"parameters": [ "parameters": [
{ {
"type": "string", "type": "string",
"description": "按名称模糊查询", "description": "按原料名称模糊查询",
"name": "name", "name": "name",
"in": "query" "in": "query"
}, },
{
"type": "string",
"description": "按营养名称模糊查询",
"name": "nutrient_name",
"in": "query"
},
{ {
"type": "string", "type": "string",
"description": "排序字段,例如 \"id DESC\"", "description": "排序字段,例如 \"id DESC\"",
@@ -3074,7 +3086,6 @@ const docTemplate = `{
}, },
{ {
"enum": [ "enum": [
7,
-1, -1,
0, 0,
1, 1,
@@ -3084,12 +3095,12 @@ const docTemplate = `{
5, 5,
-1, -1,
5, 5,
6 6,
7
], ],
"type": "integer", "type": "integer",
"format": "int32", "format": "int32",
"x-enum-varnames": [ "x-enum-varnames": [
"_numLevels",
"DebugLevel", "DebugLevel",
"InfoLevel", "InfoLevel",
"WarnLevel", "WarnLevel",
@@ -3099,7 +3110,8 @@ const docTemplate = `{
"FatalLevel", "FatalLevel",
"_minLevel", "_minLevel",
"_maxLevel", "_maxLevel",
"InvalidLevel" "InvalidLevel",
"_numLevels"
], ],
"name": "level", "name": "level",
"in": "query" "in": "query"
@@ -9646,7 +9658,6 @@ const docTemplate = `{
"type": "integer", "type": "integer",
"format": "int32", "format": "int32",
"enum": [ "enum": [
7,
-1, -1,
0, 0,
1, 1,
@@ -9656,10 +9667,10 @@ const docTemplate = `{
5, 5,
-1, -1,
5, 5,
6 6,
7
], ],
"x-enum-varnames": [ "x-enum-varnames": [
"_numLevels",
"DebugLevel", "DebugLevel",
"InfoLevel", "InfoLevel",
"WarnLevel", "WarnLevel",
@@ -9669,7 +9680,8 @@ const docTemplate = `{
"FatalLevel", "FatalLevel",
"_minLevel", "_minLevel",
"_maxLevel", "_maxLevel",
"InvalidLevel" "InvalidLevel",
"_numLevels"
] ]
} }
}, },

View File

@@ -1655,7 +1655,7 @@
"parameters": [ "parameters": [
{ {
"type": "string", "type": "string",
"description": "按名称模糊查询", "description": "按营养名称模糊查询",
"name": "name", "name": "name",
"in": "query" "in": "query"
}, },
@@ -1676,6 +1676,12 @@
"description": "每页数量", "description": "每页数量",
"name": "page_size", "name": "page_size",
"in": "query" "in": "query"
},
{
"type": "string",
"description": "按原料名称模糊查询",
"name": "raw_material_name",
"in": "query"
} }
], ],
"responses": { "responses": {
@@ -2657,10 +2663,16 @@
"parameters": [ "parameters": [
{ {
"type": "string", "type": "string",
"description": "按名称模糊查询", "description": "按原料名称模糊查询",
"name": "name", "name": "name",
"in": "query" "in": "query"
}, },
{
"type": "string",
"description": "按营养名称模糊查询",
"name": "nutrient_name",
"in": "query"
},
{ {
"type": "string", "type": "string",
"description": "排序字段,例如 \"id DESC\"", "description": "排序字段,例如 \"id DESC\"",
@@ -3066,7 +3078,6 @@
}, },
{ {
"enum": [ "enum": [
7,
-1, -1,
0, 0,
1, 1,
@@ -3076,12 +3087,12 @@
5, 5,
-1, -1,
5, 5,
6 6,
7
], ],
"type": "integer", "type": "integer",
"format": "int32", "format": "int32",
"x-enum-varnames": [ "x-enum-varnames": [
"_numLevels",
"DebugLevel", "DebugLevel",
"InfoLevel", "InfoLevel",
"WarnLevel", "WarnLevel",
@@ -3091,7 +3102,8 @@
"FatalLevel", "FatalLevel",
"_minLevel", "_minLevel",
"_maxLevel", "_maxLevel",
"InvalidLevel" "InvalidLevel",
"_numLevels"
], ],
"name": "level", "name": "level",
"in": "query" "in": "query"
@@ -9638,7 +9650,6 @@
"type": "integer", "type": "integer",
"format": "int32", "format": "int32",
"enum": [ "enum": [
7,
-1, -1,
0, 0,
1, 1,
@@ -9648,10 +9659,10 @@
5, 5,
-1, -1,
5, 5,
6 6,
7
], ],
"x-enum-varnames": [ "x-enum-varnames": [
"_numLevels",
"DebugLevel", "DebugLevel",
"InfoLevel", "InfoLevel",
"WarnLevel", "WarnLevel",
@@ -9661,7 +9672,8 @@
"FatalLevel", "FatalLevel",
"_minLevel", "_minLevel",
"_maxLevel", "_maxLevel",
"InvalidLevel" "InvalidLevel",
"_numLevels"
] ]
} }
}, },

View File

@@ -2517,7 +2517,6 @@ definitions:
- PlanTypeFilterSystem - PlanTypeFilterSystem
zapcore.Level: zapcore.Level:
enum: enum:
- 7
- -1 - -1
- 0 - 0
- 1 - 1
@@ -2528,10 +2527,10 @@ definitions:
- -1 - -1
- 5 - 5
- 6 - 6
- 7
format: int32 format: int32
type: integer type: integer
x-enum-varnames: x-enum-varnames:
- _numLevels
- DebugLevel - DebugLevel
- InfoLevel - InfoLevel
- WarnLevel - WarnLevel
@@ -2542,6 +2541,7 @@ definitions:
- _minLevel - _minLevel
- _maxLevel - _maxLevel
- InvalidLevel - InvalidLevel
- _numLevels
info: info:
contact: contact:
email: divano@example.com email: divano@example.com
@@ -3564,7 +3564,7 @@ paths:
get: get:
description: 获取所有营养种类的列表,支持分页和过滤。 description: 获取所有营养种类的列表,支持分页和过滤。
parameters: parameters:
- description: 按名称模糊查询 - description: 营养名称模糊查询
in: query in: query
name: name name: name
type: string type: string
@@ -3580,6 +3580,10 @@ paths:
in: query in: query
name: page_size name: page_size
type: integer type: integer
- description: 按原料名称模糊查询
in: query
name: raw_material_name
type: string
produces: produces:
- application/json - application/json
responses: responses:
@@ -4152,10 +4156,14 @@ paths:
get: get:
description: 获取所有原料的列表,支持分页和过滤。 description: 获取所有原料的列表,支持分页和过滤。
parameters: parameters:
- description: 按名称模糊查询 - description: 原料名称模糊查询
in: query in: query
name: name name: name
type: string type: string
- description: 按营养名称模糊查询
in: query
name: nutrient_name
type: string
- description: 排序字段,例如 "id DESC" - description: 排序字段,例如 "id DESC"
in: query in: query
name: order_by name: order_by
@@ -4390,7 +4398,6 @@ paths:
name: end_time name: end_time
type: string type: string
- enum: - enum:
- 7
- -1 - -1
- 0 - 0
- 1 - 1
@@ -4401,12 +4408,12 @@ paths:
- -1 - -1
- 5 - 5
- 6 - 6
- 7
format: int32 format: int32
in: query in: query
name: level name: level
type: integer type: integer
x-enum-varnames: x-enum-varnames:
- _numLevels
- DebugLevel - DebugLevel
- InfoLevel - InfoLevel
- WarnLevel - WarnLevel
@@ -4417,6 +4424,7 @@ paths:
- _minLevel - _minLevel
- _maxLevel - _maxLevel
- InvalidLevel - InvalidLevel
- _numLevels
- enum: - enum:
- 邮件 - 邮件
- 企业微信 - 企业微信

View File

@@ -41,7 +41,8 @@ type NutrientResponse struct {
type ListNutrientRequest struct { type ListNutrientRequest struct {
Page int `json:"page" query:"page"` // 页码 Page int `json:"page" query:"page"` // 页码
PageSize int `json:"page_size" query:"page_size"` // 每页数量 PageSize int `json:"page_size" query:"page_size"` // 每页数量
Name *string `json:"name" query:"name"` // 按名称模糊查询 Name *string `json:"name" query:"name"` // 按营养名称模糊查询
RawMaterialName *string `json:"raw_material_name" query:"raw_material_name"` // 按原料名称模糊查询
OrderBy string `json:"order_by" query:"order_by"` // 排序字段,例如 "id DESC" OrderBy string `json:"order_by" query:"order_by"` // 排序字段,例如 "id DESC"
} }
@@ -91,7 +92,8 @@ type RawMaterialResponse struct {
type ListRawMaterialRequest struct { type ListRawMaterialRequest struct {
Page int `json:"page" query:"page"` // 页码 Page int `json:"page" query:"page"` // 页码
PageSize int `json:"page_size" query:"page_size"` // 每页数量 PageSize int `json:"page_size" query:"page_size"` // 每页数量
Name *string `json:"name" query:"name"` // 按名称模糊查询 Name *string `json:"name" query:"name"` // 按原料名称模糊查询
NutrientName *string `json:"nutrient_name" query:"nutrient_name"` // 按营养名称模糊查询
OrderBy string `json:"order_by" query:"order_by"` // 排序字段,例如 "id DESC" OrderBy string `json:"order_by" query:"order_by"` // 排序字段,例如 "id DESC"
} }

View File

@@ -143,7 +143,12 @@ func (s *feedManagementServiceImpl) GetNutrient(ctx context.Context, id uint32)
func (s *feedManagementServiceImpl) ListNutrients(ctx context.Context, req *dto.ListNutrientRequest) (*dto.ListNutrientResponse, error) { func (s *feedManagementServiceImpl) ListNutrients(ctx context.Context, req *dto.ListNutrientRequest) (*dto.ListNutrientResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListNutrients") serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListNutrients")
nutrients, total, err := s.recipeSvc.ListNutrients(serviceCtx, req.Page, req.PageSize) opts := repository.NutrientListOptions{
Name: req.Name,
RawMaterialName: req.RawMaterialName,
OrderBy: req.OrderBy,
}
nutrients, total, err := s.recipeSvc.ListNutrients(serviceCtx, opts, req.Page, req.PageSize)
if err != nil { if err != nil {
return nil, fmt.Errorf("获取营养种类列表失败: %w", err) return nil, fmt.Errorf("获取营养种类列表失败: %w", err)
} }
@@ -218,7 +223,12 @@ func (s *feedManagementServiceImpl) GetRawMaterial(ctx context.Context, id uint3
func (s *feedManagementServiceImpl) ListRawMaterials(ctx context.Context, req *dto.ListRawMaterialRequest) (*dto.ListRawMaterialResponse, error) { func (s *feedManagementServiceImpl) ListRawMaterials(ctx context.Context, req *dto.ListRawMaterialRequest) (*dto.ListRawMaterialResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListRawMaterials") serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListRawMaterials")
rawMaterials, total, err := s.recipeSvc.ListRawMaterials(serviceCtx, req.Page, req.PageSize) opts := repository.RawMaterialListOptions{
Name: req.Name,
NutrientName: req.NutrientName,
OrderBy: req.OrderBy,
}
rawMaterials, total, err := s.recipeSvc.ListRawMaterials(serviceCtx, opts, req.Page, req.PageSize)
if err != nil { if err != nil {
return nil, fmt.Errorf("获取原料列表失败: %w", err) return nil, fmt.Errorf("获取原料列表失败: %w", err)
} }

View File

@@ -32,14 +32,14 @@ type Service interface {
UpdateNutrient(ctx context.Context, id uint32, name, description string) (*models.Nutrient, error) UpdateNutrient(ctx context.Context, id uint32, name, description string) (*models.Nutrient, error)
DeleteNutrient(ctx context.Context, id uint32) error DeleteNutrient(ctx context.Context, id uint32) error
GetNutrient(ctx context.Context, id uint32) (*models.Nutrient, error) GetNutrient(ctx context.Context, id uint32) (*models.Nutrient, error)
ListNutrients(ctx context.Context, page, pageSize int) ([]models.Nutrient, int64, error) ListNutrients(ctx context.Context, opts repository.NutrientListOptions, page, pageSize int) ([]models.Nutrient, int64, error)
// 原料相关接口 // 原料相关接口
CreateRawMaterial(ctx context.Context, name, description string) (*models.RawMaterial, error) CreateRawMaterial(ctx context.Context, name, description string) (*models.RawMaterial, error)
UpdateRawMaterial(ctx context.Context, id uint32, name, description string) (*models.RawMaterial, error) UpdateRawMaterial(ctx context.Context, id uint32, name, description string) (*models.RawMaterial, error)
DeleteRawMaterial(ctx context.Context, id uint32) error DeleteRawMaterial(ctx context.Context, id uint32) error
GetRawMaterial(ctx context.Context, id uint32) (*models.RawMaterial, error) GetRawMaterial(ctx context.Context, id uint32) (*models.RawMaterial, error)
ListRawMaterials(ctx context.Context, page, pageSize int) ([]models.RawMaterial, int64, error) ListRawMaterials(ctx context.Context, opts repository.RawMaterialListOptions, page, pageSize int) ([]models.RawMaterial, int64, error)
// 猪品种相关接口 // 猪品种相关接口
CreatePigBreed(ctx context.Context, breed *models.PigBreed) error CreatePigBreed(ctx context.Context, breed *models.PigBreed) error
@@ -175,10 +175,10 @@ func (s *recipeServiceImpl) GetNutrient(ctx context.Context, id uint32) (*models
} }
// ListNutrients 实现了列出营养种类的逻辑 // ListNutrients 实现了列出营养种类的逻辑
func (s *recipeServiceImpl) ListNutrients(ctx context.Context, page, pageSize int) ([]models.Nutrient, int64, error) { func (s *recipeServiceImpl) ListNutrients(ctx context.Context, opts repository.NutrientListOptions, page, pageSize int) ([]models.Nutrient, int64, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListNutrients") serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListNutrients")
nutrients, total, err := s.nutrientRepo.ListNutrients(serviceCtx, page, pageSize) nutrients, total, err := s.nutrientRepo.ListNutrients(serviceCtx, opts, page, pageSize)
if err != nil { if err != nil {
return nil, 0, fmt.Errorf("获取营养种类列表失败: %w", err) return nil, 0, fmt.Errorf("获取营养种类列表失败: %w", err)
} }
@@ -279,10 +279,10 @@ func (s *recipeServiceImpl) GetRawMaterial(ctx context.Context, id uint32) (*mod
} }
// ListRawMaterials 实现了列出原料的逻辑 // ListRawMaterials 实现了列出原料的逻辑
func (s *recipeServiceImpl) ListRawMaterials(ctx context.Context, page, pageSize int) ([]models.RawMaterial, int64, error) { func (s *recipeServiceImpl) ListRawMaterials(ctx context.Context, opts repository.RawMaterialListOptions, page, pageSize int) ([]models.RawMaterial, int64, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListRawMaterials") serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListRawMaterials")
rawMaterials, total, err := s.rawMaterialRepo.ListRawMaterials(serviceCtx, page, pageSize) rawMaterials, total, err := s.rawMaterialRepo.ListRawMaterials(serviceCtx, opts, page, pageSize)
if err != nil { if err != nil {
return nil, 0, fmt.Errorf("获取原料列表失败: %w", err) return nil, 0, fmt.Errorf("获取原料列表失败: %w", err)
} }

View File

@@ -11,12 +11,19 @@ import (
"gorm.io/gorm" "gorm.io/gorm"
) )
// NutrientListOptions 定义了查询营养种类列表时的筛选条件
type NutrientListOptions struct {
Name *string
RawMaterialName *string
OrderBy string
}
// NutrientRepository 定义了与营养种类相关的数据库操作接口 // NutrientRepository 定义了与营养种类相关的数据库操作接口
type NutrientRepository interface { type NutrientRepository interface {
CreateNutrient(ctx context.Context, nutrient *models.Nutrient) error CreateNutrient(ctx context.Context, nutrient *models.Nutrient) error
GetNutrientByID(ctx context.Context, id uint32) (*models.Nutrient, error) GetNutrientByID(ctx context.Context, id uint32) (*models.Nutrient, error)
GetNutrientByName(ctx context.Context, name string) (*models.Nutrient, error) GetNutrientByName(ctx context.Context, name string) (*models.Nutrient, error)
ListNutrients(ctx context.Context, page, pageSize int) ([]models.Nutrient, int64, error) ListNutrients(ctx context.Context, opts NutrientListOptions, page, pageSize int) ([]models.Nutrient, int64, error)
UpdateNutrient(ctx context.Context, nutrient *models.Nutrient) error UpdateNutrient(ctx context.Context, nutrient *models.Nutrient) error
DeleteNutrient(ctx context.Context, id uint32) error DeleteNutrient(ctx context.Context, id uint32) error
} }
@@ -61,19 +68,36 @@ func (r *gormNutrientRepository) GetNutrientByName(ctx context.Context, name str
} }
// ListNutrients 列出所有营养种类(分页),并预加载关联的原料信息 // ListNutrients 列出所有营养种类(分页),并预加载关联的原料信息
func (r *gormNutrientRepository) ListNutrients(ctx context.Context, page, pageSize int) ([]models.Nutrient, int64, error) { func (r *gormNutrientRepository) ListNutrients(ctx context.Context, opts NutrientListOptions, page, pageSize int) ([]models.Nutrient, int64, error) {
repoCtx := logs.AddFuncName(ctx, r.ctx, "ListNutrients") repoCtx := logs.AddFuncName(ctx, r.ctx, "ListNutrients")
var nutrients []models.Nutrient var nutrients []models.Nutrient
var total int64 var total int64
db := r.db.WithContext(repoCtx).Model(&models.Nutrient{}) db := r.db.WithContext(repoCtx).Model(&models.Nutrient{})
// 应用筛选条件
if opts.Name != nil && *opts.Name != "" {
db = db.Where("name LIKE ?", "%"+*opts.Name+"%")
}
// 如果传入了原料名称,则使用子查询进行筛选
if opts.RawMaterialName != nil && *opts.RawMaterialName != "" {
subQuery := r.db.Model(&models.RawMaterialNutrient{}).
Select("nutrient_id").
Joins("JOIN raw_materials ON raw_materials.id = raw_material_nutrients.raw_material_id").
Where("raw_materials.name LIKE ?", "%"+*opts.RawMaterialName+"%")
db = db.Where("id IN (?)", subQuery)
}
// 首先计算总数 // 首先计算总数
if err := db.Count(&total).Error; err != nil { if err := db.Count(&total).Error; err != nil {
return nil, 0, err return nil, 0, err
} }
// 然后应用分页并获取数据 // 然后应用排序、分页并获取数据
if opts.OrderBy != "" {
db = db.Order(opts.OrderBy)
}
offset := (page - 1) * pageSize offset := (page - 1) * pageSize
if err := db.Preload("RawMaterialNutrients.RawMaterial").Offset(offset).Limit(pageSize).Find(&nutrients).Error; err != nil { if err := db.Preload("RawMaterialNutrients.RawMaterial").Offset(offset).Limit(pageSize).Find(&nutrients).Error; err != nil {
return nil, 0, err return nil, 0, err

View File

@@ -11,12 +11,19 @@ import (
"gorm.io/gorm" "gorm.io/gorm"
) )
// RawMaterialListOptions 定义了查询原料列表时的筛选条件
type RawMaterialListOptions struct {
Name *string
NutrientName *string
OrderBy string
}
// RawMaterialRepository 定义了与原料相关的数据库操作接口 // RawMaterialRepository 定义了与原料相关的数据库操作接口
type RawMaterialRepository interface { type RawMaterialRepository interface {
CreateRawMaterial(ctx context.Context, rawMaterial *models.RawMaterial) error CreateRawMaterial(ctx context.Context, rawMaterial *models.RawMaterial) error
GetRawMaterialByID(ctx context.Context, id uint32) (*models.RawMaterial, error) GetRawMaterialByID(ctx context.Context, id uint32) (*models.RawMaterial, error)
GetRawMaterialByName(ctx context.Context, name string) (*models.RawMaterial, error) GetRawMaterialByName(ctx context.Context, name string) (*models.RawMaterial, error)
ListRawMaterials(ctx context.Context, page, pageSize int) ([]models.RawMaterial, int64, error) ListRawMaterials(ctx context.Context, opts RawMaterialListOptions, page, pageSize int) ([]models.RawMaterial, int64, error)
UpdateRawMaterial(ctx context.Context, rawMaterial *models.RawMaterial) error UpdateRawMaterial(ctx context.Context, rawMaterial *models.RawMaterial) error
DeleteRawMaterial(ctx context.Context, id uint32) error DeleteRawMaterial(ctx context.Context, id uint32) error
@@ -64,20 +71,38 @@ func (r *gormRawMaterialRepository) GetRawMaterialByName(ctx context.Context, na
return &rawMaterial, nil return &rawMaterial, nil
} }
// ListRawMaterials 列出所有原料(分页),并预加载关联的营养素信息 // ListRawMaterials 列出所有原料(分页),支持按名称和营养名称筛选
func (r *gormRawMaterialRepository) ListRawMaterials(ctx context.Context, page, pageSize int) ([]models.RawMaterial, int64, error) { func (r *gormRawMaterialRepository) ListRawMaterials(ctx context.Context, opts RawMaterialListOptions, page, pageSize int) ([]models.RawMaterial, int64, error) {
repoCtx := logs.AddFuncName(ctx, r.ctx, "ListRawMaterials") repoCtx := logs.AddFuncName(ctx, r.ctx, "ListRawMaterials")
var rawMaterials []models.RawMaterial var rawMaterials []models.RawMaterial
var total int64 var total int64
db := r.db.WithContext(repoCtx).Model(&models.RawMaterial{}) db := r.db.WithContext(repoCtx).Model(&models.RawMaterial{})
// 应用筛选条件
if opts.Name != nil && *opts.Name != "" {
db = db.Where("name LIKE ?", "%"+*opts.Name+"%")
}
// 如果传入了营养名称,则使用子查询进行筛选
if opts.NutrientName != nil && *opts.NutrientName != "" {
// 子查询:从 raw_material_nutrients 和 nutrients 表中找到所有包含该营养的 raw_material_id
subQuery := r.db.Model(&models.RawMaterialNutrient{}).
Select("raw_material_id").
Joins("JOIN nutrients ON nutrients.id = raw_material_nutrients.nutrient_id").
Where("nutrients.name LIKE ?", "%"+*opts.NutrientName+"%")
db = db.Where("id IN (?)", subQuery)
}
// 首先计算总数 // 首先计算总数
if err := db.Count(&total).Error; err != nil { if err := db.Count(&total).Error; err != nil {
return nil, 0, err return nil, 0, err
} }
// 然后应用分页并获取数据 // 然后应用排序、分页并获取数据
if opts.OrderBy != "" {
db = db.Order(opts.OrderBy)
}
offset := (page - 1) * pageSize offset := (page - 1) * pageSize
if err := db.Preload("RawMaterialNutrients.Nutrient").Offset(offset).Limit(pageSize).Find(&rawMaterials).Error; err != nil { if err := db.Preload("RawMaterialNutrients.Nutrient").Offset(offset).Limit(pageSize).Find(&rawMaterials).Error; err != nil {
return nil, 0, err return nil, 0, err