实现修改原料营养信息
This commit is contained in:
@@ -56,3 +56,4 @@ http://git.huangwc.com/pig/pig-farm-controller/issues/66
|
||||
6. 实现从json读取猪营养需求并写入数据库
|
||||
7. 实现配方领域关于猪模型和营养需求的增删改查
|
||||
8. 实现配方领域的web接口
|
||||
9. 实现修改原料营养信息
|
||||
131
docs/docs.go
131
docs/docs.go
@@ -2905,6 +2905,64 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/feed/raw-materials/{id}/nutrients": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "根据原料ID,替换其所有的营养成分信息。这是一个覆盖操作。",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"饲料管理"
|
||||
],
|
||||
"summary": "全量更新原料的营养成分",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "原料ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "新的营养成分列表",
|
||||
"name": "nutrients",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.UpdateRawMaterialNutrientsRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "业务码为200代表更新成功",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/controller.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/dto.RawMaterialResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/monitor/device-command-logs": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -7368,9 +7426,6 @@ const docTemplate = `{
|
||||
"dto.NutrientResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -7386,9 +7441,6 @@ const docTemplate = `{
|
||||
"items": {
|
||||
"$ref": "#/definitions/dto.NutrientRawMaterialDTO"
|
||||
}
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -7461,9 +7513,6 @@ const docTemplate = `{
|
||||
"dto.PigAgeStageResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -7472,9 +7521,6 @@ const docTemplate = `{
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -7667,9 +7713,6 @@ const docTemplate = `{
|
||||
"breed_disadvantages": {
|
||||
"type": "string"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -7681,9 +7724,6 @@ const docTemplate = `{
|
||||
},
|
||||
"parent_info": {
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -7704,9 +7744,6 @@ const docTemplate = `{
|
||||
"dto.PigNutrientRequirementDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
@@ -7724,9 +7761,6 @@ const docTemplate = `{
|
||||
"nutrient_name": {
|
||||
"description": "营养素名称",
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -7905,9 +7939,6 @@ const docTemplate = `{
|
||||
"description": "猪品种名称",
|
||||
"type": "string"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"daily_feed_intake": {
|
||||
"type": "number"
|
||||
},
|
||||
@@ -7938,9 +7969,6 @@ const docTemplate = `{
|
||||
"items": {
|
||||
"$ref": "#/definitions/dto.PigNutrientRequirementDTO"
|
||||
}
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -8052,9 +8080,6 @@ const docTemplate = `{
|
||||
"dto.RawMaterialNutrientDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
@@ -8065,21 +8090,32 @@ const docTemplate = `{
|
||||
"description": "营养素名称",
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"description": "营养价值含量",
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.RawMaterialNutrientItem": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"nutrient_id"
|
||||
],
|
||||
"properties": {
|
||||
"nutrient_id": {
|
||||
"description": "营养素ID",
|
||||
"type": "integer"
|
||||
},
|
||||
"value": {
|
||||
"description": "含量值,必须大于等于0",
|
||||
"type": "number",
|
||||
"minimum": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.RawMaterialResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -8095,9 +8131,6 @@ const docTemplate = `{
|
||||
"items": {
|
||||
"$ref": "#/definitions/dto.RawMaterialNutrientDTO"
|
||||
}
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -8991,6 +9024,20 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.UpdateRawMaterialNutrientsRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"nutrients"
|
||||
],
|
||||
"properties": {
|
||||
"nutrients": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/dto.RawMaterialNutrientItem"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.UpdateRawMaterialRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
||||
@@ -2897,6 +2897,64 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/feed/raw-materials/{id}/nutrients": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "根据原料ID,替换其所有的营养成分信息。这是一个覆盖操作。",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"饲料管理"
|
||||
],
|
||||
"summary": "全量更新原料的营养成分",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "原料ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "新的营养成分列表",
|
||||
"name": "nutrients",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.UpdateRawMaterialNutrientsRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "业务码为200代表更新成功",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/controller.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/dto.RawMaterialResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/monitor/device-command-logs": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -7360,9 +7418,6 @@
|
||||
"dto.NutrientResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -7378,9 +7433,6 @@
|
||||
"items": {
|
||||
"$ref": "#/definitions/dto.NutrientRawMaterialDTO"
|
||||
}
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -7453,9 +7505,6 @@
|
||||
"dto.PigAgeStageResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -7464,9 +7513,6 @@
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -7659,9 +7705,6 @@
|
||||
"breed_disadvantages": {
|
||||
"type": "string"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -7673,9 +7716,6 @@
|
||||
},
|
||||
"parent_info": {
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -7696,9 +7736,6 @@
|
||||
"dto.PigNutrientRequirementDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
@@ -7716,9 +7753,6 @@
|
||||
"nutrient_name": {
|
||||
"description": "营养素名称",
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -7897,9 +7931,6 @@
|
||||
"description": "猪品种名称",
|
||||
"type": "string"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"daily_feed_intake": {
|
||||
"type": "number"
|
||||
},
|
||||
@@ -7930,9 +7961,6 @@
|
||||
"items": {
|
||||
"$ref": "#/definitions/dto.PigNutrientRequirementDTO"
|
||||
}
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -8044,9 +8072,6 @@
|
||||
"dto.RawMaterialNutrientDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
@@ -8057,21 +8082,32 @@
|
||||
"description": "营养素名称",
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"description": "营养价值含量",
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.RawMaterialNutrientItem": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"nutrient_id"
|
||||
],
|
||||
"properties": {
|
||||
"nutrient_id": {
|
||||
"description": "营养素ID",
|
||||
"type": "integer"
|
||||
},
|
||||
"value": {
|
||||
"description": "含量值,必须大于等于0",
|
||||
"type": "number",
|
||||
"minimum": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.RawMaterialResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -8087,9 +8123,6 @@
|
||||
"items": {
|
||||
"$ref": "#/definitions/dto.RawMaterialNutrientDTO"
|
||||
}
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -8983,6 +9016,20 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.UpdateRawMaterialNutrientsRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"nutrients"
|
||||
],
|
||||
"properties": {
|
||||
"nutrients": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/dto.RawMaterialNutrientItem"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.UpdateRawMaterialRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
||||
@@ -898,8 +898,6 @@ definitions:
|
||||
type: object
|
||||
dto.NutrientResponse:
|
||||
properties:
|
||||
created_at:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
id:
|
||||
@@ -911,8 +909,6 @@ definitions:
|
||||
items:
|
||||
$ref: '#/definitions/dto.NutrientRawMaterialDTO'
|
||||
type: array
|
||||
updated_at:
|
||||
type: string
|
||||
type: object
|
||||
dto.PaginationDTO:
|
||||
properties:
|
||||
@@ -959,16 +955,12 @@ definitions:
|
||||
type: object
|
||||
dto.PigAgeStageResponse:
|
||||
properties:
|
||||
created_at:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
id:
|
||||
type: integer
|
||||
name:
|
||||
type: string
|
||||
updated_at:
|
||||
type: string
|
||||
type: object
|
||||
dto.PigBatchCreateDTO:
|
||||
properties:
|
||||
@@ -1094,8 +1086,6 @@ definitions:
|
||||
type: string
|
||||
breed_disadvantages:
|
||||
type: string
|
||||
created_at:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
id:
|
||||
@@ -1104,8 +1094,6 @@ definitions:
|
||||
type: string
|
||||
parent_info:
|
||||
type: string
|
||||
updated_at:
|
||||
type: string
|
||||
type: object
|
||||
dto.PigHouseResponse:
|
||||
properties:
|
||||
@@ -1118,8 +1106,6 @@ definitions:
|
||||
type: object
|
||||
dto.PigNutrientRequirementDTO:
|
||||
properties:
|
||||
created_at:
|
||||
type: string
|
||||
id:
|
||||
type: integer
|
||||
max_requirement:
|
||||
@@ -1133,8 +1119,6 @@ definitions:
|
||||
nutrient_name:
|
||||
description: 营养素名称
|
||||
type: string
|
||||
updated_at:
|
||||
type: string
|
||||
type: object
|
||||
dto.PigPurchaseDTO:
|
||||
properties:
|
||||
@@ -1252,8 +1236,6 @@ definitions:
|
||||
breed_name:
|
||||
description: 猪品种名称
|
||||
type: string
|
||||
created_at:
|
||||
type: string
|
||||
daily_feed_intake:
|
||||
type: number
|
||||
daily_gain_weight:
|
||||
@@ -1275,8 +1257,6 @@ definitions:
|
||||
items:
|
||||
$ref: '#/definitions/dto.PigNutrientRequirementDTO'
|
||||
type: array
|
||||
updated_at:
|
||||
type: string
|
||||
type: object
|
||||
dto.PlanExecutionLogDTO:
|
||||
properties:
|
||||
@@ -1346,8 +1326,6 @@ definitions:
|
||||
type: object
|
||||
dto.RawMaterialNutrientDTO:
|
||||
properties:
|
||||
created_at:
|
||||
type: string
|
||||
id:
|
||||
type: integer
|
||||
nutrient_id:
|
||||
@@ -1355,16 +1333,24 @@ definitions:
|
||||
nutrient_name:
|
||||
description: 营养素名称
|
||||
type: string
|
||||
updated_at:
|
||||
type: string
|
||||
value:
|
||||
description: 营养价值含量
|
||||
type: number
|
||||
type: object
|
||||
dto.RawMaterialNutrientItem:
|
||||
properties:
|
||||
nutrient_id:
|
||||
description: 营养素ID
|
||||
type: integer
|
||||
value:
|
||||
description: 含量值,必须大于等于0
|
||||
minimum: 0
|
||||
type: number
|
||||
required:
|
||||
- nutrient_id
|
||||
type: object
|
||||
dto.RawMaterialResponse:
|
||||
properties:
|
||||
created_at:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
id:
|
||||
@@ -1376,8 +1362,6 @@ definitions:
|
||||
items:
|
||||
$ref: '#/definitions/dto.RawMaterialNutrientDTO'
|
||||
type: array
|
||||
updated_at:
|
||||
type: string
|
||||
type: object
|
||||
dto.ReclassifyPenToNewBatchRequest:
|
||||
properties:
|
||||
@@ -1993,6 +1977,15 @@ definitions:
|
||||
required:
|
||||
- execution_type
|
||||
type: object
|
||||
dto.UpdateRawMaterialNutrientsRequest:
|
||||
properties:
|
||||
nutrients:
|
||||
items:
|
||||
$ref: '#/definitions/dto.RawMaterialNutrientItem'
|
||||
type: array
|
||||
required:
|
||||
- nutrients
|
||||
type: object
|
||||
dto.UpdateRawMaterialRequest:
|
||||
properties:
|
||||
description:
|
||||
@@ -4300,6 +4293,40 @@ paths:
|
||||
summary: 更新原料
|
||||
tags:
|
||||
- 饲料管理
|
||||
/api/v1/feed/raw-materials/{id}/nutrients:
|
||||
put:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 根据原料ID,替换其所有的营养成分信息。这是一个覆盖操作。
|
||||
parameters:
|
||||
- description: 原料ID
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: integer
|
||||
- description: 新的营养成分列表
|
||||
in: body
|
||||
name: nutrients
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/dto.UpdateRawMaterialNutrientsRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 业务码为200代表更新成功
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/controller.Response'
|
||||
- properties:
|
||||
data:
|
||||
$ref: '#/definitions/dto.RawMaterialResponse'
|
||||
type: object
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 全量更新原料的营养成分
|
||||
tags:
|
||||
- 饲料管理
|
||||
/api/v1/monitor/device-command-logs:
|
||||
get:
|
||||
description: 根据提供的过滤条件,分页获取设备命令日志
|
||||
|
||||
@@ -365,6 +365,48 @@ func (c *Controller) ListRawMaterials(ctx echo.Context) error {
|
||||
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取原料列表成功", resp, actionType, "获取原料列表成功", resp)
|
||||
}
|
||||
|
||||
// UpdateRawMaterialNutrients godoc
|
||||
// @Summary 全量更新原料的营养成分
|
||||
// @Description 根据原料ID,替换其所有的营养成分信息。这是一个覆盖操作。
|
||||
// @Tags 饲料管理
|
||||
// @Security BearerAuth
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path int true "原料ID"
|
||||
// @Param nutrients body dto.UpdateRawMaterialNutrientsRequest true "新的营养成分列表"
|
||||
// @Success 200 {object} controller.Response{data=dto.RawMaterialResponse} "业务码为200代表更新成功"
|
||||
// @Router /api/v1/feed/raw-materials/{id}/nutrients [put]
|
||||
func (c *Controller) UpdateRawMaterialNutrients(ctx echo.Context) error {
|
||||
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "UpdateRawMaterialNutrients")
|
||||
const actionType = "更新原料营养成分"
|
||||
|
||||
idStr := ctx.Param("id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 64)
|
||||
if err != nil {
|
||||
logger.Errorf("%s: 原料ID格式错误: %v, ID: %s", actionType, err, idStr)
|
||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的原料ID格式", actionType, "原料ID格式错误", idStr)
|
||||
}
|
||||
|
||||
var req dto.UpdateRawMaterialNutrientsRequest
|
||||
if err := ctx.Bind(&req); err != nil {
|
||||
logger.Errorf("%s: 参数绑定失败: %v", actionType, err)
|
||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
||||
}
|
||||
|
||||
resp, err := c.feedManagementService.UpdateRawMaterialNutrients(reqCtx, uint32(id), &req)
|
||||
if err != nil {
|
||||
logger.Errorf("%s: 服务层更新原料营养成分失败: %v, ID: %d", actionType, err, id)
|
||||
if errors.Is(err, service.ErrRawMaterialNotFound) {
|
||||
return controller.SendErrorWithAudit(ctx, controller.CodeNotFound, err.Error(), actionType, "原料不存在", id)
|
||||
}
|
||||
// 这里可以根据未来可能从服务层返回的其他特定错误进行处理
|
||||
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "更新原料营养成分失败: "+err.Error(), actionType, "服务层更新失败", req)
|
||||
}
|
||||
|
||||
logger.Infof("%s: 原料营养成分更新成功, ID: %d", actionType, resp.ID)
|
||||
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "原料营养成分更新成功", resp, actionType, "原料营养成分更新成功", resp)
|
||||
}
|
||||
|
||||
// --- 猪品种 (PigBreed) 接口方法实现 ---
|
||||
|
||||
// CreatePigBreed godoc
|
||||
|
||||
@@ -22,8 +22,6 @@ func ConvertNutrientToDTO(nutrient *models.Nutrient) *NutrientResponse {
|
||||
|
||||
return &NutrientResponse{
|
||||
ID: nutrient.ID,
|
||||
CreatedAt: nutrient.CreatedAt,
|
||||
UpdatedAt: nutrient.UpdatedAt,
|
||||
Name: nutrient.Name,
|
||||
Description: nutrient.Description,
|
||||
RawMaterials: rawMaterials,
|
||||
@@ -57,8 +55,6 @@ func ConvertRawMaterialToDTO(rm *models.RawMaterial) *RawMaterialResponse {
|
||||
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,
|
||||
@@ -67,8 +63,6 @@ func ConvertRawMaterialToDTO(rm *models.RawMaterial) *RawMaterialResponse {
|
||||
|
||||
return &RawMaterialResponse{
|
||||
ID: rm.ID,
|
||||
CreatedAt: rm.CreatedAt,
|
||||
UpdatedAt: rm.UpdatedAt,
|
||||
Name: rm.Name,
|
||||
Description: rm.Description,
|
||||
RawMaterialNutrients: rawMaterialNutrientDTOs,
|
||||
@@ -99,8 +93,6 @@ func ConvertPigBreedToDTO(breed *models.PigBreed) *PigBreedResponse {
|
||||
}
|
||||
return &PigBreedResponse{
|
||||
ID: breed.ID,
|
||||
CreatedAt: breed.CreatedAt,
|
||||
UpdatedAt: breed.UpdatedAt,
|
||||
Name: breed.Name,
|
||||
Description: breed.Description,
|
||||
ParentInfo: breed.ParentInfo,
|
||||
@@ -134,8 +126,6 @@ func ConvertPigAgeStageToDTO(ageStage *models.PigAgeStage) *PigAgeStageResponse
|
||||
}
|
||||
return &PigAgeStageResponse{
|
||||
ID: ageStage.ID,
|
||||
CreatedAt: ageStage.CreatedAt,
|
||||
UpdatedAt: ageStage.UpdatedAt,
|
||||
Name: ageStage.Name,
|
||||
Description: ageStage.Description,
|
||||
}
|
||||
@@ -168,8 +158,6 @@ func ConvertPigTypeToDTO(pt *models.PigType) *PigTypeResponse {
|
||||
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,
|
||||
@@ -179,8 +167,6 @@ func ConvertPigTypeToDTO(pt *models.PigType) *PigTypeResponse {
|
||||
|
||||
return &PigTypeResponse{
|
||||
ID: pt.ID,
|
||||
CreatedAt: pt.CreatedAt,
|
||||
UpdatedAt: pt.UpdatedAt,
|
||||
BreedID: pt.BreedID,
|
||||
BreedName: pt.Breed.Name, // 假设 Breed 已经被预加载
|
||||
AgeStageID: pt.AgeStageID,
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
package dto
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// =============================================================================================================
|
||||
// 营养种类 (Nutrient) 相关 DTO
|
||||
// =============================================================================================================
|
||||
@@ -30,8 +26,6 @@ type NutrientRawMaterialDTO struct {
|
||||
// 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"`
|
||||
RawMaterials []NutrientRawMaterialDTO `json:"raw_materials"` // 包含此营养的原料列表
|
||||
@@ -70,19 +64,15 @@ type UpdateRawMaterialRequest struct {
|
||||
|
||||
// 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"` // 营养价值含量
|
||||
ID uint32 `json:"id"`
|
||||
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"` // 关联的营养素信息
|
||||
@@ -103,6 +93,17 @@ type ListRawMaterialResponse struct {
|
||||
Pagination PaginationDTO `json:"pagination"`
|
||||
}
|
||||
|
||||
// UpdateRawMaterialNutrientsRequest 更新原料营养成分的请求体
|
||||
type UpdateRawMaterialNutrientsRequest struct {
|
||||
Nutrients []RawMaterialNutrientItem `json:"nutrients" validate:"required,dive"`
|
||||
}
|
||||
|
||||
// RawMaterialNutrientItem 代表一个营养成分及其含量
|
||||
type RawMaterialNutrientItem struct {
|
||||
NutrientID uint32 `json:"nutrient_id" validate:"required"` // 营养素ID
|
||||
Value float32 `json:"value" validate:"gte=0"` // 含量值,必须大于等于0
|
||||
}
|
||||
|
||||
// =============================================================================================================
|
||||
// 猪品种 (PigBreed) 相关 DTO
|
||||
// =============================================================================================================
|
||||
@@ -129,15 +130,13 @@ type UpdatePigBreedRequest struct {
|
||||
|
||||
// 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"`
|
||||
ID uint32 `json:"id"`
|
||||
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 定义了获取猪品种列表的请求参数
|
||||
@@ -172,11 +171,9 @@ type UpdatePigAgeStageRequest struct {
|
||||
|
||||
// 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"`
|
||||
ID uint32 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
// ListPigAgeStageRequest 定义了获取猪年龄阶段列表的请求参数
|
||||
@@ -225,20 +222,16 @@ type UpdatePigTypeRequest struct {
|
||||
|
||||
// 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"` // 最高营养需求量
|
||||
ID uint32 `json:"id"`
|
||||
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"`
|
||||
|
||||
@@ -40,6 +40,7 @@ type FeedManagementService interface {
|
||||
DeleteRawMaterial(ctx context.Context, id uint32) error
|
||||
GetRawMaterial(ctx context.Context, id uint32) (*dto.RawMaterialResponse, error)
|
||||
ListRawMaterials(ctx context.Context, req *dto.ListRawMaterialRequest) (*dto.ListRawMaterialResponse, error)
|
||||
UpdateRawMaterialNutrients(ctx context.Context, id uint32, req *dto.UpdateRawMaterialNutrientsRequest) (*dto.RawMaterialResponse, error) // 新增
|
||||
|
||||
// 猪品种相关
|
||||
CreatePigBreed(ctx context.Context, req *dto.CreatePigBreedRequest) (*dto.PigBreedResponse, error)
|
||||
@@ -236,6 +237,43 @@ func (s *feedManagementServiceImpl) ListRawMaterials(ctx context.Context, req *d
|
||||
return dto.ConvertRawMaterialListToDTO(rawMaterials, total, req.Page, req.PageSize), nil
|
||||
}
|
||||
|
||||
// UpdateRawMaterialNutrients 全量更新原料的营养成分
|
||||
func (s *feedManagementServiceImpl) UpdateRawMaterialNutrients(ctx context.Context, id uint32, req *dto.UpdateRawMaterialNutrientsRequest) (*dto.RawMaterialResponse, error) {
|
||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdateRawMaterialNutrients")
|
||||
|
||||
// 1. 将 DTO 转换为领域模型
|
||||
nutrients := make([]models.RawMaterialNutrient, len(req.Nutrients))
|
||||
for i, item := range req.Nutrients {
|
||||
nutrients[i] = models.RawMaterialNutrient{
|
||||
NutrientID: item.NutrientID,
|
||||
Value: item.Value,
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 调用领域服务执行更新命令
|
||||
err := s.recipeSvc.UpdateRawMaterialNutrients(serviceCtx, id, nutrients)
|
||||
if err != nil {
|
||||
if errors.Is(err, recipe.ErrRawMaterialNotFound) {
|
||||
return nil, ErrRawMaterialNotFound
|
||||
}
|
||||
// 此处可以根据领域层可能返回的其他特定错误进行转换
|
||||
return nil, fmt.Errorf("更新原料营养成分失败: %w", err)
|
||||
}
|
||||
|
||||
// 3. 更新成功后,调用查询服务获取最新的原料信息
|
||||
updatedRawMaterial, err := s.recipeSvc.GetRawMaterial(serviceCtx, id)
|
||||
if err != nil {
|
||||
if errors.Is(err, recipe.ErrRawMaterialNotFound) {
|
||||
// 理论上不应该发生,因为刚更新成功
|
||||
return nil, ErrRawMaterialNotFound
|
||||
}
|
||||
return nil, fmt.Errorf("更新后获取原料信息失败: %w", err)
|
||||
}
|
||||
|
||||
// 4. 将领域模型转换为 DTO 并返回
|
||||
return dto.ConvertRawMaterialToDTO(updatedRawMaterial), nil
|
||||
}
|
||||
|
||||
// =====================================================================================================================
|
||||
// 猪品种 (PigBreed) 实现
|
||||
// =====================================================================================================================
|
||||
|
||||
@@ -217,6 +217,7 @@ func initDomainServices(ctx context.Context, cfg *config.Config, infra *Infrastr
|
||||
// 配方管理服务
|
||||
recipeService := recipe.NewRecipeService(
|
||||
logs.AddCompName(baseCtx, "RecipeService"),
|
||||
infra.repos.unitOfWork,
|
||||
infra.repos.nutrientRepo,
|
||||
infra.repos.rawMaterialRepo,
|
||||
infra.repos.pigTypeRepo,
|
||||
|
||||
@@ -40,6 +40,7 @@ type Service interface {
|
||||
DeleteRawMaterial(ctx context.Context, id uint32) error
|
||||
GetRawMaterial(ctx context.Context, id uint32) (*models.RawMaterial, error)
|
||||
ListRawMaterials(ctx context.Context, opts repository.RawMaterialListOptions, page, pageSize int) ([]models.RawMaterial, int64, error)
|
||||
UpdateRawMaterialNutrients(ctx context.Context, rawMaterialID uint32, nutrients []models.RawMaterialNutrient) error
|
||||
|
||||
// 猪品种相关接口
|
||||
CreatePigBreed(ctx context.Context, breed *models.PigBreed) error
|
||||
@@ -66,15 +67,17 @@ type Service interface {
|
||||
// recipeServiceImpl 是 RecipeService 的实现
|
||||
type recipeServiceImpl struct {
|
||||
ctx context.Context
|
||||
uow repository.UnitOfWork
|
||||
nutrientRepo repository.NutrientRepository
|
||||
rawMaterialRepo repository.RawMaterialRepository
|
||||
pigTypeRepo repository.PigTypeRepository
|
||||
}
|
||||
|
||||
// NewRecipeService 创建一个新的 RecipeService 实例
|
||||
func NewRecipeService(ctx context.Context, nutrientRepo repository.NutrientRepository, rawMaterialRepo repository.RawMaterialRepository, pigTypeRepo repository.PigTypeRepository) Service {
|
||||
func NewRecipeService(ctx context.Context, uow repository.UnitOfWork, nutrientRepo repository.NutrientRepository, rawMaterialRepo repository.RawMaterialRepository, pigTypeRepo repository.PigTypeRepository) Service {
|
||||
return &recipeServiceImpl{
|
||||
ctx: ctx,
|
||||
uow: uow,
|
||||
nutrientRepo: nutrientRepo,
|
||||
rawMaterialRepo: rawMaterialRepo,
|
||||
pigTypeRepo: pigTypeRepo,
|
||||
@@ -289,6 +292,41 @@ func (s *recipeServiceImpl) ListRawMaterials(ctx context.Context, opts repositor
|
||||
return rawMaterials, total, nil
|
||||
}
|
||||
|
||||
// UpdateRawMaterialNutrients 实现了全量更新原料营养成分的业务逻辑
|
||||
func (s *recipeServiceImpl) UpdateRawMaterialNutrients(ctx context.Context, rawMaterialID uint32, nutrients []models.RawMaterialNutrient) error {
|
||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdateRawMaterialNutrients")
|
||||
|
||||
// 1. 检查原料是否存在
|
||||
if _, err := s.rawMaterialRepo.GetRawMaterialByID(serviceCtx, rawMaterialID); err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return ErrRawMaterialNotFound
|
||||
}
|
||||
return fmt.Errorf("获取待更新的原料失败: %w", err)
|
||||
}
|
||||
|
||||
// 2. 在事务中执行替换操作
|
||||
err := s.uow.ExecuteInTransaction(serviceCtx, func(tx *gorm.DB) error {
|
||||
// 2.1. 删除旧的关联记录
|
||||
if err := s.rawMaterialRepo.DeleteNutrientsByRawMaterialIDTx(serviceCtx, tx, rawMaterialID); err != nil {
|
||||
return err // 错误已在仓库层封装,直接返回
|
||||
}
|
||||
|
||||
// 2.2. 创建新的关联记录
|
||||
if err := s.rawMaterialRepo.CreateBatchRawMaterialNutrientsTx(serviceCtx, tx, nutrients); err != nil {
|
||||
return err // 错误已在仓库层封装,直接返回
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("更新原料营养成分事务执行失败: %w", err)
|
||||
}
|
||||
|
||||
// 3. 操作成功,直接返回 nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreatePigBreed 实现了创建猪品种的核心业务逻辑
|
||||
func (s *recipeServiceImpl) CreatePigBreed(ctx context.Context, breed *models.PigBreed) error {
|
||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "CreatePigBreed")
|
||||
|
||||
@@ -26,6 +26,8 @@ type RawMaterialRepository interface {
|
||||
ListRawMaterials(ctx context.Context, opts RawMaterialListOptions, page, pageSize int) ([]models.RawMaterial, int64, error)
|
||||
UpdateRawMaterial(ctx context.Context, rawMaterial *models.RawMaterial) error
|
||||
DeleteRawMaterial(ctx context.Context, id uint32) error
|
||||
DeleteNutrientsByRawMaterialIDTx(ctx context.Context, db *gorm.DB, rawMaterialID uint32) error
|
||||
CreateBatchRawMaterialNutrientsTx(ctx context.Context, db *gorm.DB, nutrients []models.RawMaterialNutrient) error
|
||||
|
||||
// 库存日志相关方法
|
||||
CreateRawMaterialStockLog(ctx context.Context, log *models.RawMaterialStockLog) error
|
||||
@@ -162,6 +164,30 @@ func (r *gormRawMaterialRepository) DeleteRawMaterial(ctx context.Context, id ui
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteNutrientsByRawMaterialIDTx 在事务中软删除指定原料的所有营养成分
|
||||
func (r *gormRawMaterialRepository) DeleteNutrientsByRawMaterialIDTx(ctx context.Context, db *gorm.DB, rawMaterialID uint32) error {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "DeleteNutrientsByRawMaterialIDTx")
|
||||
tx := db.WithContext(repoCtx)
|
||||
if err := tx.Where("raw_material_id = ?", rawMaterialID).Delete(&models.RawMaterialNutrient{}).Error; err != nil {
|
||||
return fmt.Errorf("软删除原料营养成分失败: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateBatchRawMaterialNutrientsTx 在事务中批量创建原料营养成分
|
||||
func (r *gormRawMaterialRepository) CreateBatchRawMaterialNutrientsTx(ctx context.Context, db *gorm.DB, nutrients []models.RawMaterialNutrient) error {
|
||||
// 如果没有要创建的记录,直接返回成功,避免执行空的Create语句
|
||||
if len(nutrients) == 0 {
|
||||
return nil
|
||||
}
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "CreateBatchRawMaterialNutrientsTx")
|
||||
tx := db.WithContext(repoCtx)
|
||||
if err := tx.Create(&nutrients).Error; err != nil {
|
||||
return fmt.Errorf("批量创建原料营养成分失败: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateRawMaterialStockLog 创建一条新的原料库存日志
|
||||
func (r *gormRawMaterialRepository) CreateRawMaterialStockLog(ctx context.Context, log *models.RawMaterialStockLog) error {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "CreateRawMaterialStockLog")
|
||||
|
||||
Reference in New Issue
Block a user