配方增删改查服务层和控制器
This commit is contained in:
@@ -60,4 +60,5 @@ http://git.huangwc.com/pig/pig-farm-controller/issues/66
|
|||||||
10. 实现修改猪营养需求
|
10. 实现修改猪营养需求
|
||||||
11. 配方模型定义和仓库层增删改查方法
|
11. 配方模型定义和仓库层增删改查方法
|
||||||
12. 配方领域层方法
|
12. 配方领域层方法
|
||||||
13. 重构配方领域
|
13. 重构配方领域
|
||||||
|
14. 配方增删改查服务层和控制器
|
||||||
348
docs/docs.go
348
docs/docs.go
@@ -3021,6 +3021,252 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/v1/feed/recipes": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "获取所有配方的列表,支持分页和过滤。",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"饲料管理-配方"
|
||||||
|
],
|
||||||
|
"summary": "获取配方列表",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "按名称模糊查询",
|
||||||
|
"name": "name",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "排序字段,例如 \"id DESC\"",
|
||||||
|
"name": "order_by",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "页码",
|
||||||
|
"name": "page",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "每页数量",
|
||||||
|
"name": "page_size",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "业务码为200代表成功获取列表",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/dto.ListRecipeResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "创建一个新的配方,包含其原料组成。",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"饲料管理-配方"
|
||||||
|
],
|
||||||
|
"summary": "创建配方",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "配方信息",
|
||||||
|
"name": "recipe",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.CreateRecipeRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "业务码为201代表创建成功",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/dto.RecipeResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/feed/recipes/{id}": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "根据ID获取单个配方的详细信息。",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"饲料管理-配方"
|
||||||
|
],
|
||||||
|
"summary": "获取配方详情",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "配方ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "业务码为200代表成功获取",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/dto.RecipeResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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": "recipe",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.UpdateRecipeRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "业务码为200代表更新成功",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/dto.RecipeResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "根据ID删除配方。",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"饲料管理-配方"
|
||||||
|
],
|
||||||
|
"summary": "删除配方",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "配方ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "业务码为200代表删除成功",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/controller.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/v1/monitor/device-command-logs": {
|
"/api/v1/monitor/device-command-logs": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -6761,6 +7007,31 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dto.CreateRecipeRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"description": {
|
||||||
|
"description": "配方描述",
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 255
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"description": "配方名称",
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 100
|
||||||
|
},
|
||||||
|
"recipe_ingredients": {
|
||||||
|
"description": "配方原料组成",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/dto.RecipeIngredientDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dto.CreateUserRequest": {
|
"dto.CreateUserRequest": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -7241,6 +7512,20 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dto.ListRecipeResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"list": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/dto.RecipeResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"$ref": "#/definitions/dto.PaginationDTO"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dto.ListSensorDataResponse": {
|
"dto.ListSensorDataResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -8214,6 +8499,44 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dto.RecipeIngredientDto": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"raw_material_id"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"percentage": {
|
||||||
|
"description": "原料在配方中的百分比 (0-1之间)",
|
||||||
|
"type": "number",
|
||||||
|
"maximum": 1,
|
||||||
|
"minimum": 0
|
||||||
|
},
|
||||||
|
"raw_material_id": {
|
||||||
|
"description": "原料ID",
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dto.RecipeResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"recipe_ingredients": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/dto.RecipeIngredientDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dto.ReclassifyPenToNewBatchRequest": {
|
"dto.ReclassifyPenToNewBatchRequest": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -9150,6 +9473,31 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dto.UpdateRecipeRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"description": {
|
||||||
|
"description": "配方描述",
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 255
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"description": "配方名称",
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 100
|
||||||
|
},
|
||||||
|
"recipe_ingredients": {
|
||||||
|
"description": "配方原料组成",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/dto.RecipeIngredientDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dto.UserActionLogDTO": {
|
"dto.UserActionLogDTO": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|||||||
@@ -3013,6 +3013,252 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/v1/feed/recipes": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "获取所有配方的列表,支持分页和过滤。",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"饲料管理-配方"
|
||||||
|
],
|
||||||
|
"summary": "获取配方列表",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "按名称模糊查询",
|
||||||
|
"name": "name",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "排序字段,例如 \"id DESC\"",
|
||||||
|
"name": "order_by",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "页码",
|
||||||
|
"name": "page",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "每页数量",
|
||||||
|
"name": "page_size",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "业务码为200代表成功获取列表",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/dto.ListRecipeResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "创建一个新的配方,包含其原料组成。",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"饲料管理-配方"
|
||||||
|
],
|
||||||
|
"summary": "创建配方",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "配方信息",
|
||||||
|
"name": "recipe",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.CreateRecipeRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "业务码为201代表创建成功",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/dto.RecipeResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/feed/recipes/{id}": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "根据ID获取单个配方的详细信息。",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"饲料管理-配方"
|
||||||
|
],
|
||||||
|
"summary": "获取配方详情",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "配方ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "业务码为200代表成功获取",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/dto.RecipeResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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": "recipe",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.UpdateRecipeRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "业务码为200代表更新成功",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/dto.RecipeResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "根据ID删除配方。",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"饲料管理-配方"
|
||||||
|
],
|
||||||
|
"summary": "删除配方",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "配方ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "业务码为200代表删除成功",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/controller.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/v1/monitor/device-command-logs": {
|
"/api/v1/monitor/device-command-logs": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -6753,6 +6999,31 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dto.CreateRecipeRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"description": {
|
||||||
|
"description": "配方描述",
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 255
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"description": "配方名称",
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 100
|
||||||
|
},
|
||||||
|
"recipe_ingredients": {
|
||||||
|
"description": "配方原料组成",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/dto.RecipeIngredientDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dto.CreateUserRequest": {
|
"dto.CreateUserRequest": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -7233,6 +7504,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dto.ListRecipeResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"list": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/dto.RecipeResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"$ref": "#/definitions/dto.PaginationDTO"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dto.ListSensorDataResponse": {
|
"dto.ListSensorDataResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -8206,6 +8491,44 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dto.RecipeIngredientDto": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"raw_material_id"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"percentage": {
|
||||||
|
"description": "原料在配方中的百分比 (0-1之间)",
|
||||||
|
"type": "number",
|
||||||
|
"maximum": 1,
|
||||||
|
"minimum": 0
|
||||||
|
},
|
||||||
|
"raw_material_id": {
|
||||||
|
"description": "原料ID",
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dto.RecipeResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"recipe_ingredients": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/dto.RecipeIngredientDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dto.ReclassifyPenToNewBatchRequest": {
|
"dto.ReclassifyPenToNewBatchRequest": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -9142,6 +9465,31 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dto.UpdateRecipeRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"description": {
|
||||||
|
"description": "配方描述",
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 255
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"description": "配方名称",
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 100
|
||||||
|
},
|
||||||
|
"recipe_ingredients": {
|
||||||
|
"description": "配方原料组成",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/dto.RecipeIngredientDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dto.UserActionLogDTO": {
|
"dto.UserActionLogDTO": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|||||||
@@ -423,6 +423,24 @@ definitions:
|
|||||||
required:
|
required:
|
||||||
- name
|
- name
|
||||||
type: object
|
type: object
|
||||||
|
dto.CreateRecipeRequest:
|
||||||
|
properties:
|
||||||
|
description:
|
||||||
|
description: 配方描述
|
||||||
|
maxLength: 255
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
description: 配方名称
|
||||||
|
maxLength: 100
|
||||||
|
type: string
|
||||||
|
recipe_ingredients:
|
||||||
|
description: 配方原料组成
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/dto.RecipeIngredientDto'
|
||||||
|
type: array
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
dto.CreateUserRequest:
|
dto.CreateUserRequest:
|
||||||
properties:
|
properties:
|
||||||
password:
|
password:
|
||||||
@@ -735,6 +753,15 @@ definitions:
|
|||||||
pagination:
|
pagination:
|
||||||
$ref: '#/definitions/dto.PaginationDTO'
|
$ref: '#/definitions/dto.PaginationDTO'
|
||||||
type: object
|
type: object
|
||||||
|
dto.ListRecipeResponse:
|
||||||
|
properties:
|
||||||
|
list:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/dto.RecipeResponse'
|
||||||
|
type: array
|
||||||
|
pagination:
|
||||||
|
$ref: '#/definitions/dto.PaginationDTO'
|
||||||
|
type: object
|
||||||
dto.ListSensorDataResponse:
|
dto.ListSensorDataResponse:
|
||||||
properties:
|
properties:
|
||||||
list:
|
list:
|
||||||
@@ -1379,6 +1406,32 @@ definitions:
|
|||||||
$ref: '#/definitions/dto.RawMaterialNutrientDTO'
|
$ref: '#/definitions/dto.RawMaterialNutrientDTO'
|
||||||
type: array
|
type: array
|
||||||
type: object
|
type: object
|
||||||
|
dto.RecipeIngredientDto:
|
||||||
|
properties:
|
||||||
|
percentage:
|
||||||
|
description: 原料在配方中的百分比 (0-1之间)
|
||||||
|
maximum: 1
|
||||||
|
minimum: 0
|
||||||
|
type: number
|
||||||
|
raw_material_id:
|
||||||
|
description: 原料ID
|
||||||
|
type: integer
|
||||||
|
required:
|
||||||
|
- raw_material_id
|
||||||
|
type: object
|
||||||
|
dto.RecipeResponse:
|
||||||
|
properties:
|
||||||
|
description:
|
||||||
|
type: string
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
recipe_ingredients:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/dto.RecipeIngredientDto'
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
dto.ReclassifyPenToNewBatchRequest:
|
dto.ReclassifyPenToNewBatchRequest:
|
||||||
properties:
|
properties:
|
||||||
pen_id:
|
pen_id:
|
||||||
@@ -2024,6 +2077,24 @@ definitions:
|
|||||||
required:
|
required:
|
||||||
- name
|
- name
|
||||||
type: object
|
type: object
|
||||||
|
dto.UpdateRecipeRequest:
|
||||||
|
properties:
|
||||||
|
description:
|
||||||
|
description: 配方描述
|
||||||
|
maxLength: 255
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
description: 配方名称
|
||||||
|
maxLength: 100
|
||||||
|
type: string
|
||||||
|
recipe_ingredients:
|
||||||
|
description: 配方原料组成
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/dto.RecipeIngredientDto'
|
||||||
|
type: array
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
dto.UserActionLogDTO:
|
dto.UserActionLogDTO:
|
||||||
properties:
|
properties:
|
||||||
action_type:
|
action_type:
|
||||||
@@ -4386,6 +4457,150 @@ paths:
|
|||||||
summary: 全量更新原料的营养成分
|
summary: 全量更新原料的营养成分
|
||||||
tags:
|
tags:
|
||||||
- 饲料管理-原料
|
- 饲料管理-原料
|
||||||
|
/api/v1/feed/recipes:
|
||||||
|
get:
|
||||||
|
description: 获取所有配方的列表,支持分页和过滤。
|
||||||
|
parameters:
|
||||||
|
- description: 按名称模糊查询
|
||||||
|
in: query
|
||||||
|
name: name
|
||||||
|
type: string
|
||||||
|
- description: 排序字段,例如 "id DESC"
|
||||||
|
in: query
|
||||||
|
name: order_by
|
||||||
|
type: string
|
||||||
|
- description: 页码
|
||||||
|
in: query
|
||||||
|
name: page
|
||||||
|
type: integer
|
||||||
|
- description: 每页数量
|
||||||
|
in: query
|
||||||
|
name: page_size
|
||||||
|
type: integer
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: 业务码为200代表成功获取列表
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/controller.Response'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
$ref: '#/definitions/dto.ListRecipeResponse'
|
||||||
|
type: object
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: 获取配方列表
|
||||||
|
tags:
|
||||||
|
- 饲料管理-配方
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 创建一个新的配方,包含其原料组成。
|
||||||
|
parameters:
|
||||||
|
- description: 配方信息
|
||||||
|
in: body
|
||||||
|
name: recipe
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/dto.CreateRecipeRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: 业务码为201代表创建成功
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/controller.Response'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
$ref: '#/definitions/dto.RecipeResponse'
|
||||||
|
type: object
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: 创建配方
|
||||||
|
tags:
|
||||||
|
- 饲料管理-配方
|
||||||
|
/api/v1/feed/recipes/{id}:
|
||||||
|
delete:
|
||||||
|
description: 根据ID删除配方。
|
||||||
|
parameters:
|
||||||
|
- description: 配方ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: 业务码为200代表删除成功
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/controller.Response'
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: 删除配方
|
||||||
|
tags:
|
||||||
|
- 饲料管理-配方
|
||||||
|
get:
|
||||||
|
description: 根据ID获取单个配方的详细信息。
|
||||||
|
parameters:
|
||||||
|
- description: 配方ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: 业务码为200代表成功获取
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/controller.Response'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
$ref: '#/definitions/dto.RecipeResponse'
|
||||||
|
type: object
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: 获取配方详情
|
||||||
|
tags:
|
||||||
|
- 饲料管理-配方
|
||||||
|
put:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 根据ID更新配方信息及其原料组成。
|
||||||
|
parameters:
|
||||||
|
- description: 配方ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
- description: 更新后的配方信息
|
||||||
|
in: body
|
||||||
|
name: recipe
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/dto.UpdateRecipeRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: 业务码为200代表更新成功
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/controller.Response'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
$ref: '#/definitions/dto.RecipeResponse'
|
||||||
|
type: object
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: 更新配方
|
||||||
|
tags:
|
||||||
|
- 饲料管理-配方
|
||||||
/api/v1/monitor/device-command-logs:
|
/api/v1/monitor/device-command-logs:
|
||||||
get:
|
get:
|
||||||
description: 根据提供的过滤条件,分页获取设备命令日志
|
description: 根据提供的过滤条件,分页获取设备命令日志
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ type API struct {
|
|||||||
pigBreedController *feed.PigBreedController // 猪品种控制器实例
|
pigBreedController *feed.PigBreedController // 猪品种控制器实例
|
||||||
pigTypeController *feed.PigTypeController // 猪种类控制器实例
|
pigTypeController *feed.PigTypeController // 猪种类控制器实例
|
||||||
rawMaterialController *feed.RawMaterialController // 原料控制器实例
|
rawMaterialController *feed.RawMaterialController // 原料控制器实例
|
||||||
|
recipeController *feed.RecipeController // 配方控制器实例
|
||||||
listenHandler webhook.ListenHandler // 设备上行事件监听器
|
listenHandler webhook.ListenHandler // 设备上行事件监听器
|
||||||
analysisTaskManager *domain_plan.AnalysisPlanTaskManager // 计划触发器管理器实例
|
analysisTaskManager *domain_plan.AnalysisPlanTaskManager // 计划触发器管理器实例
|
||||||
}
|
}
|
||||||
@@ -83,6 +84,7 @@ func NewAPI(cfg config.ServerConfig,
|
|||||||
pigBreedService service.PigBreedService,
|
pigBreedService service.PigBreedService,
|
||||||
pigAgeStageService service.PigAgeStageService,
|
pigAgeStageService service.PigAgeStageService,
|
||||||
pigTypeService service.PigTypeService,
|
pigTypeService service.PigTypeService,
|
||||||
|
recipeService service.RecipeService,
|
||||||
tokenGenerator token.Generator,
|
tokenGenerator token.Generator,
|
||||||
listenHandler webhook.ListenHandler,
|
listenHandler webhook.ListenHandler,
|
||||||
) *API {
|
) *API {
|
||||||
@@ -119,6 +121,7 @@ func NewAPI(cfg config.ServerConfig,
|
|||||||
pigBreedController: feed.NewPigBreedController(logs.AddCompName(baseCtx, "PigBreedController"), pigBreedService),
|
pigBreedController: feed.NewPigBreedController(logs.AddCompName(baseCtx, "PigBreedController"), pigBreedService),
|
||||||
pigTypeController: feed.NewPigTypeController(logs.AddCompName(baseCtx, "PigTypeController"), pigTypeService),
|
pigTypeController: feed.NewPigTypeController(logs.AddCompName(baseCtx, "PigTypeController"), pigTypeService),
|
||||||
rawMaterialController: feed.NewRawMaterialController(logs.AddCompName(baseCtx, "RawMaterialController"), rawMaterialService),
|
rawMaterialController: feed.NewRawMaterialController(logs.AddCompName(baseCtx, "RawMaterialController"), rawMaterialService),
|
||||||
|
recipeController: feed.NewRecipeController(logs.AddCompName(baseCtx, "RecipeController"), recipeService),
|
||||||
}
|
}
|
||||||
|
|
||||||
api.setupRoutes() // 设置所有路由
|
api.setupRoutes() // 设置所有路由
|
||||||
|
|||||||
@@ -252,6 +252,13 @@ func (a *API) setupRoutes() {
|
|||||||
feedGroup.GET("/pig-types/:id", a.pigTypeController.GetPigType)
|
feedGroup.GET("/pig-types/:id", a.pigTypeController.GetPigType)
|
||||||
feedGroup.GET("/pig-types", a.pigTypeController.ListPigTypes)
|
feedGroup.GET("/pig-types", a.pigTypeController.ListPigTypes)
|
||||||
feedGroup.PUT("/pig-types/:id/nutrient-requirements", a.pigTypeController.UpdatePigTypeNutrientRequirements)
|
feedGroup.PUT("/pig-types/:id/nutrient-requirements", a.pigTypeController.UpdatePigTypeNutrientRequirements)
|
||||||
|
|
||||||
|
// 配方 (Recipe) 路由
|
||||||
|
feedGroup.POST("/recipes", a.recipeController.CreateRecipe)
|
||||||
|
feedGroup.PUT("/recipes/:id", a.recipeController.UpdateRecipe)
|
||||||
|
feedGroup.DELETE("/recipes/:id", a.recipeController.DeleteRecipe)
|
||||||
|
feedGroup.GET("/recipes/:id", a.recipeController.GetRecipe)
|
||||||
|
feedGroup.GET("/recipes", a.recipeController.ListRecipes)
|
||||||
}
|
}
|
||||||
logger.Debug("饲料管理相关接口注册成功 (需要认证和审计)")
|
logger.Debug("饲料管理相关接口注册成功 (需要认证和审计)")
|
||||||
}
|
}
|
||||||
|
|||||||
196
internal/app/controller/feed/recipe_controller.go
Normal file
196
internal/app/controller/feed/recipe_controller.go
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
package feed
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/app/controller"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/app/service"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/domain/recipe"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
|
||||||
|
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RecipeController 包含配方相关的处理器
|
||||||
|
type RecipeController struct {
|
||||||
|
ctx context.Context
|
||||||
|
recipeService service.RecipeService
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRecipeController 创建一个新的 RecipeController
|
||||||
|
func NewRecipeController(ctx context.Context, recipeService service.RecipeService) *RecipeController {
|
||||||
|
return &RecipeController{
|
||||||
|
ctx: ctx,
|
||||||
|
recipeService: recipeService,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRecipe godoc
|
||||||
|
// @Summary 创建配方
|
||||||
|
// @Description 创建一个新的配方,包含其原料组成。
|
||||||
|
// @Tags 饲料管理-配方
|
||||||
|
// @Security BearerAuth
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param recipe body dto.CreateRecipeRequest true "配方信息"
|
||||||
|
// @Success 200 {object} controller.Response{data=dto.RecipeResponse} "业务码为201代表创建成功"
|
||||||
|
// @Router /api/v1/feed/recipes [post]
|
||||||
|
func (c *RecipeController) CreateRecipe(ctx echo.Context) error {
|
||||||
|
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "CreateRecipe")
|
||||||
|
var req dto.CreateRecipeRequest
|
||||||
|
const actionType = "创建配方"
|
||||||
|
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.recipeService.CreateRecipe(reqCtx, &req)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("%s: 服务层创建配方失败: %v", actionType, err)
|
||||||
|
if errors.Is(err, recipe.ErrRecipeNameConflict) {
|
||||||
|
return controller.SendErrorWithAudit(ctx, controller.CodeConflict, err.Error(), actionType, "配方名称已存在", req)
|
||||||
|
}
|
||||||
|
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "创建配方失败: "+err.Error(), actionType, "服务层创建配方失败", req)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Infof("%s: 配方创建成功, ID: %d", actionType, resp.ID)
|
||||||
|
return controller.SendSuccessWithAudit(ctx, controller.CodeCreated, "配方创建成功", resp, actionType, "配方创建成功", resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateRecipe godoc
|
||||||
|
// @Summary 更新配方
|
||||||
|
// @Description 根据ID更新配方信息及其原料组成。
|
||||||
|
// @Tags 饲料管理-配方
|
||||||
|
// @Security BearerAuth
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path int true "配方ID"
|
||||||
|
// @Param recipe body dto.UpdateRecipeRequest true "更新后的配方信息"
|
||||||
|
// @Success 200 {object} controller.Response{data=dto.RecipeResponse} "业务码为200代表更新成功"
|
||||||
|
// @Router /api/v1/feed/recipes/{id} [put]
|
||||||
|
func (c *RecipeController) UpdateRecipe(ctx echo.Context) error {
|
||||||
|
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "UpdateRecipe")
|
||||||
|
const actionType = "更新配方"
|
||||||
|
idStr := ctx.Param("id")
|
||||||
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
||||||
|
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.UpdateRecipeRequest
|
||||||
|
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.recipeService.UpdateRecipe(reqCtx, uint32(id), &req)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("%s: 服务层更新配方失败: %v, ID: %d", actionType, err, id)
|
||||||
|
if errors.Is(err, recipe.ErrRecipeNotFound) {
|
||||||
|
return controller.SendErrorWithAudit(ctx, controller.CodeNotFound, err.Error(), actionType, "配方不存在", id)
|
||||||
|
}
|
||||||
|
if errors.Is(err, recipe.ErrRecipeNameConflict) {
|
||||||
|
return controller.SendErrorWithAudit(ctx, controller.CodeConflict, err.Error(), actionType, "配方名称已存在", req)
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRecipe godoc
|
||||||
|
// @Summary 删除配方
|
||||||
|
// @Description 根据ID删除配方。
|
||||||
|
// @Tags 饲料管理-配方
|
||||||
|
// @Security BearerAuth
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path int true "配方ID"
|
||||||
|
// @Success 200 {object} controller.Response "业务码为200代表删除成功"
|
||||||
|
// @Router /api/v1/feed/recipes/{id} [delete]
|
||||||
|
func (c *RecipeController) DeleteRecipe(ctx echo.Context) error {
|
||||||
|
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "DeleteRecipe")
|
||||||
|
const actionType = "删除配方"
|
||||||
|
idStr := ctx.Param("id")
|
||||||
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("%s: 配方ID格式错误: %v, ID: %s", actionType, err, idStr)
|
||||||
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的配方ID格式", actionType, "配方ID格式错误", idStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.recipeService.DeleteRecipe(reqCtx, uint32(id))
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("%s: 服务层删除配方失败: %v, ID: %d", actionType, err, id)
|
||||||
|
if errors.Is(err, recipe.ErrRecipeNotFound) {
|
||||||
|
return controller.SendErrorWithAudit(ctx, controller.CodeNotFound, err.Error(), actionType, "配方不存在", id)
|
||||||
|
}
|
||||||
|
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "删除配方失败: "+err.Error(), actionType, "服务层删除配方失败", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Infof("%s: 配方删除成功, ID: %d", actionType, id)
|
||||||
|
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "配方删除成功", nil, actionType, "配方删除成功", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRecipe godoc
|
||||||
|
// @Summary 获取配方详情
|
||||||
|
// @Description 根据ID获取单个配方的详细信息。
|
||||||
|
// @Tags 饲料管理-配方
|
||||||
|
// @Security BearerAuth
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path int true "配方ID"
|
||||||
|
// @Success 200 {object} controller.Response{data=dto.RecipeResponse} "业务码为200代表成功获取"
|
||||||
|
// @Router /api/v1/feed/recipes/{id} [get]
|
||||||
|
func (c *RecipeController) GetRecipe(ctx echo.Context) error {
|
||||||
|
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "GetRecipe")
|
||||||
|
const actionType = "获取配方详情"
|
||||||
|
idStr := ctx.Param("id")
|
||||||
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("%s: 配方ID格式错误: %v, ID: %s", actionType, err, idStr)
|
||||||
|
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的配方ID格式", actionType, "配方ID格式错误", idStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := c.recipeService.GetRecipeByID(reqCtx, uint32(id))
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("%s: 服务层获取配方详情失败: %v, ID: %d", actionType, err, id)
|
||||||
|
if errors.Is(err, recipe.ErrRecipeNotFound) {
|
||||||
|
return controller.SendErrorWithAudit(ctx, controller.CodeNotFound, err.Error(), actionType, "配方不存在", id)
|
||||||
|
}
|
||||||
|
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取配方详情失败: "+err.Error(), actionType, "服务层获取配方详情失败", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Infof("%s: 获取配方详情成功, ID: %d", actionType, id)
|
||||||
|
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取配方详情成功", resp, actionType, "获取配方详情成功", resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRecipes godoc
|
||||||
|
// @Summary 获取配方列表
|
||||||
|
// @Description 获取所有配方的列表,支持分页和过滤。
|
||||||
|
// @Tags 饲料管理-配方
|
||||||
|
// @Security BearerAuth
|
||||||
|
// @Produce json
|
||||||
|
// @Param query query dto.ListRecipeRequest false "查询参数"
|
||||||
|
// @Success 200 {object} controller.Response{data=dto.ListRecipeResponse} "业务码为200代表成功获取列表"
|
||||||
|
// @Router /api/v1/feed/recipes [get]
|
||||||
|
func (c *RecipeController) ListRecipes(ctx echo.Context) error {
|
||||||
|
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "ListRecipes")
|
||||||
|
const actionType = "获取配方列表"
|
||||||
|
var req dto.ListRecipeRequest
|
||||||
|
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.recipeService.ListRecipes(reqCtx, &req)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("%s: 服务层获取配方列表失败: %v", actionType, err)
|
||||||
|
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取配方列表失败: "+err.Error(), actionType, "服务层获取配方列表失败", nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Infof("%s: 获取配方列表成功, 数量: %d", actionType, len(resp.List))
|
||||||
|
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取配方列表成功", resp, actionType, "获取配方列表成功", resp)
|
||||||
|
}
|
||||||
@@ -198,3 +198,84 @@ func ConvertPigTypeListToDTO(pigTypes []models.PigType, total int64, page, pageS
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConvertRecipeToDto 将 models.Recipe 转换为 RecipeResponse DTO
|
||||||
|
func ConvertRecipeToDto(recipe *models.Recipe) *RecipeResponse {
|
||||||
|
if recipe == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ingredients := make([]RecipeIngredientDto, len(recipe.RecipeIngredients))
|
||||||
|
for i, ri := range recipe.RecipeIngredients {
|
||||||
|
ingredients[i] = RecipeIngredientDto{
|
||||||
|
RawMaterialID: ri.RawMaterialID,
|
||||||
|
Percentage: ri.Percentage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &RecipeResponse{
|
||||||
|
ID: recipe.ID,
|
||||||
|
Name: recipe.Name,
|
||||||
|
Description: recipe.Description,
|
||||||
|
RecipeIngredients: ingredients,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConvertRecipeListToDTO 将 []models.Recipe 转换为 ListRecipeResponse DTO
|
||||||
|
func ConvertRecipeListToDTO(recipes []models.Recipe, total int64, page, pageSize int) *ListRecipeResponse {
|
||||||
|
recipeDTOs := make([]RecipeResponse, len(recipes))
|
||||||
|
for i, r := range recipes {
|
||||||
|
recipeDTOs[i] = *ConvertRecipeToDto(&r)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ListRecipeResponse{
|
||||||
|
List: recipeDTOs,
|
||||||
|
Pagination: PaginationDTO{
|
||||||
|
Page: page,
|
||||||
|
PageSize: pageSize,
|
||||||
|
Total: total,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConvertCreateRecipeRequestToModel 将 CreateRecipeRequest DTO 转换为 models.Recipe 模型
|
||||||
|
func ConvertCreateRecipeRequestToModel(req *CreateRecipeRequest) *models.Recipe {
|
||||||
|
if req == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ingredients := make([]models.RecipeIngredient, len(req.RecipeIngredients))
|
||||||
|
for i, ri := range req.RecipeIngredients {
|
||||||
|
ingredients[i] = models.RecipeIngredient{
|
||||||
|
RawMaterialID: ri.RawMaterialID,
|
||||||
|
Percentage: ri.Percentage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &models.Recipe{
|
||||||
|
Name: req.Name,
|
||||||
|
Description: req.Description,
|
||||||
|
RecipeIngredients: ingredients,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConvertUpdateRecipeRequestToModel 将 UpdateRecipeRequest DTO 转换为 models.Recipe 模型
|
||||||
|
func ConvertUpdateRecipeRequestToModel(req *UpdateRecipeRequest) *models.Recipe {
|
||||||
|
if req == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ingredients := make([]models.RecipeIngredient, len(req.RecipeIngredients))
|
||||||
|
for i, ri := range req.RecipeIngredients {
|
||||||
|
ingredients[i] = models.RecipeIngredient{
|
||||||
|
RawMaterialID: ri.RawMaterialID,
|
||||||
|
Percentage: ri.Percentage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &models.Recipe{
|
||||||
|
Name: req.Name,
|
||||||
|
Description: req.Description,
|
||||||
|
RecipeIngredients: ingredients,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -274,3 +274,49 @@ type PigNutrientRequirementItem struct {
|
|||||||
MinRequirement float32 `json:"min_requirement" validate:"gte=0"` // 最低营养需求量
|
MinRequirement float32 `json:"min_requirement" validate:"gte=0"` // 最低营养需求量
|
||||||
MaxRequirement float32 `json:"max_requirement" validate:"gte=0"` // 最高营养需求量
|
MaxRequirement float32 `json:"max_requirement" validate:"gte=0"` // 最高营养需求量
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =============================================================================================================
|
||||||
|
// 配方 (Recipe) 相关 DTO
|
||||||
|
// =============================================================================================================
|
||||||
|
|
||||||
|
// RecipeIngredientDto 代表配方中的一个原料及其百分比
|
||||||
|
type RecipeIngredientDto struct {
|
||||||
|
RawMaterialID uint32 `json:"raw_material_id" validate:"required"` // 原料ID
|
||||||
|
Percentage float32 `json:"percentage" validate:"gte=0,lte=1"` // 原料在配方中的百分比 (0-1之间)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRecipeRequest 创建配方的请求体
|
||||||
|
type CreateRecipeRequest struct {
|
||||||
|
Name string `json:"name" validate:"required,max=100"` // 配方名称
|
||||||
|
Description string `json:"description" validate:"max=255"` // 配方描述
|
||||||
|
RecipeIngredients []RecipeIngredientDto `json:"recipe_ingredients" validate:"dive"` // 配方原料组成
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateRecipeRequest 更新配方的请求体
|
||||||
|
type UpdateRecipeRequest struct {
|
||||||
|
Name string `json:"name" validate:"required,max=100"` // 配方名称
|
||||||
|
Description string `json:"description" validate:"max=255"` // 配方描述
|
||||||
|
RecipeIngredients []RecipeIngredientDto `json:"recipe_ingredients" validate:"dive"` // 配方原料组成
|
||||||
|
}
|
||||||
|
|
||||||
|
// RecipeResponse 配方响应体
|
||||||
|
type RecipeResponse struct {
|
||||||
|
ID uint32 `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
RecipeIngredients []RecipeIngredientDto `json:"recipe_ingredients"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRecipeRequest 定义了获取配方列表的请求参数
|
||||||
|
type ListRecipeRequest 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"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRecipeResponse 是获取配方列表的响应结构
|
||||||
|
type ListRecipeResponse struct {
|
||||||
|
List []RecipeResponse `json:"list"`
|
||||||
|
Pagination PaginationDTO `json:"pagination"`
|
||||||
|
}
|
||||||
|
|||||||
159
internal/app/service/recipe_service.go
Normal file
159
internal/app/service/recipe_service.go
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/domain/recipe"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
|
||||||
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 定义配方服务特定的错误
|
||||||
|
var (
|
||||||
|
ErrRecipeNameConflict = errors.New("配方名称已存在")
|
||||||
|
ErrRecipeNotFound = errors.New("配方不存在")
|
||||||
|
)
|
||||||
|
|
||||||
|
// RecipeService 定义了配方相关的应用服务接口
|
||||||
|
type RecipeService interface {
|
||||||
|
CreateRecipe(ctx context.Context, req *dto.CreateRecipeRequest) (*dto.RecipeResponse, error)
|
||||||
|
UpdateRecipe(ctx context.Context, id uint32, req *dto.UpdateRecipeRequest) (*dto.RecipeResponse, error)
|
||||||
|
DeleteRecipe(ctx context.Context, id uint32) error
|
||||||
|
GetRecipeByID(ctx context.Context, id uint32) (*dto.RecipeResponse, error)
|
||||||
|
ListRecipes(ctx context.Context, req *dto.ListRecipeRequest) (*dto.ListRecipeResponse, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// recipeServiceImpl 是 RecipeService 接口的实现
|
||||||
|
type recipeServiceImpl struct {
|
||||||
|
ctx context.Context
|
||||||
|
recipeSvc recipe.RecipeCoreService
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRecipeService 创建一个新的 RecipeService 实例
|
||||||
|
func NewRecipeService(ctx context.Context, recipeSvc recipe.RecipeCoreService) RecipeService {
|
||||||
|
return &recipeServiceImpl{
|
||||||
|
ctx: ctx,
|
||||||
|
recipeSvc: recipeSvc,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRecipe 创建配方
|
||||||
|
func (s *recipeServiceImpl) CreateRecipe(ctx context.Context, req *dto.CreateRecipeRequest) (*dto.RecipeResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "CreateRecipe")
|
||||||
|
|
||||||
|
recipeModel := dto.ConvertCreateRecipeRequestToModel(req)
|
||||||
|
|
||||||
|
createdRecipe, err := s.recipeSvc.CreateRecipe(serviceCtx, recipeModel)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrRecipeNameConflict) {
|
||||||
|
return nil, ErrRecipeNameConflict
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("创建配方失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建成功后,获取包含完整信息的配方
|
||||||
|
fullRecipe, err := s.recipeSvc.GetRecipeByID(serviceCtx, createdRecipe.ID)
|
||||||
|
if err != nil {
|
||||||
|
// 理论上不应该发生,因为刚创建成功
|
||||||
|
return nil, fmt.Errorf("创建后获取配方信息失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto.ConvertRecipeToDto(fullRecipe), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateRecipe 更新配方
|
||||||
|
func (s *recipeServiceImpl) UpdateRecipe(ctx context.Context, id uint32, req *dto.UpdateRecipeRequest) (*dto.RecipeResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdateRecipe")
|
||||||
|
|
||||||
|
// 1. 转换 DTO 为模型
|
||||||
|
recipeModel := dto.ConvertUpdateRecipeRequestToModel(req)
|
||||||
|
recipeModel.ID = id
|
||||||
|
|
||||||
|
// 2. 更新配方基础信息
|
||||||
|
_, err := s.recipeSvc.UpdateRecipe(serviceCtx, recipeModel)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrRecipeNotFound) {
|
||||||
|
return nil, ErrRecipeNotFound
|
||||||
|
}
|
||||||
|
if errors.Is(err, recipe.ErrRecipeNameConflict) {
|
||||||
|
return nil, ErrRecipeNameConflict
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("更新配方基础信息失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 更新配方原料
|
||||||
|
ingredients := make([]models.RecipeIngredient, len(req.RecipeIngredients))
|
||||||
|
for i, item := range req.RecipeIngredients {
|
||||||
|
ingredients[i] = models.RecipeIngredient{
|
||||||
|
RecipeID: id,
|
||||||
|
RawMaterialID: item.RawMaterialID,
|
||||||
|
Percentage: item.Percentage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = s.recipeSvc.UpdateRecipeIngredients(serviceCtx, id, ingredients)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrRecipeNotFound) {
|
||||||
|
return nil, ErrRecipeNotFound
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("更新配方原料失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 更新成功后,获取最新的完整配方信息并返回
|
||||||
|
updatedRecipe, err := s.recipeSvc.GetRecipeByID(serviceCtx, id)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrRecipeNotFound) {
|
||||||
|
// 理论上不应该发生,因为刚更新成功
|
||||||
|
return nil, ErrRecipeNotFound
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("更新后获取配方信息失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto.ConvertRecipeToDto(updatedRecipe), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRecipe 删除配方
|
||||||
|
func (s *recipeServiceImpl) DeleteRecipe(ctx context.Context, id uint32) error {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "DeleteRecipe")
|
||||||
|
err := s.recipeSvc.DeleteRecipe(serviceCtx, id)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrRecipeNotFound) {
|
||||||
|
return ErrRecipeNotFound
|
||||||
|
}
|
||||||
|
return fmt.Errorf("删除配方失败: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRecipeByID 获取单个配方
|
||||||
|
func (s *recipeServiceImpl) GetRecipeByID(ctx context.Context, id uint32) (*dto.RecipeResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "GetRecipeByID")
|
||||||
|
|
||||||
|
recipeModel, err := s.recipeSvc.GetRecipeByID(serviceCtx, id)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, recipe.ErrRecipeNotFound) {
|
||||||
|
return nil, ErrRecipeNotFound
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("获取配方失败: %w", err)
|
||||||
|
}
|
||||||
|
return dto.ConvertRecipeToDto(recipeModel), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRecipes 列出配方
|
||||||
|
func (s *recipeServiceImpl) ListRecipes(ctx context.Context, req *dto.ListRecipeRequest) (*dto.ListRecipeResponse, error) {
|
||||||
|
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListRecipes")
|
||||||
|
|
||||||
|
opts := repository.RecipeListOptions{
|
||||||
|
Name: req.Name,
|
||||||
|
OrderBy: req.OrderBy,
|
||||||
|
}
|
||||||
|
recipes, total, err := s.recipeSvc.ListRecipes(serviceCtx, opts, req.Page, req.PageSize)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("获取配方列表失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto.ConvertRecipeListToDTO(recipes, total, req.Page, req.PageSize), nil
|
||||||
|
}
|
||||||
@@ -68,6 +68,7 @@ func NewApplication(configPath string) (*Application, error) {
|
|||||||
appServices.pigBreedService,
|
appServices.pigBreedService,
|
||||||
appServices.pigAgeStageService,
|
appServices.pigAgeStageService,
|
||||||
appServices.pigTypeService,
|
appServices.pigTypeService,
|
||||||
|
appServices.recipeService,
|
||||||
infra.tokenGenerator,
|
infra.tokenGenerator,
|
||||||
infra.lora.listenHandler,
|
infra.lora.listenHandler,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -264,6 +264,7 @@ type AppServices struct {
|
|||||||
pigBreedService service.PigBreedService
|
pigBreedService service.PigBreedService
|
||||||
pigTypeService service.PigTypeService
|
pigTypeService service.PigTypeService
|
||||||
rawMaterialService service.RawMaterialService
|
rawMaterialService service.RawMaterialService
|
||||||
|
recipeService service.RecipeService
|
||||||
}
|
}
|
||||||
|
|
||||||
// initAppServices 初始化所有的应用服务。
|
// initAppServices 初始化所有的应用服务。
|
||||||
@@ -316,6 +317,7 @@ func initAppServices(ctx context.Context, infra *Infrastructure, domainServices
|
|||||||
pigBreedService := service.NewPigBreedService(logs.AddCompName(baseCtx, "PigBreedService"), domainServices.recipeService)
|
pigBreedService := service.NewPigBreedService(logs.AddCompName(baseCtx, "PigBreedService"), domainServices.recipeService)
|
||||||
pigTypeService := service.NewPigTypeService(logs.AddCompName(baseCtx, "PigTypeService"), domainServices.recipeService)
|
pigTypeService := service.NewPigTypeService(logs.AddCompName(baseCtx, "PigTypeService"), domainServices.recipeService)
|
||||||
rawMaterialService := service.NewRawMaterialService(logs.AddCompName(baseCtx, "RawMaterialService"), domainServices.recipeService)
|
rawMaterialService := service.NewRawMaterialService(logs.AddCompName(baseCtx, "RawMaterialService"), domainServices.recipeService)
|
||||||
|
recipeService := service.NewRecipeService(logs.AddCompName(baseCtx, "RecipeService"), domainServices.recipeService)
|
||||||
|
|
||||||
return &AppServices{
|
return &AppServices{
|
||||||
pigFarmService: pigFarmService,
|
pigFarmService: pigFarmService,
|
||||||
@@ -331,6 +333,7 @@ func initAppServices(ctx context.Context, infra *Infrastructure, domainServices
|
|||||||
pigBreedService: pigBreedService,
|
pigBreedService: pigBreedService,
|
||||||
pigTypeService: pigTypeService,
|
pigTypeService: pigTypeService,
|
||||||
rawMaterialService: rawMaterialService,
|
rawMaterialService: rawMaterialService,
|
||||||
|
recipeService: recipeService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ internal/app/controller/feed/pig_age_stage_controller.go
|
|||||||
internal/app/controller/feed/pig_breed_controller.go
|
internal/app/controller/feed/pig_breed_controller.go
|
||||||
internal/app/controller/feed/pig_type_controller.go
|
internal/app/controller/feed/pig_type_controller.go
|
||||||
internal/app/controller/feed/raw_material_controller.go
|
internal/app/controller/feed/raw_material_controller.go
|
||||||
|
internal/app/controller/feed/recipe_controller.go
|
||||||
internal/app/controller/health/health_controller.go
|
internal/app/controller/health/health_controller.go
|
||||||
internal/app/controller/management/controller_helpers.go
|
internal/app/controller/management/controller_helpers.go
|
||||||
internal/app/controller/management/pig_batch_controller.go
|
internal/app/controller/management/pig_batch_controller.go
|
||||||
@@ -94,6 +95,7 @@ internal/app/service/pig_service.go
|
|||||||
internal/app/service/pig_type_service.go
|
internal/app/service/pig_type_service.go
|
||||||
internal/app/service/plan_service.go
|
internal/app/service/plan_service.go
|
||||||
internal/app/service/raw_material_service.go
|
internal/app/service/raw_material_service.go
|
||||||
|
internal/app/service/recipe_service.go
|
||||||
internal/app/service/threshold_alarm_service.go
|
internal/app/service/threshold_alarm_service.go
|
||||||
internal/app/service/user_service.go
|
internal/app/service/user_service.go
|
||||||
internal/app/webhook/chirp_stack.go
|
internal/app/webhook/chirp_stack.go
|
||||||
|
|||||||
Reference in New Issue
Block a user