删除原有食物逻辑和模型
新增原料和营养价值表和原料库存日志和营养表定义
This commit is contained in:
47
design/archive/recipe-management/index.md
Normal file
47
design/archive/recipe-management/index.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# 需求
|
||||
|
||||
饲料配方管理及自动生成配方
|
||||
|
||||
## issue
|
||||
|
||||
http://git.huangwc.com/pig/pig-farm-controller/issues/66
|
||||
|
||||
# 开发计划
|
||||
|
||||
1. 原料营养价值管理
|
||||
- 增删改查
|
||||
- 内置60+条常用原料(玉米、豆粕43、豆粕46、发酵豆粕、麸皮、次粉、DDGS、乳清粉、鱼粉、膨化大豆、各种氨基酸、预混料、油脂等)
|
||||
- 每种原料固定营养值(消化能、粗蛋白、赖氨酸、钙、磷等15项左右)
|
||||
|
||||
2. 饲料库存管理(代替批次)
|
||||
- 字段:饲料名、当前原料种类、当前剩余量(吨)、上次入料日期、保质期剩余天数(手动填)、是否发酵料(勾选)
|
||||
- 发酵料塔额外字段:
|
||||
- 发酵状态(未发酵 / 正在发酵 / 已发酵可用)
|
||||
- 发酵开始日期
|
||||
- 发酵几天(默认3~7天)
|
||||
- 水分增加比例(默认+10~20%)
|
||||
- 营养折损系数(可调,粗蛋白-5%、能量-3%之类)
|
||||
|
||||
3. 猪只阶段营养需求管理
|
||||
- 预设10个常用阶段(教槽、仔猪、小猪、中猪、大猪、后备、怀孕前中后、哺乳)
|
||||
- 每个阶段维护营养需求上下限(消化能、粗蛋白、赖氨酸、钙、有效磷等12项)
|
||||
|
||||
4. 配方管理
|
||||
- 按阶段建配方
|
||||
- 支持增删改查 + 复制上个配方快速新建
|
||||
- 配方明细:原料 + 配比(%)
|
||||
|
||||
5. 自动生成配方(核心功能)
|
||||
- 选择阶段 → 点击“自动计算最低成本配方”
|
||||
- 自动读取当前所有料塔的:
|
||||
- 剩余量(不够的原料自动降配比)
|
||||
- 保质期剩余天数(越快过期的优先用,权重×1.5)
|
||||
- 发酵料塔如果状态是“已发酵可用”则按发酵后营养值参与计算
|
||||
- 输出:总成本、营养达标情况、发酵料占比、即将过期原料使用提示
|
||||
|
||||
6. 配方下发与记录
|
||||
- 一键下发到喂料站/料线(生成下料曲线)
|
||||
- 自动记录今天用了哪个配方
|
||||
|
||||
7. 简单查看功能
|
||||
- 两个配方对比页面(营养+成本对比)
|
||||
506
docs/docs.go
506
docs/docs.go
@@ -56,13 +56,13 @@ const docTemplate = `{
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
"Debug",
|
||||
"Info",
|
||||
"Warn",
|
||||
"Error",
|
||||
"DPanic",
|
||||
"Panic",
|
||||
"Fatal"
|
||||
"debug",
|
||||
"info",
|
||||
"warn",
|
||||
"error",
|
||||
"dpanic",
|
||||
"panic",
|
||||
"fatal"
|
||||
],
|
||||
"type": "string",
|
||||
"x-enum-varnames": [
|
||||
@@ -172,13 +172,13 @@ const docTemplate = `{
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
"Debug",
|
||||
"Info",
|
||||
"Warn",
|
||||
"Error",
|
||||
"DPanic",
|
||||
"Panic",
|
||||
"Fatal"
|
||||
"debug",
|
||||
"info",
|
||||
"warn",
|
||||
"error",
|
||||
"dpanic",
|
||||
"panic",
|
||||
"fatal"
|
||||
],
|
||||
"type": "string",
|
||||
"x-enum-varnames": [
|
||||
@@ -453,13 +453,13 @@ const docTemplate = `{
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
"Debug",
|
||||
"Info",
|
||||
"Warn",
|
||||
"Error",
|
||||
"DPanic",
|
||||
"Panic",
|
||||
"Fatal"
|
||||
"debug",
|
||||
"info",
|
||||
"warn",
|
||||
"error",
|
||||
"dpanic",
|
||||
"panic",
|
||||
"fatal"
|
||||
],
|
||||
"type": "string",
|
||||
"x-enum-varnames": [
|
||||
@@ -740,13 +740,13 @@ const docTemplate = `{
|
||||
"parameters": [
|
||||
{
|
||||
"enum": [
|
||||
"Debug",
|
||||
"Info",
|
||||
"Warn",
|
||||
"Error",
|
||||
"DPanic",
|
||||
"Panic",
|
||||
"Fatal"
|
||||
"debug",
|
||||
"info",
|
||||
"warn",
|
||||
"error",
|
||||
"dpanic",
|
||||
"panic",
|
||||
"fatal"
|
||||
],
|
||||
"type": "string",
|
||||
"x-enum-varnames": [
|
||||
@@ -1719,85 +1719,6 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/monitor/feed-usage-records": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "根据提供的过滤条件,分页获取饲料使用记录",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"数据监控"
|
||||
],
|
||||
"summary": "获取饲料使用记录列表",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"name": "end_time",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "feed_formula_id",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "operator_id",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "order_by",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "page_size",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "pen_id",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "start_time",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/controller.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/dto.ListFeedUsageRecordResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/monitor/medication-logs": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -1905,6 +1826,7 @@ const docTemplate = `{
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
7,
|
||||
-1,
|
||||
0,
|
||||
1,
|
||||
@@ -1914,12 +1836,12 @@ const docTemplate = `{
|
||||
5,
|
||||
-1,
|
||||
5,
|
||||
6,
|
||||
7
|
||||
6
|
||||
],
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-enum-varnames": [
|
||||
"_numLevels",
|
||||
"DebugLevel",
|
||||
"InfoLevel",
|
||||
"WarnLevel",
|
||||
@@ -1929,8 +1851,7 @@ const docTemplate = `{
|
||||
"FatalLevel",
|
||||
"_minLevel",
|
||||
"_maxLevel",
|
||||
"InvalidLevel",
|
||||
"_numLevels"
|
||||
"InvalidLevel"
|
||||
],
|
||||
"name": "level",
|
||||
"in": "query"
|
||||
@@ -2588,159 +2509,6 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/monitor/raw-material-purchases": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "根据提供的过滤条件,分页获取原料采购记录",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"数据监控"
|
||||
],
|
||||
"summary": "获取原料采购记录列表",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"name": "end_time",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "order_by",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "page_size",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "raw_material_id",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "start_time",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "supplier",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/controller.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/dto.ListRawMaterialPurchaseResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/monitor/raw-material-stock-logs": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "根据提供的过滤条件,分页获取原料库存日志",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"数据监控"
|
||||
],
|
||||
"summary": "获取原料库存日志列表",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"name": "end_time",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "order_by",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "page_size",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "raw_material_id",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "source_id",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "source_type",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "start_time",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/controller.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/dto.ListRawMaterialStockLogResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/monitor/sensor-data": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -5645,49 +5413,6 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.FeedFormulaDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.FeedUsageRecordDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"amount": {
|
||||
"type": "number"
|
||||
},
|
||||
"feed_formula": {
|
||||
"$ref": "#/definitions/dto.FeedFormulaDTO"
|
||||
},
|
||||
"feed_formula_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"operator_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"pen": {
|
||||
"$ref": "#/definitions/dto.PenDTO"
|
||||
},
|
||||
"pen_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"recorded_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"remarks": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.HistoricalAlarmDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -5782,20 +5507,6 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.ListFeedUsageRecordResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"list": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/dto.FeedUsageRecordDTO"
|
||||
}
|
||||
},
|
||||
"pagination": {
|
||||
"$ref": "#/definitions/dto.PaginationDTO"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.ListHistoricalAlarmResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -5951,34 +5662,6 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.ListRawMaterialPurchaseResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"list": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/dto.RawMaterialPurchaseDTO"
|
||||
}
|
||||
},
|
||||
"pagination": {
|
||||
"$ref": "#/definitions/dto.PaginationDTO"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.ListRawMaterialStockLogResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"list": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/dto.RawMaterialStockLogDTO"
|
||||
}
|
||||
},
|
||||
"pagination": {
|
||||
"$ref": "#/definitions/dto.PaginationDTO"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.ListSensorDataResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -6216,17 +5899,6 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.PenDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.PenResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -6733,75 +6405,6 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.RawMaterialDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.RawMaterialPurchaseDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"amount": {
|
||||
"type": "number"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"purchase_date": {
|
||||
"type": "string"
|
||||
},
|
||||
"raw_material": {
|
||||
"$ref": "#/definitions/dto.RawMaterialDTO"
|
||||
},
|
||||
"raw_material_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"supplier": {
|
||||
"type": "string"
|
||||
},
|
||||
"total_price": {
|
||||
"type": "number"
|
||||
},
|
||||
"unit_price": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.RawMaterialStockLogDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"change_amount": {
|
||||
"type": "number"
|
||||
},
|
||||
"happened_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"raw_material_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"remarks": {
|
||||
"type": "string"
|
||||
},
|
||||
"source_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"source_type": {
|
||||
"$ref": "#/definitions/models.StockLogSourceType"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.ReclassifyPenToNewBatchRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@@ -8140,13 +7743,13 @@ const docTemplate = `{
|
||||
"models.SeverityLevel": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Debug",
|
||||
"Info",
|
||||
"Warn",
|
||||
"Error",
|
||||
"DPanic",
|
||||
"Panic",
|
||||
"Fatal"
|
||||
"debug",
|
||||
"info",
|
||||
"warn",
|
||||
"error",
|
||||
"dpanic",
|
||||
"panic",
|
||||
"fatal"
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"DebugLevel",
|
||||
@@ -8158,25 +7761,6 @@ const docTemplate = `{
|
||||
"FatalLevel"
|
||||
]
|
||||
},
|
||||
"models.StockLogSourceType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"采购入库",
|
||||
"饲喂出库",
|
||||
"变质出库",
|
||||
"售卖出库",
|
||||
"杂用领取",
|
||||
"手动盘点"
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"StockLogSourcePurchase",
|
||||
"StockLogSourceFeeding",
|
||||
"StockLogSourceDeteriorate",
|
||||
"StockLogSourceSale",
|
||||
"StockLogSourceMiscellaneous",
|
||||
"StockLogSourceManual"
|
||||
]
|
||||
},
|
||||
"models.TaskType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
@@ -8185,6 +7769,7 @@ const docTemplate = `{
|
||||
"下料",
|
||||
"全量采集",
|
||||
"告警通知",
|
||||
"通知刷新",
|
||||
"设备阈值检查",
|
||||
"区域阈值检查"
|
||||
],
|
||||
@@ -8194,6 +7779,7 @@ const docTemplate = `{
|
||||
"TaskTypeAreaCollectorThresholdCheck": "区域阈值检查任务",
|
||||
"TaskTypeDeviceThresholdCheck": "设备阈值检查任务",
|
||||
"TaskTypeFullCollection": "新增的全量采集任务",
|
||||
"TaskTypeNotificationRefresh": "通知刷新任务",
|
||||
"TaskTypeReleaseFeedWeight": "下料口释放指定重量任务",
|
||||
"TaskTypeWaiting": "等待任务"
|
||||
},
|
||||
@@ -8203,6 +7789,7 @@ const docTemplate = `{
|
||||
"下料口释放指定重量任务",
|
||||
"新增的全量采集任务",
|
||||
"告警通知任务",
|
||||
"通知刷新任务",
|
||||
"设备阈值检查任务",
|
||||
"区域阈值检查任务"
|
||||
],
|
||||
@@ -8212,6 +7799,7 @@ const docTemplate = `{
|
||||
"TaskTypeReleaseFeedWeight",
|
||||
"TaskTypeFullCollection",
|
||||
"TaskTypeAlarmNotification",
|
||||
"TaskTypeNotificationRefresh",
|
||||
"TaskTypeDeviceThresholdCheck",
|
||||
"TaskTypeAreaCollectorThresholdCheck"
|
||||
]
|
||||
@@ -8249,6 +7837,7 @@ const docTemplate = `{
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"enum": [
|
||||
7,
|
||||
-1,
|
||||
0,
|
||||
1,
|
||||
@@ -8258,10 +7847,10 @@ const docTemplate = `{
|
||||
5,
|
||||
-1,
|
||||
5,
|
||||
6,
|
||||
7
|
||||
6
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"_numLevels",
|
||||
"DebugLevel",
|
||||
"InfoLevel",
|
||||
"WarnLevel",
|
||||
@@ -8271,8 +7860,7 @@ const docTemplate = `{
|
||||
"FatalLevel",
|
||||
"_minLevel",
|
||||
"_maxLevel",
|
||||
"InvalidLevel",
|
||||
"_numLevels"
|
||||
"InvalidLevel"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -48,13 +48,13 @@
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
"Debug",
|
||||
"Info",
|
||||
"Warn",
|
||||
"Error",
|
||||
"DPanic",
|
||||
"Panic",
|
||||
"Fatal"
|
||||
"debug",
|
||||
"info",
|
||||
"warn",
|
||||
"error",
|
||||
"dpanic",
|
||||
"panic",
|
||||
"fatal"
|
||||
],
|
||||
"type": "string",
|
||||
"x-enum-varnames": [
|
||||
@@ -164,13 +164,13 @@
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
"Debug",
|
||||
"Info",
|
||||
"Warn",
|
||||
"Error",
|
||||
"DPanic",
|
||||
"Panic",
|
||||
"Fatal"
|
||||
"debug",
|
||||
"info",
|
||||
"warn",
|
||||
"error",
|
||||
"dpanic",
|
||||
"panic",
|
||||
"fatal"
|
||||
],
|
||||
"type": "string",
|
||||
"x-enum-varnames": [
|
||||
@@ -445,13 +445,13 @@
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
"Debug",
|
||||
"Info",
|
||||
"Warn",
|
||||
"Error",
|
||||
"DPanic",
|
||||
"Panic",
|
||||
"Fatal"
|
||||
"debug",
|
||||
"info",
|
||||
"warn",
|
||||
"error",
|
||||
"dpanic",
|
||||
"panic",
|
||||
"fatal"
|
||||
],
|
||||
"type": "string",
|
||||
"x-enum-varnames": [
|
||||
@@ -732,13 +732,13 @@
|
||||
"parameters": [
|
||||
{
|
||||
"enum": [
|
||||
"Debug",
|
||||
"Info",
|
||||
"Warn",
|
||||
"Error",
|
||||
"DPanic",
|
||||
"Panic",
|
||||
"Fatal"
|
||||
"debug",
|
||||
"info",
|
||||
"warn",
|
||||
"error",
|
||||
"dpanic",
|
||||
"panic",
|
||||
"fatal"
|
||||
],
|
||||
"type": "string",
|
||||
"x-enum-varnames": [
|
||||
@@ -1711,85 +1711,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/monitor/feed-usage-records": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "根据提供的过滤条件,分页获取饲料使用记录",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"数据监控"
|
||||
],
|
||||
"summary": "获取饲料使用记录列表",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"name": "end_time",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "feed_formula_id",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "operator_id",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "order_by",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "page_size",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "pen_id",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "start_time",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/controller.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/dto.ListFeedUsageRecordResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/monitor/medication-logs": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -1897,6 +1818,7 @@
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
7,
|
||||
-1,
|
||||
0,
|
||||
1,
|
||||
@@ -1906,12 +1828,12 @@
|
||||
5,
|
||||
-1,
|
||||
5,
|
||||
6,
|
||||
7
|
||||
6
|
||||
],
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-enum-varnames": [
|
||||
"_numLevels",
|
||||
"DebugLevel",
|
||||
"InfoLevel",
|
||||
"WarnLevel",
|
||||
@@ -1921,8 +1843,7 @@
|
||||
"FatalLevel",
|
||||
"_minLevel",
|
||||
"_maxLevel",
|
||||
"InvalidLevel",
|
||||
"_numLevels"
|
||||
"InvalidLevel"
|
||||
],
|
||||
"name": "level",
|
||||
"in": "query"
|
||||
@@ -2580,159 +2501,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/monitor/raw-material-purchases": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "根据提供的过滤条件,分页获取原料采购记录",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"数据监控"
|
||||
],
|
||||
"summary": "获取原料采购记录列表",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"name": "end_time",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "order_by",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "page_size",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "raw_material_id",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "start_time",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "supplier",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/controller.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/dto.ListRawMaterialPurchaseResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/monitor/raw-material-stock-logs": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "根据提供的过滤条件,分页获取原料库存日志",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"数据监控"
|
||||
],
|
||||
"summary": "获取原料库存日志列表",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"name": "end_time",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "order_by",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "page_size",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "raw_material_id",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "source_id",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "source_type",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "start_time",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/controller.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/dto.ListRawMaterialStockLogResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/monitor/sensor-data": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -5637,49 +5405,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.FeedFormulaDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.FeedUsageRecordDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"amount": {
|
||||
"type": "number"
|
||||
},
|
||||
"feed_formula": {
|
||||
"$ref": "#/definitions/dto.FeedFormulaDTO"
|
||||
},
|
||||
"feed_formula_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"operator_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"pen": {
|
||||
"$ref": "#/definitions/dto.PenDTO"
|
||||
},
|
||||
"pen_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"recorded_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"remarks": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.HistoricalAlarmDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -5774,20 +5499,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.ListFeedUsageRecordResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"list": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/dto.FeedUsageRecordDTO"
|
||||
}
|
||||
},
|
||||
"pagination": {
|
||||
"$ref": "#/definitions/dto.PaginationDTO"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.ListHistoricalAlarmResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -5943,34 +5654,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.ListRawMaterialPurchaseResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"list": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/dto.RawMaterialPurchaseDTO"
|
||||
}
|
||||
},
|
||||
"pagination": {
|
||||
"$ref": "#/definitions/dto.PaginationDTO"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.ListRawMaterialStockLogResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"list": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/dto.RawMaterialStockLogDTO"
|
||||
}
|
||||
},
|
||||
"pagination": {
|
||||
"$ref": "#/definitions/dto.PaginationDTO"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.ListSensorDataResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -6208,17 +5891,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.PenDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.PenResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -6725,75 +6397,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.RawMaterialDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.RawMaterialPurchaseDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"amount": {
|
||||
"type": "number"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"purchase_date": {
|
||||
"type": "string"
|
||||
},
|
||||
"raw_material": {
|
||||
"$ref": "#/definitions/dto.RawMaterialDTO"
|
||||
},
|
||||
"raw_material_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"supplier": {
|
||||
"type": "string"
|
||||
},
|
||||
"total_price": {
|
||||
"type": "number"
|
||||
},
|
||||
"unit_price": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.RawMaterialStockLogDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"change_amount": {
|
||||
"type": "number"
|
||||
},
|
||||
"happened_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"raw_material_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"remarks": {
|
||||
"type": "string"
|
||||
},
|
||||
"source_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"source_type": {
|
||||
"$ref": "#/definitions/models.StockLogSourceType"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.ReclassifyPenToNewBatchRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@@ -8132,13 +7735,13 @@
|
||||
"models.SeverityLevel": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Debug",
|
||||
"Info",
|
||||
"Warn",
|
||||
"Error",
|
||||
"DPanic",
|
||||
"Panic",
|
||||
"Fatal"
|
||||
"debug",
|
||||
"info",
|
||||
"warn",
|
||||
"error",
|
||||
"dpanic",
|
||||
"panic",
|
||||
"fatal"
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"DebugLevel",
|
||||
@@ -8150,25 +7753,6 @@
|
||||
"FatalLevel"
|
||||
]
|
||||
},
|
||||
"models.StockLogSourceType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"采购入库",
|
||||
"饲喂出库",
|
||||
"变质出库",
|
||||
"售卖出库",
|
||||
"杂用领取",
|
||||
"手动盘点"
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"StockLogSourcePurchase",
|
||||
"StockLogSourceFeeding",
|
||||
"StockLogSourceDeteriorate",
|
||||
"StockLogSourceSale",
|
||||
"StockLogSourceMiscellaneous",
|
||||
"StockLogSourceManual"
|
||||
]
|
||||
},
|
||||
"models.TaskType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
@@ -8177,6 +7761,7 @@
|
||||
"下料",
|
||||
"全量采集",
|
||||
"告警通知",
|
||||
"通知刷新",
|
||||
"设备阈值检查",
|
||||
"区域阈值检查"
|
||||
],
|
||||
@@ -8186,6 +7771,7 @@
|
||||
"TaskTypeAreaCollectorThresholdCheck": "区域阈值检查任务",
|
||||
"TaskTypeDeviceThresholdCheck": "设备阈值检查任务",
|
||||
"TaskTypeFullCollection": "新增的全量采集任务",
|
||||
"TaskTypeNotificationRefresh": "通知刷新任务",
|
||||
"TaskTypeReleaseFeedWeight": "下料口释放指定重量任务",
|
||||
"TaskTypeWaiting": "等待任务"
|
||||
},
|
||||
@@ -8195,6 +7781,7 @@
|
||||
"下料口释放指定重量任务",
|
||||
"新增的全量采集任务",
|
||||
"告警通知任务",
|
||||
"通知刷新任务",
|
||||
"设备阈值检查任务",
|
||||
"区域阈值检查任务"
|
||||
],
|
||||
@@ -8204,6 +7791,7 @@
|
||||
"TaskTypeReleaseFeedWeight",
|
||||
"TaskTypeFullCollection",
|
||||
"TaskTypeAlarmNotification",
|
||||
"TaskTypeNotificationRefresh",
|
||||
"TaskTypeDeviceThresholdCheck",
|
||||
"TaskTypeAreaCollectorThresholdCheck"
|
||||
]
|
||||
@@ -8241,6 +7829,7 @@
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"enum": [
|
||||
7,
|
||||
-1,
|
||||
0,
|
||||
1,
|
||||
@@ -8250,10 +7839,10 @@
|
||||
5,
|
||||
-1,
|
||||
5,
|
||||
6,
|
||||
7
|
||||
6
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"_numLevels",
|
||||
"DebugLevel",
|
||||
"InfoLevel",
|
||||
"WarnLevel",
|
||||
@@ -8263,8 +7852,7 @@
|
||||
"FatalLevel",
|
||||
"_minLevel",
|
||||
"_maxLevel",
|
||||
"InvalidLevel",
|
||||
"_numLevels"
|
||||
"InvalidLevel"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -432,34 +432,6 @@ definitions:
|
||||
thresholds:
|
||||
type: number
|
||||
type: object
|
||||
dto.FeedFormulaDTO:
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
name:
|
||||
type: string
|
||||
type: object
|
||||
dto.FeedUsageRecordDTO:
|
||||
properties:
|
||||
amount:
|
||||
type: number
|
||||
feed_formula:
|
||||
$ref: '#/definitions/dto.FeedFormulaDTO'
|
||||
feed_formula_id:
|
||||
type: integer
|
||||
id:
|
||||
type: integer
|
||||
operator_id:
|
||||
type: integer
|
||||
pen:
|
||||
$ref: '#/definitions/dto.PenDTO'
|
||||
pen_id:
|
||||
type: integer
|
||||
recorded_at:
|
||||
type: string
|
||||
remarks:
|
||||
type: string
|
||||
type: object
|
||||
dto.HistoricalAlarmDTO:
|
||||
properties:
|
||||
alarm_code:
|
||||
@@ -521,15 +493,6 @@ definitions:
|
||||
pagination:
|
||||
$ref: '#/definitions/dto.PaginationDTO'
|
||||
type: object
|
||||
dto.ListFeedUsageRecordResponse:
|
||||
properties:
|
||||
list:
|
||||
items:
|
||||
$ref: '#/definitions/dto.FeedUsageRecordDTO'
|
||||
type: array
|
||||
pagination:
|
||||
$ref: '#/definitions/dto.PaginationDTO'
|
||||
type: object
|
||||
dto.ListHistoricalAlarmResponse:
|
||||
properties:
|
||||
list:
|
||||
@@ -630,24 +593,6 @@ definitions:
|
||||
example: 100
|
||||
type: integer
|
||||
type: object
|
||||
dto.ListRawMaterialPurchaseResponse:
|
||||
properties:
|
||||
list:
|
||||
items:
|
||||
$ref: '#/definitions/dto.RawMaterialPurchaseDTO'
|
||||
type: array
|
||||
pagination:
|
||||
$ref: '#/definitions/dto.PaginationDTO'
|
||||
type: object
|
||||
dto.ListRawMaterialStockLogResponse:
|
||||
properties:
|
||||
list:
|
||||
items:
|
||||
$ref: '#/definitions/dto.RawMaterialStockLogDTO'
|
||||
type: array
|
||||
pagination:
|
||||
$ref: '#/definitions/dto.PaginationDTO'
|
||||
type: object
|
||||
dto.ListSensorDataResponse:
|
||||
properties:
|
||||
list:
|
||||
@@ -806,13 +751,6 @@ definitions:
|
||||
total:
|
||||
type: integer
|
||||
type: object
|
||||
dto.PenDTO:
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
name:
|
||||
type: string
|
||||
type: object
|
||||
dto.PenResponse:
|
||||
properties:
|
||||
capacity:
|
||||
@@ -1142,51 +1080,6 @@ definitions:
|
||||
$ref: '#/definitions/dto.TaskResponse'
|
||||
type: array
|
||||
type: object
|
||||
dto.RawMaterialDTO:
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
name:
|
||||
type: string
|
||||
type: object
|
||||
dto.RawMaterialPurchaseDTO:
|
||||
properties:
|
||||
amount:
|
||||
type: number
|
||||
created_at:
|
||||
type: string
|
||||
id:
|
||||
type: integer
|
||||
purchase_date:
|
||||
type: string
|
||||
raw_material:
|
||||
$ref: '#/definitions/dto.RawMaterialDTO'
|
||||
raw_material_id:
|
||||
type: integer
|
||||
supplier:
|
||||
type: string
|
||||
total_price:
|
||||
type: number
|
||||
unit_price:
|
||||
type: number
|
||||
type: object
|
||||
dto.RawMaterialStockLogDTO:
|
||||
properties:
|
||||
change_amount:
|
||||
type: number
|
||||
happened_at:
|
||||
type: string
|
||||
id:
|
||||
type: integer
|
||||
raw_material_id:
|
||||
type: integer
|
||||
remarks:
|
||||
type: string
|
||||
source_id:
|
||||
type: integer
|
||||
source_type:
|
||||
$ref: '#/definitions/models.StockLogSourceType'
|
||||
type: object
|
||||
dto.ReclassifyPenToNewBatchRequest:
|
||||
properties:
|
||||
pen_id:
|
||||
@@ -2159,13 +2052,13 @@ definitions:
|
||||
- SensorTypeWeight
|
||||
models.SeverityLevel:
|
||||
enum:
|
||||
- Debug
|
||||
- Info
|
||||
- Warn
|
||||
- Error
|
||||
- DPanic
|
||||
- Panic
|
||||
- Fatal
|
||||
- debug
|
||||
- info
|
||||
- warn
|
||||
- error
|
||||
- dpanic
|
||||
- panic
|
||||
- fatal
|
||||
type: string
|
||||
x-enum-varnames:
|
||||
- DebugLevel
|
||||
@@ -2175,22 +2068,6 @@ definitions:
|
||||
- DPanicLevel
|
||||
- PanicLevel
|
||||
- FatalLevel
|
||||
models.StockLogSourceType:
|
||||
enum:
|
||||
- 采购入库
|
||||
- 饲喂出库
|
||||
- 变质出库
|
||||
- 售卖出库
|
||||
- 杂用领取
|
||||
- 手动盘点
|
||||
type: string
|
||||
x-enum-varnames:
|
||||
- StockLogSourcePurchase
|
||||
- StockLogSourceFeeding
|
||||
- StockLogSourceDeteriorate
|
||||
- StockLogSourceSale
|
||||
- StockLogSourceMiscellaneous
|
||||
- StockLogSourceManual
|
||||
models.TaskType:
|
||||
enum:
|
||||
- 计划分析
|
||||
@@ -2198,6 +2075,7 @@ definitions:
|
||||
- 下料
|
||||
- 全量采集
|
||||
- 告警通知
|
||||
- 通知刷新
|
||||
- 设备阈值检查
|
||||
- 区域阈值检查
|
||||
type: string
|
||||
@@ -2207,6 +2085,7 @@ definitions:
|
||||
TaskTypeAreaCollectorThresholdCheck: 区域阈值检查任务
|
||||
TaskTypeDeviceThresholdCheck: 设备阈值检查任务
|
||||
TaskTypeFullCollection: 新增的全量采集任务
|
||||
TaskTypeNotificationRefresh: 通知刷新任务
|
||||
TaskTypeReleaseFeedWeight: 下料口释放指定重量任务
|
||||
TaskTypeWaiting: 等待任务
|
||||
x-enum-descriptions:
|
||||
@@ -2215,6 +2094,7 @@ definitions:
|
||||
- 下料口释放指定重量任务
|
||||
- 新增的全量采集任务
|
||||
- 告警通知任务
|
||||
- 通知刷新任务
|
||||
- 设备阈值检查任务
|
||||
- 区域阈值检查任务
|
||||
x-enum-varnames:
|
||||
@@ -2223,6 +2103,7 @@ definitions:
|
||||
- TaskTypeReleaseFeedWeight
|
||||
- TaskTypeFullCollection
|
||||
- TaskTypeAlarmNotification
|
||||
- TaskTypeNotificationRefresh
|
||||
- TaskTypeDeviceThresholdCheck
|
||||
- TaskTypeAreaCollectorThresholdCheck
|
||||
models.ValueDescriptor:
|
||||
@@ -2248,6 +2129,7 @@ definitions:
|
||||
- PlanTypeFilterSystem
|
||||
zapcore.Level:
|
||||
enum:
|
||||
- 7
|
||||
- -1
|
||||
- 0
|
||||
- 1
|
||||
@@ -2258,10 +2140,10 @@ definitions:
|
||||
- -1
|
||||
- 5
|
||||
- 6
|
||||
- 7
|
||||
format: int32
|
||||
type: integer
|
||||
x-enum-varnames:
|
||||
- _numLevels
|
||||
- DebugLevel
|
||||
- InfoLevel
|
||||
- WarnLevel
|
||||
@@ -2272,7 +2154,6 @@ definitions:
|
||||
- _minLevel
|
||||
- _maxLevel
|
||||
- InvalidLevel
|
||||
- _numLevels
|
||||
info:
|
||||
contact:
|
||||
email: divano@example.com
|
||||
@@ -2353,13 +2234,13 @@ paths:
|
||||
type: boolean
|
||||
- description: 按告警严重性等级过滤
|
||||
enum:
|
||||
- Debug
|
||||
- Info
|
||||
- Warn
|
||||
- Error
|
||||
- DPanic
|
||||
- Panic
|
||||
- Fatal
|
||||
- debug
|
||||
- info
|
||||
- warn
|
||||
- error
|
||||
- dpanic
|
||||
- panic
|
||||
- fatal
|
||||
in: query
|
||||
name: level
|
||||
type: string
|
||||
@@ -2430,13 +2311,13 @@ paths:
|
||||
type: integer
|
||||
- description: 按告警等级过滤
|
||||
enum:
|
||||
- Debug
|
||||
- Info
|
||||
- Warn
|
||||
- Error
|
||||
- DPanic
|
||||
- Panic
|
||||
- Fatal
|
||||
- debug
|
||||
- info
|
||||
- warn
|
||||
- error
|
||||
- dpanic
|
||||
- panic
|
||||
- fatal
|
||||
in: query
|
||||
name: level
|
||||
type: string
|
||||
@@ -2612,13 +2493,13 @@ paths:
|
||||
type: integer
|
||||
- description: 按告警等级过滤
|
||||
enum:
|
||||
- Debug
|
||||
- Info
|
||||
- Warn
|
||||
- Error
|
||||
- DPanic
|
||||
- Panic
|
||||
- Fatal
|
||||
- debug
|
||||
- info
|
||||
- warn
|
||||
- error
|
||||
- dpanic
|
||||
- panic
|
||||
- fatal
|
||||
in: query
|
||||
name: level
|
||||
type: string
|
||||
@@ -2798,13 +2679,13 @@ paths:
|
||||
parameters:
|
||||
- description: 按告警严重性等级过滤
|
||||
enum:
|
||||
- Debug
|
||||
- Info
|
||||
- Warn
|
||||
- Error
|
||||
- DPanic
|
||||
- Panic
|
||||
- Fatal
|
||||
- debug
|
||||
- info
|
||||
- warn
|
||||
- error
|
||||
- dpanic
|
||||
- panic
|
||||
- fatal
|
||||
in: query
|
||||
name: level
|
||||
type: string
|
||||
@@ -3333,51 +3214,6 @@ paths:
|
||||
summary: 获取设备命令日志列表
|
||||
tags:
|
||||
- 数据监控
|
||||
/api/v1/monitor/feed-usage-records:
|
||||
get:
|
||||
description: 根据提供的过滤条件,分页获取饲料使用记录
|
||||
parameters:
|
||||
- in: query
|
||||
name: end_time
|
||||
type: string
|
||||
- in: query
|
||||
name: feed_formula_id
|
||||
type: integer
|
||||
- in: query
|
||||
name: operator_id
|
||||
type: integer
|
||||
- in: query
|
||||
name: order_by
|
||||
type: string
|
||||
- in: query
|
||||
name: page
|
||||
type: integer
|
||||
- in: query
|
||||
name: page_size
|
||||
type: integer
|
||||
- in: query
|
||||
name: pen_id
|
||||
type: integer
|
||||
- in: query
|
||||
name: start_time
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/controller.Response'
|
||||
- properties:
|
||||
data:
|
||||
$ref: '#/definitions/dto.ListFeedUsageRecordResponse'
|
||||
type: object
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 获取饲料使用记录列表
|
||||
tags:
|
||||
- 数据监控
|
||||
/api/v1/monitor/medication-logs:
|
||||
get:
|
||||
description: 根据提供的过滤条件,分页获取用药记录
|
||||
@@ -3434,6 +3270,7 @@ paths:
|
||||
name: end_time
|
||||
type: string
|
||||
- enum:
|
||||
- 7
|
||||
- -1
|
||||
- 0
|
||||
- 1
|
||||
@@ -3444,12 +3281,12 @@ paths:
|
||||
- -1
|
||||
- 5
|
||||
- 6
|
||||
- 7
|
||||
format: int32
|
||||
in: query
|
||||
name: level
|
||||
type: integer
|
||||
x-enum-varnames:
|
||||
- _numLevels
|
||||
- DebugLevel
|
||||
- InfoLevel
|
||||
- WarnLevel
|
||||
@@ -3460,7 +3297,6 @@ paths:
|
||||
- _minLevel
|
||||
- _maxLevel
|
||||
- InvalidLevel
|
||||
- _numLevels
|
||||
- enum:
|
||||
- 邮件
|
||||
- 企业微信
|
||||
@@ -3846,93 +3682,6 @@ paths:
|
||||
summary: 获取计划执行日志列表
|
||||
tags:
|
||||
- 数据监控
|
||||
/api/v1/monitor/raw-material-purchases:
|
||||
get:
|
||||
description: 根据提供的过滤条件,分页获取原料采购记录
|
||||
parameters:
|
||||
- in: query
|
||||
name: end_time
|
||||
type: string
|
||||
- in: query
|
||||
name: order_by
|
||||
type: string
|
||||
- in: query
|
||||
name: page
|
||||
type: integer
|
||||
- in: query
|
||||
name: page_size
|
||||
type: integer
|
||||
- in: query
|
||||
name: raw_material_id
|
||||
type: integer
|
||||
- in: query
|
||||
name: start_time
|
||||
type: string
|
||||
- in: query
|
||||
name: supplier
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/controller.Response'
|
||||
- properties:
|
||||
data:
|
||||
$ref: '#/definitions/dto.ListRawMaterialPurchaseResponse'
|
||||
type: object
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 获取原料采购记录列表
|
||||
tags:
|
||||
- 数据监控
|
||||
/api/v1/monitor/raw-material-stock-logs:
|
||||
get:
|
||||
description: 根据提供的过滤条件,分页获取原料库存日志
|
||||
parameters:
|
||||
- in: query
|
||||
name: end_time
|
||||
type: string
|
||||
- in: query
|
||||
name: order_by
|
||||
type: string
|
||||
- in: query
|
||||
name: page
|
||||
type: integer
|
||||
- in: query
|
||||
name: page_size
|
||||
type: integer
|
||||
- in: query
|
||||
name: raw_material_id
|
||||
type: integer
|
||||
- in: query
|
||||
name: source_id
|
||||
type: integer
|
||||
- in: query
|
||||
name: source_type
|
||||
type: string
|
||||
- in: query
|
||||
name: start_time
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/controller.Response'
|
||||
- properties:
|
||||
data:
|
||||
$ref: '#/definitions/dto.ListRawMaterialStockLogResponse'
|
||||
type: object
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 获取原料库存日志列表
|
||||
tags:
|
||||
- 数据监控
|
||||
/api/v1/monitor/sensor-data:
|
||||
get:
|
||||
description: 根据提供的过滤条件,分页获取传感器数据
|
||||
|
||||
@@ -173,9 +173,6 @@ func (a *API) setupRoutes() {
|
||||
monitorGroup.GET("/task-execution-logs", a.monitorController.ListTaskExecutionLogs)
|
||||
monitorGroup.GET("/pending-collections", a.monitorController.ListPendingCollections)
|
||||
monitorGroup.GET("/user-action-logs", a.monitorController.ListUserActionLogs)
|
||||
monitorGroup.GET("/raw-material-purchases", a.monitorController.ListRawMaterialPurchases)
|
||||
monitorGroup.GET("raw-material-stock-logs", a.monitorController.ListRawMaterialStockLogs)
|
||||
monitorGroup.GET("/feed-usage-records", a.monitorController.ListFeedUsageRecords)
|
||||
monitorGroup.GET("/medication-logs", a.monitorController.ListMedicationLogs)
|
||||
monitorGroup.GET("/pig-batch-logs", a.monitorController.ListPigBatchLogs)
|
||||
monitorGroup.GET("/weighing-batches", a.monitorController.ListWeighingBatches)
|
||||
|
||||
@@ -231,108 +231,6 @@ func (c *Controller) ListUserActionLogs(ctx echo.Context) error {
|
||||
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取用户操作日志成功", resp, actionType, "获取用户操作日志成功", req)
|
||||
}
|
||||
|
||||
// ListRawMaterialPurchases godoc
|
||||
// @Summary 获取原料采购记录列表
|
||||
// @Description 根据提供的过滤条件,分页获取原料采购记录
|
||||
// @Tags 数据监控
|
||||
// @Security BearerAuth
|
||||
// @Produce json
|
||||
// @Param query query dto.ListRawMaterialPurchaseRequest true "查询参数"
|
||||
// @Success 200 {object} controller.Response{data=dto.ListRawMaterialPurchaseResponse}
|
||||
// @Router /api/v1/monitor/raw-material-purchases [get]
|
||||
func (c *Controller) ListRawMaterialPurchases(ctx echo.Context) error {
|
||||
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "ListRawMaterialPurchases")
|
||||
const actionType = "获取原料采购记录列表"
|
||||
|
||||
var req dto.ListRawMaterialPurchaseRequest
|
||||
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.monitorService.ListRawMaterialPurchases(reqCtx, &req)
|
||||
if err != nil {
|
||||
if errors.Is(err, repository.ErrInvalidPagination) {
|
||||
logger.Warnf("%s: 无效的分页参数: %v", actionType, err)
|
||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的分页参数: "+err.Error(), actionType, "无效分页参数", req)
|
||||
}
|
||||
|
||||
logger.Errorf("%s: 服务层查询失败: %v", actionType, err)
|
||||
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取原料采购记录失败: "+err.Error(), actionType, "服务层查询失败", req)
|
||||
}
|
||||
|
||||
logger.Infof("%s: 成功, 获取到 %d 条记录, 总计 %d 条", actionType, len(resp.List), resp.Pagination.Total)
|
||||
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取原料采购记录成功", resp, actionType, "获取原料采购记录成功", req)
|
||||
}
|
||||
|
||||
// ListRawMaterialStockLogs godoc
|
||||
// @Summary 获取原料库存日志列表
|
||||
// @Description 根据提供的过滤条件,分页获取原料库存日志
|
||||
// @Tags 数据监控
|
||||
// @Security BearerAuth
|
||||
// @Produce json
|
||||
// @Param query query dto.ListRawMaterialStockLogRequest true "查询参数"
|
||||
// @Success 200 {object} controller.Response{data=dto.ListRawMaterialStockLogResponse}
|
||||
// @Router /api/v1/monitor/raw-material-stock-logs [get]
|
||||
func (c *Controller) ListRawMaterialStockLogs(ctx echo.Context) error {
|
||||
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "ListRawMaterialStockLogs")
|
||||
const actionType = "获取原料库存日志列表"
|
||||
|
||||
var req dto.ListRawMaterialStockLogRequest
|
||||
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.monitorService.ListRawMaterialStockLogs(reqCtx, &req)
|
||||
if err != nil {
|
||||
if errors.Is(err, repository.ErrInvalidPagination) {
|
||||
logger.Warnf("%s: 无效的分页参数: %v", actionType, err)
|
||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的分页参数: "+err.Error(), actionType, "无效分页参数", req)
|
||||
}
|
||||
|
||||
logger.Errorf("%s: 服务层查询失败: %v", actionType, err)
|
||||
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取原料库存日志失败: "+err.Error(), actionType, "服务层查询失败", req)
|
||||
}
|
||||
|
||||
logger.Infof("%s: 成功, 获取到 %d 条记录, 总计 %d 条", actionType, len(resp.List), resp.Pagination.Total)
|
||||
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取原料库存日志成功", resp, actionType, "获取原料库存日志成功", req)
|
||||
}
|
||||
|
||||
// ListFeedUsageRecords godoc
|
||||
// @Summary 获取饲料使用记录列表
|
||||
// @Description 根据提供的过滤条件,分页获取饲料使用记录
|
||||
// @Tags 数据监控
|
||||
// @Security BearerAuth
|
||||
// @Produce json
|
||||
// @Param query query dto.ListFeedUsageRecordRequest true "查询参数"
|
||||
// @Success 200 {object} controller.Response{data=dto.ListFeedUsageRecordResponse}
|
||||
// @Router /api/v1/monitor/feed-usage-records [get]
|
||||
func (c *Controller) ListFeedUsageRecords(ctx echo.Context) error {
|
||||
reqCtx, logger := logs.Trace(ctx.Request().Context(), c.ctx, "ListFeedUsageRecords")
|
||||
const actionType = "获取饲料使用记录列表"
|
||||
|
||||
var req dto.ListFeedUsageRecordRequest
|
||||
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.monitorService.ListFeedUsageRecords(reqCtx, &req)
|
||||
if err != nil {
|
||||
if errors.Is(err, repository.ErrInvalidPagination) {
|
||||
logger.Warnf("%s: 无效的分页参数: %v", actionType, err)
|
||||
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的分页参数: "+err.Error(), actionType, "无效分页参数", req)
|
||||
}
|
||||
|
||||
logger.Errorf("%s: 服务层查询失败: %v", actionType, err)
|
||||
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取饲料使用记录失败: "+err.Error(), actionType, "服务层查询失败", req)
|
||||
}
|
||||
|
||||
logger.Infof("%s: 成功, 获取到 %d 条记录, 总计 %d 条", actionType, len(resp.List), resp.Pagination.Total)
|
||||
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取饲料使用记录成功", resp, actionType, "获取饲料使用记录成功", req)
|
||||
}
|
||||
|
||||
// ListMedicationLogs godoc
|
||||
// @Summary 获取用药记录列表
|
||||
// @Description 根据提供的过滤条件,分页获取用药记录
|
||||
|
||||
@@ -170,94 +170,6 @@ func NewListUserActionLogResponse(data []models.UserActionLog, total int64, page
|
||||
}
|
||||
}
|
||||
|
||||
// NewListRawMaterialPurchaseResponse 从模型数据创建列表响应 DTO
|
||||
func NewListRawMaterialPurchaseResponse(data []models.RawMaterialPurchase, total int64, page, pageSize int) *ListRawMaterialPurchaseResponse {
|
||||
dtos := make([]RawMaterialPurchaseDTO, len(data))
|
||||
for i, item := range data {
|
||||
dtos[i] = RawMaterialPurchaseDTO{
|
||||
ID: item.ID,
|
||||
RawMaterialID: item.RawMaterialID,
|
||||
RawMaterial: RawMaterialDTO{
|
||||
ID: item.RawMaterial.ID,
|
||||
Name: item.RawMaterial.Name,
|
||||
},
|
||||
Supplier: item.Supplier,
|
||||
Amount: item.Amount,
|
||||
UnitPrice: item.UnitPrice,
|
||||
TotalPrice: item.TotalPrice,
|
||||
PurchaseDate: item.PurchaseDate,
|
||||
CreatedAt: item.CreatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
return &ListRawMaterialPurchaseResponse{
|
||||
List: dtos,
|
||||
Pagination: PaginationDTO{
|
||||
Total: total,
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// NewListRawMaterialStockLogResponse 从模型数据创建列表响应 DTO
|
||||
func NewListRawMaterialStockLogResponse(data []models.RawMaterialStockLog, total int64, page, pageSize int) *ListRawMaterialStockLogResponse {
|
||||
dtos := make([]RawMaterialStockLogDTO, len(data))
|
||||
for i, item := range data {
|
||||
dtos[i] = RawMaterialStockLogDTO{
|
||||
ID: item.ID,
|
||||
RawMaterialID: item.RawMaterialID,
|
||||
ChangeAmount: item.ChangeAmount,
|
||||
SourceType: item.SourceType,
|
||||
SourceID: item.SourceID,
|
||||
HappenedAt: item.HappenedAt,
|
||||
Remarks: item.Remarks,
|
||||
}
|
||||
}
|
||||
|
||||
return &ListRawMaterialStockLogResponse{
|
||||
List: dtos,
|
||||
Pagination: PaginationDTO{
|
||||
Total: total,
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// NewListFeedUsageRecordResponse 从模型数据创建列表响应 DTO
|
||||
func NewListFeedUsageRecordResponse(data []models.FeedUsageRecord, total int64, page, pageSize int) *ListFeedUsageRecordResponse {
|
||||
dtos := make([]FeedUsageRecordDTO, len(data))
|
||||
for i, item := range data {
|
||||
dtos[i] = FeedUsageRecordDTO{
|
||||
ID: item.ID,
|
||||
PenID: item.PenID,
|
||||
Pen: PenDTO{
|
||||
ID: item.Pen.ID,
|
||||
Name: item.Pen.PenNumber,
|
||||
},
|
||||
FeedFormulaID: item.FeedFormulaID,
|
||||
FeedFormula: FeedFormulaDTO{
|
||||
ID: item.FeedFormula.ID,
|
||||
Name: item.FeedFormula.Name,
|
||||
},
|
||||
Amount: item.Amount,
|
||||
RecordedAt: item.RecordedAt,
|
||||
OperatorID: item.OperatorID,
|
||||
Remarks: item.Remarks,
|
||||
}
|
||||
}
|
||||
|
||||
return &ListFeedUsageRecordResponse{
|
||||
List: dtos,
|
||||
Pagination: PaginationDTO{
|
||||
Total: total,
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// NewListMedicationLogResponse 从模型数据创建列表响应 DTO
|
||||
func NewListMedicationLogResponse(data []models.MedicationLog, total int64, page, pageSize int) *ListMedicationLogResponse {
|
||||
dtos := make([]MedicationLogDTO, len(data))
|
||||
|
||||
@@ -202,120 +202,6 @@ type ListUserActionLogResponse struct {
|
||||
Pagination PaginationDTO `json:"pagination"`
|
||||
}
|
||||
|
||||
// --- RawMaterialPurchase ---
|
||||
|
||||
// ListRawMaterialPurchaseRequest 定义了获取原料采购列表的请求参数
|
||||
type ListRawMaterialPurchaseRequest struct {
|
||||
Page int `json:"page" query:"page"`
|
||||
PageSize int `json:"page_size" query:"page_size"`
|
||||
RawMaterialID *uint32 `json:"raw_material_id" query:"raw_material_id"`
|
||||
Supplier *string `json:"supplier" query:"supplier"`
|
||||
StartTime *time.Time `json:"start_time" query:"start_time"`
|
||||
EndTime *time.Time `json:"end_time" query:"end_time"`
|
||||
OrderBy string `json:"order_by" query:"order_by"`
|
||||
}
|
||||
|
||||
// RawMaterialDTO 是用于API响应的简化版原料结构
|
||||
type RawMaterialDTO struct {
|
||||
ID uint32 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// RawMaterialPurchaseDTO 是用于API响应的原料采购结构
|
||||
type RawMaterialPurchaseDTO struct {
|
||||
ID uint32 `json:"id"`
|
||||
RawMaterialID uint32 `json:"raw_material_id"`
|
||||
RawMaterial RawMaterialDTO `json:"raw_material"`
|
||||
Supplier string `json:"supplier"`
|
||||
Amount float32 `json:"amount"`
|
||||
UnitPrice float32 `json:"unit_price"`
|
||||
TotalPrice float32 `json:"total_price"`
|
||||
PurchaseDate time.Time `json:"purchase_date"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// ListRawMaterialPurchaseResponse 是获取原料采购列表的响应结构
|
||||
type ListRawMaterialPurchaseResponse struct {
|
||||
List []RawMaterialPurchaseDTO `json:"list"`
|
||||
Pagination PaginationDTO `json:"pagination"`
|
||||
}
|
||||
|
||||
// --- RawMaterialStockLog ---
|
||||
|
||||
// ListRawMaterialStockLogRequest 定义了获取原料库存日志列表的请求参数
|
||||
type ListRawMaterialStockLogRequest struct {
|
||||
Page int `json:"page" query:"page"`
|
||||
PageSize int `json:"page_size" query:"page_size"`
|
||||
RawMaterialID *uint32 `json:"raw_material_id" query:"raw_material_id"`
|
||||
SourceType *string `json:"source_type" query:"source_type"`
|
||||
SourceID *uint32 `json:"source_id" query:"source_id"`
|
||||
StartTime *time.Time `json:"start_time" query:"start_time"`
|
||||
EndTime *time.Time `json:"end_time" query:"end_time"`
|
||||
OrderBy string `json:"order_by" query:"order_by"`
|
||||
}
|
||||
|
||||
// RawMaterialStockLogDTO 是用于API响应的原料库存日志结构
|
||||
type RawMaterialStockLogDTO struct {
|
||||
ID uint32 `json:"id"`
|
||||
RawMaterialID uint32 `json:"raw_material_id"`
|
||||
ChangeAmount float32 `json:"change_amount"`
|
||||
SourceType models.StockLogSourceType `json:"source_type"`
|
||||
SourceID uint32 `json:"source_id"`
|
||||
HappenedAt time.Time `json:"happened_at"`
|
||||
Remarks string `json:"remarks"`
|
||||
}
|
||||
|
||||
// ListRawMaterialStockLogResponse 是获取原料库存日志列表的响应结构
|
||||
type ListRawMaterialStockLogResponse struct {
|
||||
List []RawMaterialStockLogDTO `json:"list"`
|
||||
Pagination PaginationDTO `json:"pagination"`
|
||||
}
|
||||
|
||||
// --- FeedUsageRecord ---
|
||||
|
||||
// ListFeedUsageRecordRequest 定义了获取饲料使用记录列表的请求参数
|
||||
type ListFeedUsageRecordRequest struct {
|
||||
Page int `json:"page" query:"page"`
|
||||
PageSize int `json:"page_size" query:"page_size"`
|
||||
PenID *uint32 `json:"pen_id" query:"pen_id"`
|
||||
FeedFormulaID *uint32 `json:"feed_formula_id" query:"feed_formula_id"`
|
||||
OperatorID *uint32 `json:"operator_id" query:"operator_id"`
|
||||
StartTime *time.Time `json:"start_time" query:"start_time"`
|
||||
EndTime *time.Time `json:"end_time" query:"end_time"`
|
||||
OrderBy string `json:"order_by" query:"order_by"`
|
||||
}
|
||||
|
||||
// PenDTO 是用于API响应的简化版猪栏结构
|
||||
type PenDTO struct {
|
||||
ID uint32 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// FeedFormulaDTO 是用于API响应的简化版饲料配方结构
|
||||
type FeedFormulaDTO struct {
|
||||
ID uint32 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// FeedUsageRecordDTO 是用于API响应的饲料使用记录结构
|
||||
type FeedUsageRecordDTO struct {
|
||||
ID uint32 `json:"id"`
|
||||
PenID uint32 `json:"pen_id"`
|
||||
Pen PenDTO `json:"pen"`
|
||||
FeedFormulaID uint32 `json:"feed_formula_id"`
|
||||
FeedFormula FeedFormulaDTO `json:"feed_formula"`
|
||||
Amount float32 `json:"amount"`
|
||||
RecordedAt time.Time `json:"recorded_at"`
|
||||
OperatorID uint32 `json:"operator_id"`
|
||||
Remarks string `json:"remarks"`
|
||||
}
|
||||
|
||||
// ListFeedUsageRecordResponse 是获取饲料使用记录列表的响应结构
|
||||
type ListFeedUsageRecordResponse struct {
|
||||
List []FeedUsageRecordDTO `json:"list"`
|
||||
Pagination PaginationDTO `json:"pagination"`
|
||||
}
|
||||
|
||||
// --- MedicationLog ---
|
||||
|
||||
// ListMedicationLogRequest 定义了获取用药记录列表的请求参数
|
||||
|
||||
@@ -17,9 +17,6 @@ type MonitorService interface {
|
||||
ListTaskExecutionLogs(ctx context.Context, req *dto.ListTaskExecutionLogRequest) (*dto.ListTaskExecutionLogResponse, error)
|
||||
ListPendingCollections(ctx context.Context, req *dto.ListPendingCollectionRequest) (*dto.ListPendingCollectionResponse, error)
|
||||
ListUserActionLogs(ctx context.Context, req *dto.ListUserActionLogRequest) (*dto.ListUserActionLogResponse, error)
|
||||
ListRawMaterialPurchases(ctx context.Context, req *dto.ListRawMaterialPurchaseRequest) (*dto.ListRawMaterialPurchaseResponse, error)
|
||||
ListRawMaterialStockLogs(ctx context.Context, req *dto.ListRawMaterialStockLogRequest) (*dto.ListRawMaterialStockLogResponse, error)
|
||||
ListFeedUsageRecords(ctx context.Context, req *dto.ListFeedUsageRecordRequest) (*dto.ListFeedUsageRecordResponse, error)
|
||||
ListMedicationLogs(ctx context.Context, req *dto.ListMedicationLogRequest) (*dto.ListMedicationLogResponse, error)
|
||||
ListPigBatchLogs(ctx context.Context, req *dto.ListPigBatchLogRequest) (*dto.ListPigBatchLogResponse, error)
|
||||
ListWeighingBatches(ctx context.Context, req *dto.ListWeighingBatchRequest) (*dto.ListWeighingBatchResponse, error)
|
||||
@@ -40,7 +37,6 @@ type monitorService struct {
|
||||
planRepository repository.PlanRepository
|
||||
pendingCollectionRepo repository.PendingCollectionRepository
|
||||
userActionLogRepo repository.UserActionLogRepository
|
||||
rawMaterialRepo repository.RawMaterialRepository
|
||||
medicationRepo repository.MedicationLogRepository
|
||||
pigBatchRepo repository.PigBatchRepository
|
||||
pigBatchLogRepo repository.PigBatchLogRepository
|
||||
@@ -59,7 +55,6 @@ func NewMonitorService(
|
||||
planRepository repository.PlanRepository,
|
||||
pendingCollectionRepo repository.PendingCollectionRepository,
|
||||
userActionLogRepo repository.UserActionLogRepository,
|
||||
rawMaterialRepo repository.RawMaterialRepository,
|
||||
medicationRepo repository.MedicationLogRepository,
|
||||
pigBatchRepo repository.PigBatchRepository,
|
||||
pigBatchLogRepo repository.PigBatchLogRepository,
|
||||
@@ -76,7 +71,6 @@ func NewMonitorService(
|
||||
planRepository: planRepository,
|
||||
pendingCollectionRepo: pendingCollectionRepo,
|
||||
userActionLogRepo: userActionLogRepo,
|
||||
rawMaterialRepo: rawMaterialRepo,
|
||||
medicationRepo: medicationRepo,
|
||||
pigBatchRepo: pigBatchRepo,
|
||||
pigBatchLogRepo: pigBatchLogRepo,
|
||||
@@ -236,68 +230,6 @@ func (s *monitorService) ListUserActionLogs(ctx context.Context, req *dto.ListUs
|
||||
return dto.NewListUserActionLogResponse(data, total, req.Page, req.PageSize), nil
|
||||
}
|
||||
|
||||
// ListRawMaterialPurchases 负责处理查询原料采购记录列表的业务逻辑
|
||||
func (s *monitorService) ListRawMaterialPurchases(ctx context.Context, req *dto.ListRawMaterialPurchaseRequest) (*dto.ListRawMaterialPurchaseResponse, error) {
|
||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListRawMaterialPurchases")
|
||||
opts := repository.RawMaterialPurchaseListOptions{
|
||||
RawMaterialID: req.RawMaterialID,
|
||||
Supplier: req.Supplier,
|
||||
OrderBy: req.OrderBy,
|
||||
StartTime: req.StartTime,
|
||||
EndTime: req.EndTime,
|
||||
}
|
||||
|
||||
data, total, err := s.rawMaterialRepo.ListRawMaterialPurchases(serviceCtx, opts, req.Page, req.PageSize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return dto.NewListRawMaterialPurchaseResponse(data, total, req.Page, req.PageSize), nil
|
||||
}
|
||||
|
||||
// ListRawMaterialStockLogs 负责处理查询原料库存日志列表的业务逻辑
|
||||
func (s *monitorService) ListRawMaterialStockLogs(ctx context.Context, req *dto.ListRawMaterialStockLogRequest) (*dto.ListRawMaterialStockLogResponse, error) {
|
||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListRawMaterialStockLogs")
|
||||
opts := repository.RawMaterialStockLogListOptions{
|
||||
RawMaterialID: req.RawMaterialID,
|
||||
SourceID: req.SourceID,
|
||||
OrderBy: req.OrderBy,
|
||||
StartTime: req.StartTime,
|
||||
EndTime: req.EndTime,
|
||||
}
|
||||
if req.SourceType != nil {
|
||||
sourceType := models.StockLogSourceType(*req.SourceType)
|
||||
opts.SourceType = &sourceType
|
||||
}
|
||||
|
||||
data, total, err := s.rawMaterialRepo.ListRawMaterialStockLogs(serviceCtx, opts, req.Page, req.PageSize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return dto.NewListRawMaterialStockLogResponse(data, total, req.Page, req.PageSize), nil
|
||||
}
|
||||
|
||||
// ListFeedUsageRecords 负责处理查询饲料使用记录列表的业务逻辑
|
||||
func (s *monitorService) ListFeedUsageRecords(ctx context.Context, req *dto.ListFeedUsageRecordRequest) (*dto.ListFeedUsageRecordResponse, error) {
|
||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListFeedUsageRecords")
|
||||
opts := repository.FeedUsageRecordListOptions{
|
||||
PenID: req.PenID,
|
||||
FeedFormulaID: req.FeedFormulaID,
|
||||
OperatorID: req.OperatorID,
|
||||
OrderBy: req.OrderBy,
|
||||
StartTime: req.StartTime,
|
||||
EndTime: req.EndTime,
|
||||
}
|
||||
|
||||
data, total, err := s.rawMaterialRepo.ListFeedUsageRecords(serviceCtx, opts, req.Page, req.PageSize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return dto.NewListFeedUsageRecordResponse(data, total, req.Page, req.PageSize), nil
|
||||
}
|
||||
|
||||
// ListMedicationLogs 负责处理查询用药记录列表的业务逻辑
|
||||
func (s *monitorService) ListMedicationLogs(ctx context.Context, req *dto.ListMedicationLogRequest) (*dto.ListMedicationLogResponse, error) {
|
||||
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListMedicationLogs")
|
||||
|
||||
@@ -79,7 +79,6 @@ type Repositories struct {
|
||||
pigTradeRepo repository.PigTradeRepository
|
||||
pigSickPigLogRepo repository.PigSickLogRepository
|
||||
medicationLogRepo repository.MedicationLogRepository
|
||||
rawMaterialRepo repository.RawMaterialRepository
|
||||
notificationRepo repository.NotificationRepository
|
||||
alarmRepo repository.AlarmRepository
|
||||
unitOfWork repository.UnitOfWork
|
||||
@@ -108,7 +107,6 @@ func initRepositories(ctx context.Context, db *gorm.DB) *Repositories {
|
||||
pigTradeRepo: repository.NewGormPigTradeRepository(logs.AddCompName(baseCtx, "PigTradeRepo"), db),
|
||||
pigSickPigLogRepo: repository.NewGormPigSickLogRepository(logs.AddCompName(baseCtx, "PigSickPigLogRepo"), db),
|
||||
medicationLogRepo: repository.NewGormMedicationLogRepository(logs.AddCompName(baseCtx, "MedicationLogRepo"), db),
|
||||
rawMaterialRepo: repository.NewGormRawMaterialRepository(logs.AddCompName(baseCtx, "RawMaterialRepo"), db),
|
||||
notificationRepo: repository.NewGormNotificationRepository(logs.AddCompName(baseCtx, "NotificationRepo"), db),
|
||||
alarmRepo: repository.NewGormAlarmRepository(logs.AddCompName(baseCtx, "AlarmRepo"), db),
|
||||
unitOfWork: repository.NewGormUnitOfWork(logs.AddCompName(baseCtx, "UnitOfWork"), db),
|
||||
@@ -247,7 +245,6 @@ func initAppServices(ctx context.Context, infra *Infrastructure, domainServices
|
||||
infra.repos.planRepo,
|
||||
infra.repos.pendingCollectionRepo,
|
||||
infra.repos.userActionLogRepo,
|
||||
infra.repos.rawMaterialRepo,
|
||||
infra.repos.medicationLogRepo,
|
||||
infra.repos.pigBatchRepo,
|
||||
infra.repos.pigBatchLogRepo,
|
||||
|
||||
@@ -167,9 +167,6 @@ func (ps *PostgresStorage) creatingHyperTable(ctx context.Context) error {
|
||||
{models.TaskExecutionLog{}, "created_at"},
|
||||
{models.PendingCollection{}, "created_at"},
|
||||
{models.UserActionLog{}, "time"},
|
||||
{models.RawMaterialPurchase{}, "purchase_date"},
|
||||
{models.RawMaterialStockLog{}, "happened_at"},
|
||||
{models.FeedUsageRecord{}, "recorded_at"},
|
||||
{models.MedicationLog{}, "happened_at"},
|
||||
{models.PigBatchLog{}, "happened_at"},
|
||||
{models.WeighingBatch{}, "weighing_time"},
|
||||
@@ -180,6 +177,7 @@ func (ps *PostgresStorage) creatingHyperTable(ctx context.Context) error {
|
||||
{models.PigSale{}, "sale_date"},
|
||||
{models.Notification{}, "alarm_timestamp"},
|
||||
{models.HistoricalAlarm{}, "trigger_time"},
|
||||
{models.RawMaterialStockLog{}, "happened_at"},
|
||||
}
|
||||
|
||||
for _, table := range tablesToConvert {
|
||||
@@ -210,9 +208,6 @@ func (ps *PostgresStorage) applyCompressionPolicies(ctx context.Context) error {
|
||||
{models.TaskExecutionLog{}, "task_id"},
|
||||
{models.PendingCollection{}, "device_id"},
|
||||
{models.UserActionLog{}, "user_id"},
|
||||
{models.RawMaterialPurchase{}, "raw_material_id"},
|
||||
{models.RawMaterialStockLog{}, "raw_material_id"},
|
||||
{models.FeedUsageRecord{}, "pen_id"},
|
||||
{models.MedicationLog{}, "pig_batch_id"},
|
||||
{models.PigBatchLog{}, "pig_batch_id"},
|
||||
{models.WeighingBatch{}, "pig_batch_id"},
|
||||
@@ -223,6 +218,7 @@ func (ps *PostgresStorage) applyCompressionPolicies(ctx context.Context) error {
|
||||
{models.PigSale{}, "pig_batch_id"},
|
||||
{models.Notification{}, "user_id"},
|
||||
{models.HistoricalAlarm{}, "source_id"},
|
||||
{models.RawMaterialStockLog{}, "raw_material_id"},
|
||||
}
|
||||
|
||||
for _, policy := range policies {
|
||||
@@ -258,6 +254,15 @@ func (ps *PostgresStorage) creatingIndex(ctx context.Context) error {
|
||||
// 使用 IF NOT EXISTS 保证幂等性
|
||||
// 如果索引已存在,此命令不会报错
|
||||
|
||||
// 为 raw_material_nutrients 表创建部分唯一索引,以兼容软删除
|
||||
logger.Debug("正在为 raw_material_nutrients 表创建部分唯一索引")
|
||||
partialIndexSQL := "CREATE UNIQUE INDEX IF NOT EXISTS idx_raw_material_nutrients_unique_when_not_deleted ON raw_material_nutrients (raw_material_id, nutrient_id) WHERE deleted_at IS NULL;"
|
||||
if err := ps.db.WithContext(storageCtx).Exec(partialIndexSQL).Error; err != nil {
|
||||
logger.Errorw("为 raw_material_nutrients 创建部分唯一索引失败", "error", err)
|
||||
return fmt.Errorf("为 raw_material_nutrients 创建部分唯一索引失败: %w", err)
|
||||
}
|
||||
logger.Debug("成功为 raw_material_nutrients 创建部分唯一索引 (或已存在)")
|
||||
|
||||
// 为 sensor_data 表的 data 字段创建 GIN 索引
|
||||
logger.Debug("正在为 sensor_data 表的 data 字段创建 GIN 索引")
|
||||
ginSensorDataIndexSQL := "CREATE INDEX IF NOT EXISTS idx_sensor_data_data_gin ON sensor_data USING GIN (data);"
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
/*
|
||||
饲料和饲喂相关的模型
|
||||
*/
|
||||
|
||||
// RawMaterial 代表饲料的原料。
|
||||
// 建议:所有重量单位统一存储 (例如, 全部使用 'g'),便于计算和避免转换错误。
|
||||
type RawMaterial struct {
|
||||
Model
|
||||
Name string `gorm:"size:100;unique;not null;comment:原料名称"`
|
||||
Description string `gorm:"size:255;comment:描述"`
|
||||
Quantity float32 `gorm:"not null;comment:库存总量, 单位: g"`
|
||||
}
|
||||
|
||||
func (RawMaterial) TableName() string {
|
||||
return "raw_materials"
|
||||
}
|
||||
|
||||
// RawMaterialPurchase 记录了原料的每一次采购。
|
||||
type RawMaterialPurchase struct {
|
||||
Model
|
||||
RawMaterialID uint32 `gorm:"not null;index;comment:关联的原料ID"`
|
||||
RawMaterial RawMaterial `gorm:"foreignKey:RawMaterialID"`
|
||||
Supplier string `gorm:"size:100;comment:供应商"`
|
||||
Amount float32 `gorm:"not null;comment:采购数量, 单位: g"`
|
||||
UnitPrice float32 `gorm:"comment:单价"`
|
||||
TotalPrice float32 `gorm:"comment:总价"`
|
||||
PurchaseDate time.Time `gorm:"primaryKey;comment:采购日期"`
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
func (RawMaterialPurchase) TableName() string {
|
||||
return "raw_material_purchases"
|
||||
}
|
||||
|
||||
// StockLogSourceType 定义了库存日志来源的类型
|
||||
type StockLogSourceType string
|
||||
|
||||
const (
|
||||
StockLogSourcePurchase StockLogSourceType = "采购入库"
|
||||
StockLogSourceFeeding StockLogSourceType = "饲喂出库"
|
||||
StockLogSourceDeteriorate StockLogSourceType = "变质出库"
|
||||
StockLogSourceSale StockLogSourceType = "售卖出库"
|
||||
StockLogSourceMiscellaneous StockLogSourceType = "杂用领取"
|
||||
StockLogSourceManual StockLogSourceType = "手动盘点"
|
||||
)
|
||||
|
||||
// RawMaterialStockLog 记录了原料库存的所有变动,提供了完整的追溯链。
|
||||
type RawMaterialStockLog struct {
|
||||
Model
|
||||
RawMaterialID uint32 `gorm:"not null;index;comment:关联的原料ID"`
|
||||
ChangeAmount float32 `gorm:"not null;comment:变动数量, 正数为入库, 负数为出库"`
|
||||
SourceType StockLogSourceType `gorm:"size:50;not null;index;comment:库存变动来源类型"`
|
||||
SourceID uint32 `gorm:"not null;index;comment:来源记录的ID (如 RawMaterialPurchase.ID 或 FeedUsageRecord.ID)"`
|
||||
HappenedAt time.Time `gorm:"primaryKey;comment:业务发生时间"`
|
||||
Remarks string `gorm:"comment:备注, 如主动领取的理由等"`
|
||||
}
|
||||
|
||||
func (RawMaterialStockLog) TableName() string {
|
||||
return "raw_material_stock_logs"
|
||||
}
|
||||
|
||||
// FeedFormula 代表饲料配方。
|
||||
// 对于没有配方的外购饲料,可以将其视为一种特殊的 RawMaterial, 并为其创建一个仅包含它自己的 FeedFormula。
|
||||
type FeedFormula struct {
|
||||
Model
|
||||
Name string `gorm:"size:100;unique;not null;comment:配方名称"`
|
||||
Description string `gorm:"size:255;comment:描述"`
|
||||
Components []FeedFormulaComponent `gorm:"foreignKey:FeedFormulaID"`
|
||||
}
|
||||
|
||||
func (FeedFormula) TableName() string {
|
||||
return "feed_formulas"
|
||||
}
|
||||
|
||||
// FeedFormulaComponent 代表配方中的一种原料及其占比。
|
||||
type FeedFormulaComponent struct {
|
||||
Model
|
||||
FeedFormulaID uint32 `gorm:"not null;index;comment:外键到 FeedFormula"`
|
||||
RawMaterialID uint32 `gorm:"not null;index;comment:外键到 RawMaterial"`
|
||||
RawMaterial RawMaterial `gorm:"foreignKey:RawMaterialID"`
|
||||
Percentage float32 `gorm:"not null;comment:该原料在配方中的百分比 (0-1.0)"`
|
||||
}
|
||||
|
||||
func (FeedFormulaComponent) TableName() string {
|
||||
return "feed_formula_components"
|
||||
}
|
||||
|
||||
// FeedUsageRecord 代表饲料使用记录。
|
||||
// 应用层逻辑:当一条使用记录被创建时,应根据其使用的 FeedFormula,
|
||||
// 计算出每种 RawMaterial 的消耗量,并在 RawMaterialStockLog 中创建对应的出库记录。
|
||||
type FeedUsageRecord struct {
|
||||
Model
|
||||
PenID uint32 `gorm:"not null;index;comment:关联的猪栏ID"`
|
||||
Pen Pen `gorm:"foreignKey:PenID"`
|
||||
FeedFormulaID uint32 `gorm:"not null;index;comment:使用的饲料配方ID"`
|
||||
FeedFormula FeedFormula `gorm:"foreignKey:FeedFormulaID"`
|
||||
Amount float32 `gorm:"not null;comment:使用数量, 单位: g"`
|
||||
RecordedAt time.Time `gorm:"primaryKey;comment:记录时间"`
|
||||
OperatorID uint32 `gorm:"not null;comment:操作员"`
|
||||
Remarks string `gorm:"comment:备注, 如 '例行喂料, 弱猪补料' 等"`
|
||||
}
|
||||
|
||||
func (FeedUsageRecord) TableName() string {
|
||||
return "feed_usage_records"
|
||||
}
|
||||
@@ -63,11 +63,9 @@ func GetAllModels() []interface{} {
|
||||
|
||||
// Feed Models
|
||||
&RawMaterial{},
|
||||
&RawMaterialPurchase{},
|
||||
&Nutrient{},
|
||||
&RawMaterialNutrient{},
|
||||
&RawMaterialStockLog{},
|
||||
&FeedFormula{},
|
||||
&FeedFormulaComponent{},
|
||||
&FeedUsageRecord{},
|
||||
|
||||
// Medication Models
|
||||
&Medication{},
|
||||
|
||||
92
internal/infra/models/raw_material.go
Normal file
92
internal/infra/models/raw_material.go
Normal file
@@ -0,0 +1,92 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// StockLogSourceType 定义了库存日志来源的类型
|
||||
type StockLogSourceType string
|
||||
|
||||
const (
|
||||
StockLogSourcePurchase StockLogSourceType = "采购入库"
|
||||
StockLogSourceFeeding StockLogSourceType = "饲喂出库"
|
||||
StockLogSourceDeteriorate StockLogSourceType = "变质出库"
|
||||
StockLogSourceSale StockLogSourceType = "售卖出库"
|
||||
StockLogSourceMiscellaneous StockLogSourceType = "杂用领取"
|
||||
StockLogSourceManual StockLogSourceType = "手动盘点"
|
||||
StockLogSourceFermentStart StockLogSourceType = "发酵出库" // 原料投入发酵,从库存中扣除
|
||||
StockLogSourceFermentEnd StockLogSourceType = "发酵入库" // 发酵料产出,作为新原料计入库存
|
||||
)
|
||||
|
||||
// NutrientType 定义了营养素的分类,用于配方优化和成本控制。
|
||||
type NutrientType string
|
||||
|
||||
const (
|
||||
PositiveNutrient NutrientType = "正面营养" // 希望在配方中最大化的营养素,如蛋白质、能量
|
||||
NegativeNutrient NutrientType = "负面营养" // 需要控制上限的营养素,如粗纤维、霉菌毒素
|
||||
)
|
||||
|
||||
// RawMaterial 代表一种原料的静态定义,是系统中的原料字典。
|
||||
type RawMaterial struct {
|
||||
Model
|
||||
Name string `gorm:"size:100;unique;not null;comment:原料名称"`
|
||||
Description string `gorm:"size:255;comment:描述"`
|
||||
// Quantity 是当前库存的快照值,用于提供高性能的库存查询。
|
||||
// 注意:此字段的值必须在数据库事务中与 RawMaterialStockLog 同步更新,以保证数据一致性。
|
||||
Quantity float32 `gorm:"not null;default:0;comment:当前库存快照, 单位: g"`
|
||||
}
|
||||
|
||||
func (RawMaterial) TableName() string {
|
||||
return "raw_materials"
|
||||
}
|
||||
|
||||
// Nutrient 代表一种营养素的静态定义,是系统中的营养素字典。
|
||||
// 注意:本系统强制统一营养单位,不再单独设置Unit字段。
|
||||
// 约定:宏量营养素(粗蛋白等)单位为百分比(%),微量元素(氨基酸等)单位为毫克/千克(mg/kg)。
|
||||
type Nutrient struct {
|
||||
Model
|
||||
Name string `gorm:"size:100;unique;not null;comment:营养素名称"`
|
||||
Type NutrientType `gorm:"size:50;not null;comment:营养素类型 (正面营养/负面营养)"`
|
||||
Description string `gorm:"size:255;comment:描述"`
|
||||
}
|
||||
|
||||
func (Nutrient) TableName() string {
|
||||
return "nutrients"
|
||||
}
|
||||
|
||||
// RawMaterialNutrient 存储了特定原料的特定营养素的含量值。
|
||||
// 这是连接原料和营养素的“营养价值表”。
|
||||
// 注意:其唯一性由 postgres.go 中的部分唯一索引保证,以兼容软删除。
|
||||
type RawMaterialNutrient struct {
|
||||
Model
|
||||
RawMaterialID uint32 `gorm:"not null;comment:关联的原料ID"`
|
||||
RawMaterial RawMaterial `gorm:"foreignKey:RawMaterialID"`
|
||||
NutrientID uint32 `gorm:"not null;comment:关联的营养素ID"`
|
||||
Nutrient Nutrient `gorm:"foreignKey:NutrientID"`
|
||||
// Value 存储营养价值含量。单位遵循 Nutrient 表中定义的系统级约定。
|
||||
Value float32 `gorm:"not null;comment:营养价值含量"`
|
||||
}
|
||||
|
||||
func (RawMaterialNutrient) TableName() string {
|
||||
return "raw_material_nutrients"
|
||||
}
|
||||
|
||||
// RawMaterialStockLog 记录了原料库存的所有变动,提供了完整的追溯链。
|
||||
// 它是保证数据一致性和可审计性的核心。
|
||||
type RawMaterialStockLog struct {
|
||||
Model
|
||||
RawMaterialID uint32 `gorm:"not null;index;comment:关联的原料ID"`
|
||||
RawMaterial RawMaterial `gorm:"foreignKey:RawMaterialID"`
|
||||
ChangeAmount float32 `gorm:"not null;comment:变动数量, 正数为入库, 负数为出库, 单位: g"`
|
||||
// SourceType 告知 SourceID 关联的是哪种类型的业务单据。
|
||||
SourceType StockLogSourceType `gorm:"size:50;not null;index;comment:库存变动来源类型"`
|
||||
// SourceID 是一个多态外键,关联到触发此次变动的业务单据ID (如采购单ID)。
|
||||
// 对于无单据的业务(如手动盘点),此字段可为NULL。
|
||||
SourceID *uint32 `gorm:"index;comment:来源业务单据的ID"`
|
||||
HappenedAt time.Time `gorm:"primaryKey;comment:业务发生时间"`
|
||||
Remarks string `gorm:"comment:备注"`
|
||||
}
|
||||
|
||||
func (RawMaterialStockLog) TableName() string {
|
||||
return "raw_material_stock_logs"
|
||||
}
|
||||
@@ -1,187 +0,0 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// RawMaterialPurchaseListOptions 定义了查询原料采购记录时的可选参数
|
||||
type RawMaterialPurchaseListOptions struct {
|
||||
RawMaterialID *uint32
|
||||
Supplier *string
|
||||
StartTime *time.Time // 基于 purchase_date 字段
|
||||
EndTime *time.Time // 基于 purchase_date 字段
|
||||
OrderBy string // 例如 "purchase_date asc"
|
||||
}
|
||||
|
||||
// RawMaterialStockLogListOptions 定义了查询原料库存日志时的可选参数
|
||||
type RawMaterialStockLogListOptions struct {
|
||||
RawMaterialID *uint32
|
||||
SourceType *models.StockLogSourceType
|
||||
SourceID *uint32
|
||||
StartTime *time.Time // 基于 happened_at 字段
|
||||
EndTime *time.Time // 基于 happened_at 字段
|
||||
OrderBy string // 例如 "happened_at asc"
|
||||
}
|
||||
|
||||
// FeedUsageRecordListOptions 定义了查询饲料使用记录时的可选参数
|
||||
type FeedUsageRecordListOptions struct {
|
||||
PenID *uint32
|
||||
FeedFormulaID *uint32
|
||||
OperatorID *uint32
|
||||
StartTime *time.Time // 基于 recorded_at 字段
|
||||
EndTime *time.Time // 基于 recorded_at 字段
|
||||
OrderBy string // 例如 "recorded_at asc"
|
||||
}
|
||||
|
||||
// RawMaterialRepository 定义了与原料相关的数据库操作接口
|
||||
type RawMaterialRepository interface {
|
||||
ListRawMaterialPurchases(ctx context.Context, opts RawMaterialPurchaseListOptions, page, pageSize int) ([]models.RawMaterialPurchase, int64, error)
|
||||
ListRawMaterialStockLogs(ctx context.Context, opts RawMaterialStockLogListOptions, page, pageSize int) ([]models.RawMaterialStockLog, int64, error)
|
||||
ListFeedUsageRecords(ctx context.Context, opts FeedUsageRecordListOptions, page, pageSize int) ([]models.FeedUsageRecord, int64, error)
|
||||
}
|
||||
|
||||
// gormRawMaterialRepository 是 RawMaterialRepository 的 GORM 实现
|
||||
type gormRawMaterialRepository struct {
|
||||
ctx context.Context
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
// NewGormRawMaterialRepository 创建一个新的 RawMaterialRepository GORM 实现实例
|
||||
func NewGormRawMaterialRepository(ctx context.Context, db *gorm.DB) RawMaterialRepository {
|
||||
return &gormRawMaterialRepository{ctx: ctx, db: db}
|
||||
}
|
||||
|
||||
// ListRawMaterialPurchases 实现了分页和过滤查询原料采购记录的功能
|
||||
func (r *gormRawMaterialRepository) ListRawMaterialPurchases(ctx context.Context, opts RawMaterialPurchaseListOptions, page, pageSize int) ([]models.RawMaterialPurchase, int64, error) {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "ListRawMaterialPurchases")
|
||||
if page <= 0 || pageSize <= 0 {
|
||||
return nil, 0, ErrInvalidPagination
|
||||
}
|
||||
|
||||
var results []models.RawMaterialPurchase
|
||||
var total int64
|
||||
|
||||
query := r.db.WithContext(repoCtx).Model(&models.RawMaterialPurchase{})
|
||||
|
||||
if opts.RawMaterialID != nil {
|
||||
query = query.Where("raw_material_id = ?", *opts.RawMaterialID)
|
||||
}
|
||||
if opts.Supplier != nil {
|
||||
query = query.Where("supplier LIKE ?", "%"+*opts.Supplier+"%")
|
||||
}
|
||||
if opts.StartTime != nil {
|
||||
query = query.Where("purchase_date >= ?", *opts.StartTime)
|
||||
}
|
||||
if opts.EndTime != nil {
|
||||
query = query.Where("purchase_date <= ?", *opts.EndTime)
|
||||
}
|
||||
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
orderBy := "purchase_date DESC"
|
||||
if opts.OrderBy != "" {
|
||||
orderBy = opts.OrderBy
|
||||
}
|
||||
query = query.Order(orderBy).Preload("RawMaterial")
|
||||
|
||||
offset := (page - 1) * pageSize
|
||||
err := query.Limit(pageSize).Offset(offset).Find(&results).Error
|
||||
|
||||
return results, total, err
|
||||
}
|
||||
|
||||
// ListRawMaterialStockLogs 实现了分页和过滤查询原料库存日志的功能
|
||||
func (r *gormRawMaterialRepository) ListRawMaterialStockLogs(ctx context.Context, opts RawMaterialStockLogListOptions, page, pageSize int) ([]models.RawMaterialStockLog, int64, error) {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "ListRawMaterialStockLogs")
|
||||
if page <= 0 || pageSize <= 0 {
|
||||
return nil, 0, ErrInvalidPagination
|
||||
}
|
||||
|
||||
var results []models.RawMaterialStockLog
|
||||
var total int64
|
||||
|
||||
query := r.db.WithContext(repoCtx).Model(&models.RawMaterialStockLog{})
|
||||
|
||||
if opts.RawMaterialID != nil {
|
||||
query = query.Where("raw_material_id = ?", *opts.RawMaterialID)
|
||||
}
|
||||
if opts.SourceType != nil {
|
||||
query = query.Where("source_type = ?", *opts.SourceType)
|
||||
}
|
||||
if opts.SourceID != nil {
|
||||
query = query.Where("source_id = ?", *opts.SourceID)
|
||||
}
|
||||
if opts.StartTime != nil {
|
||||
query = query.Where("happened_at >= ?", *opts.StartTime)
|
||||
}
|
||||
if opts.EndTime != nil {
|
||||
query = query.Where("happened_at <= ?", *opts.EndTime)
|
||||
}
|
||||
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
orderBy := "happened_at DESC"
|
||||
if opts.OrderBy != "" {
|
||||
orderBy = opts.OrderBy
|
||||
}
|
||||
query = query.Order(orderBy)
|
||||
|
||||
offset := (page - 1) * pageSize
|
||||
err := query.Limit(pageSize).Offset(offset).Find(&results).Error
|
||||
|
||||
return results, total, err
|
||||
}
|
||||
|
||||
// ListFeedUsageRecords 实现了分页和过滤查询饲料使用记录的功能
|
||||
func (r *gormRawMaterialRepository) ListFeedUsageRecords(ctx context.Context, opts FeedUsageRecordListOptions, page, pageSize int) ([]models.FeedUsageRecord, int64, error) {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "ListFeedUsageRecords")
|
||||
if page <= 0 || pageSize <= 0 {
|
||||
return nil, 0, ErrInvalidPagination
|
||||
}
|
||||
|
||||
var results []models.FeedUsageRecord
|
||||
var total int64
|
||||
|
||||
query := r.db.WithContext(repoCtx).Model(&models.FeedUsageRecord{})
|
||||
|
||||
if opts.PenID != nil {
|
||||
query = query.Where("pen_id = ?", *opts.PenID)
|
||||
}
|
||||
if opts.FeedFormulaID != nil {
|
||||
query = query.Where("feed_formula_id = ?", *opts.FeedFormulaID)
|
||||
}
|
||||
if opts.OperatorID != nil {
|
||||
query = query.Where("operator_id = ?", *opts.OperatorID)
|
||||
}
|
||||
if opts.StartTime != nil {
|
||||
query = query.Where("recorded_at >= ?", *opts.StartTime)
|
||||
}
|
||||
if opts.EndTime != nil {
|
||||
query = query.Where("recorded_at <= ?", *opts.EndTime)
|
||||
}
|
||||
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
orderBy := "recorded_at DESC"
|
||||
if opts.OrderBy != "" {
|
||||
orderBy = opts.OrderBy
|
||||
}
|
||||
query = query.Order(orderBy).Preload("Pen").Preload("FeedFormula")
|
||||
|
||||
offset := (page - 1) * pageSize
|
||||
err := query.Limit(pageSize).Offset(offset).Find(&results).Error
|
||||
|
||||
return results, total, err
|
||||
}
|
||||
Reference in New Issue
Block a user