实现配方领域的web接口
This commit is contained in:
202
internal/app/dto/feed_converter.go
Normal file
202
internal/app/dto/feed_converter.go
Normal file
@@ -0,0 +1,202 @@
|
||||
package dto
|
||||
|
||||
import (
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
|
||||
)
|
||||
|
||||
// ConvertNutrientToDTO 将 models.Nutrient 转换为 NutrientResponse DTO
|
||||
func ConvertNutrientToDTO(nutrient *models.Nutrient) *NutrientResponse {
|
||||
if nutrient == nil {
|
||||
return nil
|
||||
}
|
||||
return &NutrientResponse{
|
||||
ID: nutrient.ID,
|
||||
CreatedAt: nutrient.CreatedAt,
|
||||
UpdatedAt: nutrient.UpdatedAt,
|
||||
Name: nutrient.Name,
|
||||
Description: nutrient.Description,
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertNutrientListToDTO 将 []models.Nutrient 转换为 ListNutrientResponse DTO
|
||||
func ConvertNutrientListToDTO(nutrients []models.Nutrient, total int64, page, pageSize int) *ListNutrientResponse {
|
||||
nutrientDTOs := make([]NutrientResponse, len(nutrients))
|
||||
for i, n := range nutrients {
|
||||
nutrientDTOs[i] = *ConvertNutrientToDTO(&n)
|
||||
}
|
||||
|
||||
return &ListNutrientResponse{
|
||||
List: nutrientDTOs,
|
||||
Pagination: PaginationDTO{
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
Total: total,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertRawMaterialToDTO 将 models.RawMaterial 转换为 RawMaterialResponse DTO
|
||||
func ConvertRawMaterialToDTO(rm *models.RawMaterial) *RawMaterialResponse {
|
||||
if rm == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
rawMaterialNutrientDTOs := make([]RawMaterialNutrientDTO, len(rm.RawMaterialNutrients))
|
||||
for i, rmn := range rm.RawMaterialNutrients {
|
||||
rawMaterialNutrientDTOs[i] = RawMaterialNutrientDTO{
|
||||
ID: rmn.ID,
|
||||
CreatedAt: rmn.CreatedAt,
|
||||
UpdatedAt: rmn.UpdatedAt,
|
||||
NutrientID: rmn.NutrientID,
|
||||
Nutrient: rmn.Nutrient.Name, // 假设 Nutrient 已经被预加载
|
||||
Value: rmn.Value,
|
||||
}
|
||||
}
|
||||
|
||||
return &RawMaterialResponse{
|
||||
ID: rm.ID,
|
||||
CreatedAt: rm.CreatedAt,
|
||||
UpdatedAt: rm.UpdatedAt,
|
||||
Name: rm.Name,
|
||||
Description: rm.Description,
|
||||
RawMaterialNutrients: rawMaterialNutrientDTOs,
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertRawMaterialListToDTO 将 []models.RawMaterial 转换为 ListRawMaterialResponse DTO
|
||||
func ConvertRawMaterialListToDTO(rawMaterials []models.RawMaterial, total int64, page, pageSize int) *ListRawMaterialResponse {
|
||||
rawMaterialDTOs := make([]RawMaterialResponse, len(rawMaterials))
|
||||
for i, rm := range rawMaterials {
|
||||
rawMaterialDTOs[i] = *ConvertRawMaterialToDTO(&rm)
|
||||
}
|
||||
|
||||
return &ListRawMaterialResponse{
|
||||
List: rawMaterialDTOs,
|
||||
Pagination: PaginationDTO{
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
Total: total,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertPigBreedToDTO 将 models.PigBreed 转换为 PigBreedResponse DTO
|
||||
func ConvertPigBreedToDTO(breed *models.PigBreed) *PigBreedResponse {
|
||||
if breed == nil {
|
||||
return nil
|
||||
}
|
||||
return &PigBreedResponse{
|
||||
ID: breed.ID,
|
||||
CreatedAt: breed.CreatedAt,
|
||||
UpdatedAt: breed.UpdatedAt,
|
||||
Name: breed.Name,
|
||||
Description: breed.Description,
|
||||
ParentInfo: breed.ParentInfo,
|
||||
AppearanceFeatures: breed.AppearanceFeatures,
|
||||
BreedAdvantages: breed.BreedAdvantages,
|
||||
BreedDisadvantages: breed.BreedDisadvantages,
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertPigBreedListToDTO 将 []models.PigBreed 转换为 ListPigBreedResponse DTO
|
||||
func ConvertPigBreedListToDTO(breeds []models.PigBreed, total int64, page, pageSize int) *ListPigBreedResponse {
|
||||
breedDTOs := make([]PigBreedResponse, len(breeds))
|
||||
for i, b := range breeds {
|
||||
breedDTOs[i] = *ConvertPigBreedToDTO(&b)
|
||||
}
|
||||
|
||||
return &ListPigBreedResponse{
|
||||
List: breedDTOs,
|
||||
Pagination: PaginationDTO{
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
Total: total,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertPigAgeStageToDTO 将 models.PigAgeStage 转换为 PigAgeStageResponse DTO
|
||||
func ConvertPigAgeStageToDTO(ageStage *models.PigAgeStage) *PigAgeStageResponse {
|
||||
if ageStage == nil {
|
||||
return nil
|
||||
}
|
||||
return &PigAgeStageResponse{
|
||||
ID: ageStage.ID,
|
||||
CreatedAt: ageStage.CreatedAt,
|
||||
UpdatedAt: ageStage.UpdatedAt,
|
||||
Name: ageStage.Name,
|
||||
Description: ageStage.Description,
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertPigAgeStageListToDTO 将 []models.PigAgeStage 转换为 ListPigAgeStageResponse DTO
|
||||
func ConvertPigAgeStageListToDTO(ageStages []models.PigAgeStage, total int64, page, pageSize int) *ListPigAgeStageResponse {
|
||||
ageStageDTOs := make([]PigAgeStageResponse, len(ageStages))
|
||||
for i, as := range ageStages {
|
||||
ageStageDTOs[i] = *ConvertPigAgeStageToDTO(&as)
|
||||
}
|
||||
|
||||
return &ListPigAgeStageResponse{
|
||||
List: ageStageDTOs,
|
||||
Pagination: PaginationDTO{
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
Total: total,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertPigTypeToDTO 将 models.PigType 转换为 PigTypeResponse DTO
|
||||
func ConvertPigTypeToDTO(pt *models.PigType) *PigTypeResponse {
|
||||
if pt == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
pigNutrientRequirementDTOs := make([]PigNutrientRequirementDTO, len(pt.PigNutrientRequirements))
|
||||
for i, pnr := range pt.PigNutrientRequirements {
|
||||
pigNutrientRequirementDTOs[i] = PigNutrientRequirementDTO{
|
||||
ID: pnr.ID,
|
||||
CreatedAt: pnr.CreatedAt,
|
||||
UpdatedAt: pnr.UpdatedAt,
|
||||
NutrientID: pnr.NutrientID,
|
||||
NutrientName: pnr.Nutrient.Name, // 假设 Nutrient 已经被预加载
|
||||
MinRequirement: pnr.MinRequirement,
|
||||
MaxRequirement: pnr.MaxRequirement,
|
||||
}
|
||||
}
|
||||
|
||||
return &PigTypeResponse{
|
||||
ID: pt.ID,
|
||||
CreatedAt: pt.CreatedAt,
|
||||
UpdatedAt: pt.UpdatedAt,
|
||||
BreedID: pt.BreedID,
|
||||
BreedName: pt.Breed.Name, // 假设 Breed 已经被预加载
|
||||
AgeStageID: pt.AgeStageID,
|
||||
AgeStageName: pt.AgeStage.Name, // 假设 AgeStage 已经被预加载
|
||||
Description: pt.Description,
|
||||
DailyFeedIntake: pt.DailyFeedIntake,
|
||||
DailyGainWeight: pt.DailyGainWeight,
|
||||
MinDays: pt.MinDays,
|
||||
MaxDays: pt.MaxDays,
|
||||
MinWeight: pt.MinWeight,
|
||||
MaxWeight: pt.MaxWeight,
|
||||
PigNutrientRequirements: pigNutrientRequirementDTOs,
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertPigTypeListToDTO 将 []models.PigType 转换为 ListPigTypeResponse DTO
|
||||
func ConvertPigTypeListToDTO(pigTypes []models.PigType, total int64, page, pageSize int) *ListPigTypeResponse {
|
||||
pigTypeDTOs := make([]PigTypeResponse, len(pigTypes))
|
||||
for i, pt := range pigTypes {
|
||||
pigTypeDTOs[i] = *ConvertPigTypeToDTO(&pt)
|
||||
}
|
||||
|
||||
return &ListPigTypeResponse{
|
||||
List: pigTypeDTOs,
|
||||
Pagination: PaginationDTO{
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
Total: total,
|
||||
},
|
||||
}
|
||||
}
|
||||
261
internal/app/dto/feed_dto.go
Normal file
261
internal/app/dto/feed_dto.go
Normal file
@@ -0,0 +1,261 @@
|
||||
package dto
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// =============================================================================================================
|
||||
// 营养种类 (Nutrient) 相关 DTO
|
||||
// =============================================================================================================
|
||||
|
||||
// CreateNutrientRequest 创建营养种类的请求体
|
||||
type CreateNutrientRequest struct {
|
||||
Name string `json:"name" validate:"required,max=100"` // 营养素名称
|
||||
Description string `json:"description" validate:"max=255"` // 描述
|
||||
}
|
||||
|
||||
// UpdateNutrientRequest 更新营养种类的请求体
|
||||
type UpdateNutrientRequest struct {
|
||||
Name string `json:"name" validate:"required,max=100"` // 营养素名称
|
||||
Description string `json:"description" validate:"max=255"` // 描述
|
||||
}
|
||||
|
||||
// NutrientResponse 营养种类响应体
|
||||
type NutrientResponse struct {
|
||||
ID uint32 `json:"id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
// ListNutrientRequest 定义了获取营养种类列表的请求参数
|
||||
type ListNutrientRequest struct {
|
||||
Page int `json:"page" query:"page"` // 页码
|
||||
PageSize int `json:"page_size" query:"page_size"` // 每页数量
|
||||
Name *string `json:"name" query:"name"` // 按名称模糊查询
|
||||
OrderBy string `json:"order_by" query:"order_by"` // 排序字段,例如 "id DESC"
|
||||
}
|
||||
|
||||
// ListNutrientResponse 是获取营养种类列表的响应结构
|
||||
type ListNutrientResponse struct {
|
||||
List []NutrientResponse `json:"list"`
|
||||
Pagination PaginationDTO `json:"pagination"`
|
||||
}
|
||||
|
||||
// =============================================================================================================
|
||||
// 原料 (RawMaterial) 相关 DTO
|
||||
// =============================================================================================================
|
||||
|
||||
// CreateRawMaterialRequest 创建原料的请求体
|
||||
type CreateRawMaterialRequest struct {
|
||||
Name string `json:"name" validate:"required,max=100"` // 原料名称
|
||||
Description string `json:"description" validate:"max=255"` // 描述
|
||||
}
|
||||
|
||||
// UpdateRawMaterialRequest 更新原料的请求体
|
||||
type UpdateRawMaterialRequest struct {
|
||||
Name string `json:"name" validate:"required,max=100"` // 原料名称
|
||||
Description string `json:"description" validate:"max=255"` // 描述
|
||||
}
|
||||
|
||||
// RawMaterialNutrientDTO 原料营养素响应体
|
||||
type RawMaterialNutrientDTO struct {
|
||||
ID uint32 `json:"id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
NutrientID uint32 `json:"nutrient_id"`
|
||||
Nutrient string `json:"nutrient_name"` // 营养素名称
|
||||
Value float32 `json:"value"` // 营养价值含量
|
||||
}
|
||||
|
||||
// RawMaterialResponse 原料响应体
|
||||
type RawMaterialResponse struct {
|
||||
ID uint32 `json:"id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
RawMaterialNutrients []RawMaterialNutrientDTO `json:"raw_material_nutrients"` // 关联的营养素信息
|
||||
}
|
||||
|
||||
// ListRawMaterialRequest 定义了获取原料列表的请求参数
|
||||
type ListRawMaterialRequest struct {
|
||||
Page int `json:"page" query:"page"` // 页码
|
||||
PageSize int `json:"page_size" query:"page_size"` // 每页数量
|
||||
Name *string `json:"name" query:"name"` // 按名称模糊查询
|
||||
OrderBy string `json:"order_by" query:"order_by"` // 排序字段,例如 "id DESC"
|
||||
}
|
||||
|
||||
// ListRawMaterialResponse 是获取原料列表的响应结构
|
||||
type ListRawMaterialResponse struct {
|
||||
List []RawMaterialResponse `json:"list"`
|
||||
Pagination PaginationDTO `json:"pagination"`
|
||||
}
|
||||
|
||||
// =============================================================================================================
|
||||
// 猪品种 (PigBreed) 相关 DTO
|
||||
// =============================================================================================================
|
||||
|
||||
// CreatePigBreedRequest 创建猪品种的请求体
|
||||
type CreatePigBreedRequest struct {
|
||||
Name string `json:"name" validate:"required,max=50"` // 品种名称
|
||||
Description string `json:"description"` // 其他描述
|
||||
ParentInfo string `json:"parent_info"` // 父母信息
|
||||
AppearanceFeatures string `json:"appearance_features"` // 外貌特征
|
||||
BreedAdvantages string `json:"breed_advantages"` // 品种优点
|
||||
BreedDisadvantages string `json:"breed_disadvantages"` // 品种缺点
|
||||
}
|
||||
|
||||
// UpdatePigBreedRequest 更新猪品种的请求体
|
||||
type UpdatePigBreedRequest struct {
|
||||
Name string `json:"name" validate:"required,max=50"` // 品种名称
|
||||
Description string `json:"description"` // 其他描述
|
||||
ParentInfo string `json:"parent_info"` // 父母信息
|
||||
AppearanceFeatures string `json:"appearance_features"` // 外貌特征
|
||||
BreedAdvantages string `json:"breed_advantages"` // 品种优点
|
||||
BreedDisadvantages string `json:"breed_disadvantages"` // 品种缺点
|
||||
}
|
||||
|
||||
// PigBreedResponse 猪品种响应体
|
||||
type PigBreedResponse struct {
|
||||
ID uint32 `json:"id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
ParentInfo string `json:"parent_info"`
|
||||
AppearanceFeatures string `json:"appearance_features"`
|
||||
BreedAdvantages string `json:"breed_advantages"`
|
||||
BreedDisadvantages string `json:"breed_disadvantages"`
|
||||
}
|
||||
|
||||
// ListPigBreedRequest 定义了获取猪品种列表的请求参数
|
||||
type ListPigBreedRequest struct {
|
||||
Page int `json:"page" query:"page"` // 页码
|
||||
PageSize int `json:"page_size" query:"page_size"` // 每页数量
|
||||
Name *string `json:"name" query:"name"` // 按名称模糊查询
|
||||
OrderBy string `json:"order_by" query:"order_by"` // 排序字段,例如 "id DESC"
|
||||
}
|
||||
|
||||
// ListPigBreedResponse 是获取猪品种列表的响应结构
|
||||
type ListPigBreedResponse struct {
|
||||
List []PigBreedResponse `json:"list"`
|
||||
Pagination PaginationDTO `json:"pagination"`
|
||||
}
|
||||
|
||||
// =============================================================================================================
|
||||
// 猪年龄阶段 (PigAgeStage) 相关 DTO
|
||||
// =============================================================================================================
|
||||
|
||||
// CreatePigAgeStageRequest 创建猪年龄阶段的请求体
|
||||
type CreatePigAgeStageRequest struct {
|
||||
Name string `json:"name" validate:"required,max=50"` // 年龄阶段名称
|
||||
Description string `json:"description" validate:"max=255"` // 阶段描述
|
||||
}
|
||||
|
||||
// UpdatePigAgeStageRequest 更新猪年龄阶段的请求体
|
||||
type UpdatePigAgeStageRequest struct {
|
||||
Name string `json:"name" validate:"required,max=50"` // 年龄阶段名称
|
||||
Description string `json:"description" validate:"max=255"` // 阶段描述
|
||||
}
|
||||
|
||||
// PigAgeStageResponse 猪年龄阶段响应体
|
||||
type PigAgeStageResponse struct {
|
||||
ID uint32 `json:"id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
// ListPigAgeStageRequest 定义了获取猪年龄阶段列表的请求参数
|
||||
type ListPigAgeStageRequest struct {
|
||||
Page int `json:"page" query:"page"` // 页码
|
||||
PageSize int `json:"page_size" query:"page_size"` // 每页数量
|
||||
Name *string `json:"name" query:"name"` // 按名称模糊查询
|
||||
OrderBy string `json:"order_by" query:"order_by"` // 排序字段,例如 "id DESC"
|
||||
}
|
||||
|
||||
// ListPigAgeStageResponse 是获取猪年龄阶段列表的响应结构
|
||||
type ListPigAgeStageResponse struct {
|
||||
List []PigAgeStageResponse `json:"list"`
|
||||
Pagination PaginationDTO `json:"pagination"`
|
||||
}
|
||||
|
||||
// =============================================================================================================
|
||||
// 猪类型 (PigType) 相关 DTO
|
||||
// =============================================================================================================
|
||||
|
||||
// CreatePigTypeRequest 创建猪类型的请求体
|
||||
type CreatePigTypeRequest struct {
|
||||
BreedID uint32 `json:"breed_id" validate:"required"` // 关联的猪品种ID
|
||||
AgeStageID uint32 `json:"age_stage_id" validate:"required"` // 关联的猪年龄阶段ID
|
||||
Description string `json:"description" validate:"max=255"` // 该猪类型的描述或特点
|
||||
DailyFeedIntake float32 `json:"daily_feed_intake"` // 理论日均食量 (g/天)
|
||||
DailyGainWeight float32 `json:"daily_gain_weight"` // 理论日增重 (g/天)
|
||||
MinDays uint32 `json:"min_days"` // 该猪类型在该年龄阶段的最小日龄
|
||||
MaxDays uint32 `json:"max_days"` // 该猪类型在该年龄阶段的最大日龄
|
||||
MinWeight float32 `json:"min_weight"` // 该猪类型在该年龄阶段的最小体重 (g)
|
||||
MaxWeight float32 `json:"max_weight"` // 该猪类型在该年龄阶段的最大体重 (g)
|
||||
}
|
||||
|
||||
// UpdatePigTypeRequest 更新猪类型的请求体
|
||||
type UpdatePigTypeRequest struct {
|
||||
BreedID uint32 `json:"breed_id" validate:"required"` // 关联的猪品种ID
|
||||
AgeStageID uint32 `json:"age_stage_id" validate:"required"` // 关联的猪年龄阶段ID
|
||||
Description string `json:"description" validate:"max=255"` // 该猪类型的描述或特点
|
||||
DailyFeedIntake float32 `json:"daily_feed_intake"` // 理论日均食量 (g/天)
|
||||
DailyGainWeight float32 `json:"daily_gain_weight"` // 理论日增重 (g/天)
|
||||
MinDays uint32 `json:"min_days"` // 该猪类型在该年龄阶段的最小日龄
|
||||
MaxDays uint32 `json:"max_days"` // 该猪类型在该年龄阶段的最大日龄
|
||||
MinWeight float32 `json:"min_weight"` // 该猪类型在该年龄阶段的最小体重 (g)
|
||||
MaxWeight float32 `json:"max_weight"` // 该猪类型在该年龄阶段的最大体重 (g)
|
||||
}
|
||||
|
||||
// PigNutrientRequirementDTO 猪营养需求响应体
|
||||
type PigNutrientRequirementDTO struct {
|
||||
ID uint32 `json:"id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
NutrientID uint32 `json:"nutrient_id"`
|
||||
NutrientName string `json:"nutrient_name"` // 营养素名称
|
||||
MinRequirement float32 `json:"min_requirement"` // 最低营养需求量
|
||||
MaxRequirement float32 `json:"max_requirement"` // 最高营养需求量
|
||||
}
|
||||
|
||||
// PigTypeResponse 猪类型响应体
|
||||
type PigTypeResponse struct {
|
||||
ID uint32 `json:"id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
BreedID uint32 `json:"breed_id"`
|
||||
BreedName string `json:"breed_name"` // 猪品种名称
|
||||
AgeStageID uint32 `json:"age_stage_id"`
|
||||
AgeStageName string `json:"age_stage_name"` // 猪年龄阶段名称
|
||||
Description string `json:"description"`
|
||||
DailyFeedIntake float32 `json:"daily_feed_intake"`
|
||||
DailyGainWeight float32 `json:"daily_gain_weight"`
|
||||
MinDays uint32 `json:"min_days"`
|
||||
MaxDays uint32 `json:"max_days"`
|
||||
MinWeight float32 `json:"min_weight"`
|
||||
MaxWeight float32 `json:"max_weight"`
|
||||
PigNutrientRequirements []PigNutrientRequirementDTO `json:"pig_nutrient_requirements"` // 关联的营养需求
|
||||
}
|
||||
|
||||
// ListPigTypeRequest 定义了获取猪类型列表的请求参数
|
||||
type ListPigTypeRequest struct {
|
||||
Page int `json:"page" query:"page"` // 页码
|
||||
PageSize int `json:"page_size" query:"page_size"` // 每页数量
|
||||
BreedID *uint32 `json:"breed_id" query:"breed_id"` // 关联的猪品种ID
|
||||
AgeStageID *uint32 `json:"age_stage_id" query:"age_stage_id"` // 关联的猪年龄阶段ID
|
||||
BreedName *string `json:"breed_name" query:"breed_name"` // 关联的猪品种名称 (用于模糊查询)
|
||||
AgeStageName *string `json:"age_stage_name" query:"age_stage_name"` // 关联的猪年龄阶段名称 (用于模糊查询)
|
||||
OrderBy string `json:"order_by" query:"order_by"` // 排序字段,例如 "id DESC"
|
||||
}
|
||||
|
||||
// ListPigTypeResponse 是获取猪类型列表的响应结构
|
||||
type ListPigTypeResponse struct {
|
||||
List []PigTypeResponse `json:"list"`
|
||||
Pagination PaginationDTO `json:"pagination"`
|
||||
}
|
||||
Reference in New Issue
Block a user