实现从json读取猪营养需求并写入数据库

This commit is contained in:
2025-11-20 22:55:18 +08:00
parent c4ab53db12
commit aa13239e89
5 changed files with 1254 additions and 34 deletions

View File

@@ -1864,7 +1864,7 @@
"氢氰酸 (mg/kg)": "木薯、苦杏仁等原料中潜在剧毒物质阻断细胞呼吸极微量即可引起猪中毒死亡。构树原料标0为已脱毒处理使用前必须确认氢氰酸含量合格。", "氢氰酸 (mg/kg)": "木薯、苦杏仁等原料中潜在剧毒物质阻断细胞呼吸极微量即可引起猪中毒死亡。构树原料标0为已脱毒处理使用前必须确认氢氰酸含量合格。",
"总黄酮 (mg/kg)": "构树等植物次生代谢物,具有抗氧化、抗菌、改善血管功能的作用,对母猪繁殖性能和仔猪抗应激有一定正面作用,但过量也可能影响适口性。", "总黄酮 (mg/kg)": "构树等植物次生代谢物,具有抗氧化、抗菌、改善血管功能的作用,对母猪繁殖性能和仔猪抗应激有一定正面作用,但过量也可能影响适口性。",
"生物碱 (mg/kg)": "构树等原料中潜在有害物质,高量会引起猪神经症状、食欲下降甚至中毒,使用时需严格控制比例。", "生物碱 (mg/kg)": "构树等原料中潜在有害物质,高量会引起猪神经症状、食欲下降甚至中毒,使用时需严格控制比例。",
"沙门氏菌": "进口鱼粉卫生指标必须为0即阴性。一旦检出阳性整批原料禁止用于猪饲料否则极易引发仔猪副伤寒和全身感染。", "沙门氏菌 (mg/kg)": "进口鱼粉卫生指标必须为0即阴性。一旦检出阳性整批原料禁止用于猪饲料否则极易引发仔猪副伤寒和全身感染。",
"总棉酚 (mg/kg)": "棉粕中主要毒素,包括游离棉酚和结合棉酚。高量引起公猪精子畸形、母猪流产、生长猪肝肾损伤。生长育肥猪建议总棉酚<300mg/kg种猪<100mg/kg。", "总棉酚 (mg/kg)": "棉粕中主要毒素,包括游离棉酚和结合棉酚。高量引起公猪精子畸形、母猪流产、生长猪肝肾损伤。生长育肥猪建议总棉酚<300mg/kg种猪<100mg/kg。",
"环丙烯酸 (mg/kg)": "棉粕中另一种毒素,与棉酚协同作用,破坏赖氨酸利用率,严重影响蛋白质沉积。优质脱酚棉粕应<500mg/kg。", "环丙烯酸 (mg/kg)": "棉粕中另一种毒素,与棉酚协同作用,破坏赖氨酸利用率,严重影响蛋白质沉积。优质脱酚棉粕应<500mg/kg。",
"硫酸盐 (mg/kg)": "玉米DDGS发酵副产物高硫酸盐>8000mg/kg常见易导致猪脑软化症硫中毒生长猪日粮硫酸盐建议不超过4000mg/kg。", "硫酸盐 (mg/kg)": "玉米DDGS发酵副产物高硫酸盐>8000mg/kg常见易导致猪脑软化症硫中毒生长猪日粮硫酸盐建议不超过4000mg/kg。",

View File

@@ -0,0 +1,914 @@
{
"type": "pig_nutrient_requirements",
"data": {
"杜长大 (DLY)": {
"保育期": {
"可消化赖氨酸 (SID %)": {
"min_requirement": 0.012,
"max_requirement": 0.015
},
"蛋+胱氨酸 (%)": {
"min_requirement": 0.0072,
"max_requirement": 0.0105
},
"可消化苏氨酸 (SID %)": {
"min_requirement": 0.0078,
"max_requirement": 0.0108
},
"可消化色氨酸 (SID %)": {
"min_requirement": 0.0022,
"max_requirement": 0.0030
},
"粗蛋白 (%)": {
"min_requirement": 0.18,
"max_requirement": 0.22
},
"粗脂肪 (%)": {
"min_requirement": 0.03,
"max_requirement": 0.06
},
"粗纤维 (%)": {
"min_requirement": 0.02,
"max_requirement": 0.06
},
"钙 (%)": {
"min_requirement": 0.009,
"max_requirement": 0.012
},
"总磷 (%)": {
"min_requirement": 0.006,
"max_requirement": 0.008
},
"有效磷 (%)": {
"min_requirement": 0.002,
"max_requirement": 0.0045
},
"代谢能 (kcal/kg)": {
"min_requirement": 3226.5,
"max_requirement": 3585.0
},
"钠 (%)": {
"min_requirement": 0.0015,
"max_requirement": 0.0025
},
"氯 (%)": {
"min_requirement": 0.0025,
"max_requirement": 0.0045
},
"黄曲霉毒素B1 (μg/kg)": {
"max_requirement": 10
},
"呕吐毒素DON (μg/kg)": {
"max_requirement": 1
},
"玉米赤霉烯酮ZEN (μg/kg)": {
"max_requirement": 0.15
}
},
"育肥前期": {
"可消化赖氨酸 (SID %)": {
"min_requirement": 0.0094,
"max_requirement": 0.0110
},
"蛋+胱氨酸 (%)": {
"min_requirement": 0.0055,
"max_requirement": 0.0073
},
"可消化苏氨酸 (SID %)": {
"min_requirement": 0.0058,
"max_requirement": 0.0077
},
"可消化色氨酸 (SID %)": {
"min_requirement": 0.0016,
"max_requirement": 0.0022
},
"粗蛋白 (%)": {
"min_requirement": 0.16,
"max_requirement": 0.18
},
"粗脂肪 (%)": {
"min_requirement": 0.03,
"max_requirement": 0.06
},
"粗纤维 (%)": {
"min_requirement": 0.02,
"max_requirement": 0.06
},
"钙 (%)": {
"min_requirement": 0.007,
"max_requirement": 0.009
},
"总磷 (%)": {
"min_requirement": 0.005,
"max_requirement": 0.007
},
"有效磷 (%)": {
"min_requirement": 0.002,
"max_requirement": 0.0040
},
"代谢能 (kcal/kg)": {
"min_requirement": 3107.0,
"max_requirement": 3346.0
},
"钠 (%)": {
"min_requirement": 0.0015,
"max_requirement": 0.0025
},
"氯 (%)": {
"min_requirement": 0.0025,
"max_requirement": 0.0045
},
"黄曲霉毒素B1 (μg/kg)": {
"max_requirement": 10
},
"呕吐毒素DON (μg/kg)": {
"max_requirement": 1
},
"玉米赤霉烯酮ZEN (μg/kg)": {
"max_requirement": 0.15
}
},
"育肥后期": {
"可消化赖氨酸 (SID %)": {
"min_requirement": 0.0081,
"max_requirement": 0.0090
},
"蛋+胱氨酸 (%)": {
"min_requirement": 0.0045,
"max_requirement": 0.0058
},
"可消化苏氨酸 (SID %)": {
"min_requirement": 0.0048,
"max_requirement": 0.0061
},
"可消化色氨酸 (SID %)": {
"min_requirement": 0.0013,
"max_requirement": 0.0018
},
"粗蛋白 (%)": {
"min_requirement": 0.14,
"max_requirement": 0.16
},
"粗脂肪 (%)": {
"min_requirement": 0.03,
"max_requirement": 0.06
},
"粗纤维 (%)": {
"min_requirement": 0.02,
"max_requirement": 0.06
},
"钙 (%)": {
"min_requirement": 0.006,
"max_requirement": 0.008
},
"总磷 (%)": {
"min_requirement": 0.0045,
"max_requirement": 0.006
},
"有效磷 (%)": {
"min_requirement": 0.0018,
"max_requirement": 0.0035
},
"代谢能 (kcal/kg)": {
"min_requirement": 2987.5,
"max_requirement": 3226.5
},
"钠 (%)": {
"min_requirement": 0.0015,
"max_requirement": 0.0025
},
"氯 (%)": {
"min_requirement": 0.0025,
"max_requirement": 0.0045
},
"黄曲霉毒素B1 (μg/kg)": {
"max_requirement": 10
},
"呕吐毒素DON (μg/kg)": {
"max_requirement": 1
},
"玉米赤霉烯酮ZEN (μg/kg)": {
"max_requirement": 0.15
}
},
"二次育肥期": {
"可消化赖氨酸 (SID %)": {
"min_requirement": 0.0053,
"max_requirement": 0.0065
},
"蛋+胱氨酸 (%)": {
"min_requirement": 0.0030,
"max_requirement": 0.0041
},
"可消化苏氨酸 (SID %)": {
"min_requirement": 0.0031,
"max_requirement": 0.0043
},
"可消化色氨酸 (SID %)": {
"min_requirement": 0.0010,
"max_requirement": 0.0013
},
"粗蛋白 (%)": {
"min_requirement": 0.12,
"max_requirement": 0.14
},
"粗脂肪 (%)": {
"min_requirement": 0.03,
"max_requirement": 0.06
},
"粗纤维 (%)": {
"min_requirement": 0.02,
"max_requirement": 0.06
},
"钙 (%)": {
"min_requirement": 0.005,
"max_requirement": 0.007
},
"总磷 (%)": {
"min_requirement": 0.004,
"max_requirement": 0.0055
},
"有效磷 (%)": {
"min_requirement": 0.0015,
"max_requirement": 0.0030
},
"代谢能 (kcal/kg)": {
"min_requirement": 2868.0,
"max_requirement": 3107.0
},
"钠 (%)": {
"min_requirement": 0.0015,
"max_requirement": 0.0025
},
"氯 (%)": {
"min_requirement": 0.0025,
"max_requirement": 0.0045
},
"黄曲霉毒素B1 (μg/kg)": {
"max_requirement": 10
},
"呕吐毒素DON (μg/kg)": {
"max_requirement": 1
},
"玉米赤霉烯酮ZEN (μg/kg)": {
"max_requirement": 0.15
}
}
},
"杜大长 (DY L)": {
"保育期": {
"可消化赖氨酸 (SID %)": {
"min_requirement": 0.012,
"max_requirement": 0.015
},
"蛋+胱氨酸 (%)": {
"min_requirement": 0.0072,
"max_requirement": 0.0105
},
"可消化苏氨酸 (SID %)": {
"min_requirement": 0.0078,
"max_requirement": 0.0108
},
"可消化色氨酸 (SID %)": {
"min_requirement": 0.0022,
"max_requirement": 0.0030
},
"粗蛋白 (%)": {
"min_requirement": 0.18,
"max_requirement": 0.22
},
"粗脂肪 (%)": {
"min_requirement": 0.03,
"max_requirement": 0.06
},
"粗纤维 (%)": {
"min_requirement": 0.02,
"max_requirement": 0.06
},
"钙 (%)": {
"min_requirement": 0.009,
"max_requirement": 0.012
},
"总磷 (%)": {
"min_requirement": 0.006,
"max_requirement": 0.008
},
"有效磷 (%)": {
"min_requirement": 0.002,
"max_requirement": 0.0045
},
"代谢能 (kcal/kg)": {
"min_requirement": 3226.5,
"max_requirement": 3585.0
},
"钠 (%)": {
"min_requirement": 0.0015,
"max_requirement": 0.0025
},
"氯 (%)": {
"min_requirement": 0.0025,
"max_requirement": 0.0045
},
"黄曲霉毒素B1 (μg/kg)": {
"max_requirement": 10
},
"呕吐毒素DON (μg/kg)": {
"max_requirement": 1
},
"玉米赤霉烯酮ZEN (μg/kg)": {
"max_requirement": 0.15
}
},
"育肥前期": {
"可消化赖氨酸 (SID %)": {
"min_requirement": 0.0094,
"max_requirement": 0.0110
},
"蛋+胱氨酸 (%)": {
"min_requirement": 0.0055,
"max_requirement": 0.0073
},
"可消化苏氨酸 (SID %)": {
"min_requirement": 0.0058,
"max_requirement": 0.0077
},
"可消化色氨酸 (SID %)": {
"min_requirement": 0.0016,
"max_requirement": 0.0022
},
"粗蛋白 (%)": {
"min_requirement": 0.16,
"max_requirement": 0.18
},
"粗脂肪 (%)": {
"min_requirement": 0.03,
"max_requirement": 0.06
},
"粗纤维 (%)": {
"min_requirement": 0.02,
"max_requirement": 0.06
},
"钙 (%)": {
"min_requirement": 0.007,
"max_requirement": 0.009
},
"总磷 (%)": {
"min_requirement": 0.005,
"max_requirement": 0.007
},
"有效磷 (%)": {
"min_requirement": 0.002,
"max_requirement": 0.0040
},
"代谢能 (kcal/kg)": {
"min_requirement": 3107.0,
"max_requirement": 3346.0
},
"钠 (%)": {
"min_requirement": 0.0015,
"max_requirement": 0.0025
},
"氯 (%)": {
"min_requirement": 0.0025,
"max_requirement": 0.0045
},
"黄曲霉毒素B1 (μg/kg)": {
"max_requirement": 10
},
"呕吐毒素DON (μg/kg)": {
"max_requirement": 1
},
"玉米赤霉烯酮ZEN (μg/kg)": {
"max_requirement": 0.15
}
},
"育肥后期": {
"可消化赖氨酸 (SID %)": {
"min_requirement": 0.0081,
"max_requirement": 0.0090
},
"蛋+胱氨酸 (%)": {
"min_requirement": 0.0045,
"max_requirement": 0.0058
},
"可消化苏氨酸 (SID %)": {
"min_requirement": 0.0048,
"max_requirement": 0.0061
},
"可消化色氨酸 (SID %)": {
"min_requirement": 0.0013,
"max_requirement": 0.0018
},
"粗蛋白 (%)": {
"min_requirement": 0.14,
"max_requirement": 0.16
},
"粗脂肪 (%)": {
"min_requirement": 0.03,
"max_requirement": 0.06
},
"粗纤维 (%)": {
"min_requirement": 0.02,
"max_requirement": 0.06
},
"钙 (%)": {
"min_requirement": 0.006,
"max_requirement": 0.008
},
"总磷 (%)": {
"min_requirement": 0.0045,
"max_requirement": 0.006
},
"有效磷 (%)": {
"min_requirement": 0.0018,
"max_requirement": 0.0035
},
"代谢能 (kcal/kg)": {
"min_requirement": 2987.5,
"max_requirement": 3226.5
},
"钠 (%)": {
"min_requirement": 0.0015,
"max_requirement": 0.0025
},
"氯 (%)": {
"min_requirement": 0.0025,
"max_requirement": 0.0045
},
"黄曲霉毒素B1 (μg/kg)": {
"max_requirement": 10
},
"呕吐毒素DON (μg/kg)": {
"max_requirement": 1
},
"玉米赤霉烯酮ZEN (μg/kg)": {
"max_requirement": 0.15
}
},
"二次育肥期": {
"可消化赖氨酸 (SID %)": {
"min_requirement": 0.0053,
"max_requirement": 0.0065
},
"蛋+胱氨酸 (%)": {
"min_requirement": 0.0030,
"max_requirement": 0.0041
},
"可消化苏氨酸 (SID %)": {
"min_requirement": 0.0031,
"max_requirement": 0.0043
},
"可消化色氨酸 (SID %)": {
"min_requirement": 0.0010,
"max_requirement": 0.0013
},
"粗蛋白 (%)": {
"min_requirement": 0.12,
"max_requirement": 0.14
},
"粗脂肪 (%)": {
"min_requirement": 0.03,
"max_requirement": 0.06
},
"粗纤维 (%)": {
"min_requirement": 0.02,
"max_requirement": 0.06
},
"钙 (%)": {
"min_requirement": 0.005,
"max_requirement": 0.007
},
"总磷 (%)": {
"min_requirement": 0.004,
"max_requirement": 0.0055
},
"有效磷 (%)": {
"min_requirement": 0.0015,
"max_requirement": 0.0030
},
"代谢能 (kcal/kg)": {
"min_requirement": 2868.0,
"max_requirement": 3107.0
},
"钠 (%)": {
"min_requirement": 0.0015,
"max_requirement": 0.0025
},
"氯 (%)": {
"min_requirement": 0.0025,
"max_requirement": 0.0045
},
"黄曲霉毒素B1 (μg/kg)": {
"max_requirement": 10
},
"呕吐毒素DON (μg/kg)": {
"max_requirement": 1
},
"玉米赤霉烯酮ZEN (μg/kg)": {
"max_requirement": 0.15
}
}
},
"皮长大 (PL Y)": {
"保育期": {
"可消化赖氨酸 (SID %)": {
"min_requirement": 0.012,
"max_requirement": 0.015
},
"蛋+胱氨酸 (%)": {
"min_requirement": 0.0072,
"max_requirement": 0.0105
},
"可消化苏氨酸 (SID %)": {
"min_requirement": 0.0078,
"max_requirement": 0.0108
},
"可消化色氨酸 (SID %)": {
"min_requirement": 0.0022,
"max_requirement": 0.0030
},
"粗蛋白 (%)": {
"min_requirement": 0.18,
"max_requirement": 0.22
},
"粗脂肪 (%)": {
"min_requirement": 0.03,
"max_requirement": 0.06
},
"粗纤维 (%)": {
"min_requirement": 0.02,
"max_requirement": 0.06
},
"钙 (%)": {
"min_requirement": 0.009,
"max_requirement": 0.012
},
"总磷 (%)": {
"min_requirement": 0.006,
"max_requirement": 0.008
},
"有效磷 (%)": {
"min_requirement": 0.002,
"max_requirement": 0.0045
},
"代谢能 (kcal/kg)": {
"min_requirement": 3226.5,
"max_requirement": 3585.0
},
"钠 (%)": {
"min_requirement": 0.0015,
"max_requirement": 0.0025
},
"氯 (%)": {
"min_requirement": 0.0025,
"max_requirement": 0.0045
},
"黄曲霉毒素B1 (μg/kg)": {
"max_requirement": 10
},
"呕吐毒素DON (μg/kg)": {
"max_requirement": 1
},
"玉米赤霉烯酮ZEN (μg/kg)": {
"max_requirement": 0.15
}
},
"育肥前期": {
"可消化赖氨酸 (SID %)": {
"min_requirement": 0.0094,
"max_requirement": 0.0110
},
"蛋+胱氨酸 (%)": {
"min_requirement": 0.0055,
"max_requirement": 0.0073
},
"可消化苏氨酸 (SID %)": {
"min_requirement": 0.0058,
"max_requirement": 0.0077
},
"可消化色氨酸 (SID %)": {
"min_requirement": 0.0016,
"max_requirement": 0.0022
},
"粗蛋白 (%)": {
"min_requirement": 0.16,
"max_requirement": 0.18
},
"粗脂肪 (%)": {
"min_requirement": 0.03,
"max_requirement": 0.06
},
"粗纤维 (%)": {
"min_requirement": 0.02,
"max_requirement": 0.06
},
"钙 (%)": {
"min_requirement": 0.007,
"max_requirement": 0.009
},
"总磷 (%)": {
"min_requirement": 0.005,
"max_requirement": 0.007
},
"有效磷 (%)": {
"min_requirement": 0.002,
"max_requirement": 0.0040
},
"代谢能 (kcal/kg)": {
"min_requirement": 3107.0,
"max_requirement": 3346.0
},
"钠 (%)": {
"min_requirement": 0.0015,
"max_requirement": 0.0025
},
"氯 (%)": {
"min_requirement": 0.0025,
"max_requirement": 0.0045
},
"黄曲霉毒素B1 (μg/kg)": {
"max_requirement": 10
},
"呕吐毒素DON (μg/kg)": {
"max_requirement": 1
},
"玉米赤霉烯酮ZEN (μg/kg)": {
"max_requirement": 0.15
}
},
"育肥后期": {
"可消化赖氨酸 (SID %)": {
"min_requirement": 0.0081,
"max_requirement": 0.0090
},
"蛋+胱氨酸 (%)": {
"min_requirement": 0.0045,
"max_requirement": 0.0058
},
"可消化苏氨酸 (SID %)": {
"min_requirement": 0.0048,
"max_requirement": 0.0061
},
"可消化色氨酸 (SID %)": {
"min_requirement": 0.0013,
"max_requirement": 0.0018
},
"粗蛋白 (%)": {
"min_requirement": 0.14,
"max_requirement": 0.16
},
"粗脂肪 (%)": {
"min_requirement": 0.03,
"max_requirement": 0.06
},
"粗纤维 (%)": {
"min_requirement": 0.02,
"max_requirement": 0.06
},
"钙 (%)": {
"min_requirement": 0.006,
"max_requirement": 0.008
},
"总磷 (%)": {
"min_requirement": 0.0045,
"max_requirement": 0.006
},
"有效磷 (%)": {
"min_requirement": 0.0018,
"max_requirement": 0.0035
},
"代谢能 (kcal/kg)": {
"min_requirement": 2987.5,
"max_requirement": 3226.5
},
"钠 (%)": {
"min_requirement": 0.0015,
"max_requirement": 0.0025
},
"氯 (%)": {
"min_requirement": 0.0025,
"max_requirement": 0.0045
},
"黄曲霉毒素B1 (μg/kg)": {
"max_requirement": 10
},
"呕吐毒素DON (μg/kg)": {
"max_requirement": 1
},
"玉米赤霉烯酮ZEN (μg/kg)": {
"max_requirement": 0.15
}
},
"二次育肥期": {
"可消化赖氨酸 (SID %)": {
"min_requirement": 0.0053,
"max_requirement": 0.0065
},
"蛋+胱氨酸 (%)": {
"min_requirement": 0.0030,
"max_requirement": 0.0041
},
"可消化苏氨酸 (SID %)": {
"min_requirement": 0.0031,
"max_requirement": 0.0043
},
"可消化色氨酸 (SID %)": {
"min_requirement": 0.0010,
"max_requirement": 0.0013
},
"粗蛋白 (%)": {
"min_requirement": 0.12,
"max_requirement": 0.14
},
"粗脂肪 (%)": {
"min_requirement": 0.03,
"max_requirement": 0.06
},
"粗纤维 (%)": {
"min_requirement": 0.02,
"max_requirement": 0.06
},
"钙 (%)": {
"min_requirement": 0.005,
"max_requirement": 0.007
},
"总磷 (%)": {
"min_requirement": 0.004,
"max_requirement": 0.0055
},
"有效磷 (%)": {
"min_requirement": 0.0015,
"max_requirement": 0.0030
},
"代谢能 (kcal/kg)": {
"min_requirement": 2868.0,
"max_requirement": 3107.0
},
"钠 (%)": {
"min_requirement": 0.0015,
"max_requirement": 0.0025
},
"氯 (%)": {
"min_requirement": 0.0025,
"max_requirement": 0.0045
},
"黄曲霉毒素B1 (μg/kg)": {
"max_requirement": 10
},
"呕吐毒素DON (μg/kg)": {
"max_requirement": 1
},
"玉米赤霉烯酮ZEN (μg/kg)": {
"max_requirement": 0.15
}
}
}
},
"descriptions": {
"pig_breeds": {
"杜长大 (DLY)": {
"description": "杜长大是中国市场占有率最高的商品肉猪。通过利用杜洛克、长白、大约克三品种的杂种优势,实现高效生长和高瘦肉率。",
"parent_info": "终端父本:杜洛克 (D);二元母本:长白 (L) × 大约克 (Y)。",
"appearance_features": "全身白色,体型健壮、体躯较长,肌肉发达,背腰平直。",
"breed_advantages": "生长速度快、日增重极高、饲料转化率最优、瘦肉率稳定在60%以上、适应性良好、出栏时间最短。",
"breed_disadvantages": "抗应激能力中等,对疫病和环境变化相对敏感;无法作为种猪进行自繁。"
},
"杜大长 (DY L)": {
"description": "杜大长是另一种重要的外三元猪,与杜长大体系相似,但在母本的搭配上有所区别,同样追求高生长速度和高瘦肉率。",
"parent_info": "终端父本:杜洛克 (D);二元母本:大约克 (Y) × 长白 (L)。",
"appearance_features": "全身白色,体型比杜长大略微魁梧,肌肉丰满度高。",
"breed_advantages": "生长性能和瘦肉率与杜长大相当,同时遗传了大约克母本的良好体型和生长潜力,综合性能优秀。",
"breed_disadvantages": "与杜长大相似,无法留作种用,需要依赖稳定的种源体系;对饲养管理要求高。"
},
"皮长大 (PL Y)": {
"description": "皮长大是以皮特兰作为终端父本的杂交体系,专注于生产超高瘦肉率的商品肉猪。",
"parent_info": "终端父本:皮特兰 (P);二元母本:长白 (L) × 大约克 (Y)。",
"appearance_features": "多数为白色或带有黑色斑点,肌肉极其发达,后臀饱满,体型呈方形。",
"breed_advantages": "瘦肉率极高能达到65%以上),胴体丰满,背膘薄。",
"breed_disadvantages": "生长速度和日增重逊于杜长大应激敏感性极高易发生P.S.S.管理难度大肉质易出现PSE苍白、软、渗水现象影响口感和加工性能。"
}
},
"pig_age_stages": {
"保育期": "从断奶到转入生长舍。主要目标是适应固体饲料建立肠道菌群确保健康稳定过渡体重约5kg~30kg。",
"育肥前期": "小猪转入育肥舍后到体重达到约60kg的阶段。以骨骼和肌肉生长为主是高效增重期。",
"育肥后期": "体重从约60kg到达到出栏体重约110-120kg的阶段。脂肪沉积速度开始加快是出栏前的冲刺期。",
"二次育肥期": "指收购达到常规出栏体重约100-120kg的商品猪继续饲养至更大体重140-180kg+)的阶段。其存在主要受市场价格波动驱动,目的是提高单体出肉量。"
},
"pig_breed_age_stages": {
"杜长大 (DLY)": {
"保育期": {
"description": "遗传自杜洛克的生长优势在断奶后开始显现,需精细化管理以避免断奶应激和腹泻。",
"daily_feed_intake": 400.0,
"daily_gain_weight": 350.0,
"min_days": 21,
"max_days": 70,
"min_weight": 5000.0,
"max_weight": 30000.0
},
"育肥前期": {
"description": "生长速度和饲料转化率表现良好,是瘦肉沉积效率高的阶段。",
"daily_feed_intake": 1800.0,
"daily_gain_weight": 700.0,
"min_days": 71,
"max_days": 120,
"min_weight": 30000.0,
"max_weight": 60000.0
},
"育肥后期": {
"description": "继续实现较高日增重,脂肪沉积开始加快,管理目标为达到目标出栏体重并保持料肉比。",
"daily_feed_intake": 2800.0,
"daily_gain_weight": 800.0,
"min_days": 121,
"max_days": 180,
"min_weight": 60000.0,
"max_weight": 100000.0
},
"二次育肥期": {
"description": "增重效率下降,料肉比恶化,增重多为脂肪沉积,注意热应激与蹄部问题。",
"daily_feed_intake": 3500.0,
"daily_gain_weight": 600.0,
"min_days": 181,
"max_days": 240,
"min_weight": 100000.0,
"max_weight": 140000.0
}
},
"杜大长 (DY L)": {
"保育期": {
"description": "与杜长大相近,生长潜力强,管理重点为断奶适应与稳定采食。",
"daily_feed_intake": 400.0,
"daily_gain_weight": 330.0,
"min_days": 21,
"max_days": 70,
"min_weight": 5000.0,
"max_weight": 30000.0
},
"育肥前期": {
"description": "生长期增重与料肉比接近杜长大,肌肉发展迅速。",
"daily_feed_intake": 1750.0,
"daily_gain_weight": 680.0,
"min_days": 71,
"max_days": 120,
"min_weight": 30000.0,
"max_weight": 60000.0
},
"育肥后期": {
"description": "保持较高增重速度,脂肪沉积稍快于部分 DLY 群体,需配方微调以控制背膘。",
"daily_feed_intake": 2700.0,
"daily_gain_weight": 770.0,
"min_days": 121,
"max_days": 180,
"min_weight": 60000.0,
"max_weight": 100000.0
},
"二次育肥期": {
"description": "与杜长大相似,采食量高但增重多为脂肪,注意健康与福利管理。",
"daily_feed_intake": 3500.0,
"daily_gain_weight": 580.0,
"min_days": 181,
"max_days": 240,
"min_weight": 100000.0,
"max_weight": 140000.0
}
},
"皮长大 (PLY)": {
"保育期": {
"description": "个体应激敏感性可能更高,需要稳定环境与逐步换料以减少应激性下降重。",
"daily_feed_intake": 350.0,
"daily_gain_weight": 300.0,
"min_days": 21,
"max_days": 70,
"min_weight": 5000.0,
"max_weight": 30000.0
},
"育肥前期": {
"description": "增重速度一般,但瘦肉率高;需注意高应激个体的管理以避免肉质问题。",
"daily_feed_intake": 1600.0,
"daily_gain_weight": 600.0,
"min_days": 71,
"max_days": 120,
"min_weight": 30000.0,
"max_weight": 60000.0
},
"育肥后期": {
"description": "瘦肉率高且脂肪沉积较慢,但应激易导致肉质问题,育肥管理需谨慎。",
"daily_feed_intake": 2400.0,
"daily_gain_weight": 650.0,
"min_days": 121,
"max_days": 180,
"min_weight": 60000.0,
"max_weight": 100000.0
},
"二次育肥期": {
"description": "超重育肥带来的应激和死亡风险增加,通常不推荐长期二次育肥。",
"daily_feed_intake": 3200.0,
"daily_gain_weight": 450.0,
"min_days": 181,
"max_days": 240,
"min_weight": 100000.0,
"max_weight": 140000.0
}
}
}
}
}

View File

@@ -53,3 +53,4 @@ http://git.huangwc.com/pig/pig-farm-controller/issues/66
3. 定义配方领域, 实现营养元素的增删改查 3. 定义配方领域, 实现营养元素的增删改查
4. 实现原材料的增删改查和仓库层的原料库存记录表增查 4. 实现原材料的增删改查和仓库层的原料库存记录表增查
5. 定义猪的模型和营养需求模型 5. 定义猪的模型和营养需求模型
6. 实现从json读取猪营养需求并写入数据库

View File

@@ -26,60 +26,87 @@ type SeederFunc func(tx *gorm.DB, jsonData []byte) error
func SeedFromPreset(ctx context.Context, db *gorm.DB, presetDir string) error { func SeedFromPreset(ctx context.Context, db *gorm.DB, presetDir string) error {
logger := logs.TraceLogger(ctx, ctx, "SeedFromPreset") logger := logs.TraceLogger(ctx, ctx, "SeedFromPreset")
// 定义必须存在的预设数据类型 // 定义必须存在的预设数据类型及其处理顺序
requiredTypes := []string{"nutrient"} // 确保 "nutrient" 在 "pig_nutrient_requirements" 之前处理,因为后者依赖于前者。
processedTypes := make(map[string]bool) processingOrder := []string{"nutrient", "pig_nutrient_requirements"}
requiredTypes := make(map[string]bool)
for _, t := range processingOrder {
requiredTypes[t] = true
}
// 用于检测重复的 type processedTypes := make(map[string]bool)
typeToFileMap := make(map[string]string) typeToFileMap := make(map[string]string) // 用于检测重复的 type并存储每个 type 对应的文件路径
groupedFiles := make(map[string][][]byte) // 按 type 分组存储 jsonData
files, err := os.ReadDir(presetDir) files, err := os.ReadDir(presetDir)
if err != nil { if err != nil {
return fmt.Errorf("读取预设数据目录 '%s' 失败: %w", presetDir, err) return fmt.Errorf("读取预设数据目录 '%s' 失败: %w", presetDir, err)
} }
// 第一阶段:读取所有文件并按 type 分组
for _, file := range files {
if filepath.Ext(file.Name()) != ".json" {
continue
}
filePath := filepath.Join(presetDir, file.Name())
jsonData, err := os.ReadFile(filePath)
if err != nil {
return fmt.Errorf("读取文件 '%s' 失败: %w", filePath, err)
}
dataType := gjson.GetBytes(jsonData, "type")
if !dataType.Exists() {
logger.Warnf("警告: 文件 '%s' 中缺少 'type' 字段,已跳过", filePath)
continue
}
dataTypeStr := dataType.String()
// 检查是否存在重复的 type
if existingFile, found := typeToFileMap[dataTypeStr]; found {
return fmt.Errorf("预设数据校验失败: type '%s' 在文件 '%s' 和 '%s' 中重复定义", dataTypeStr, existingFile, filePath)
}
typeToFileMap[dataTypeStr] = filePath // 记录该 type 对应的文件路径
groupedFiles[dataTypeStr] = append(groupedFiles[dataTypeStr], jsonData)
}
// 第二阶段:按照预定义顺序处理分组后的数据
return db.Transaction(func(tx *gorm.DB) error { return db.Transaction(func(tx *gorm.DB) error {
for _, file := range files { for _, dataTypeStr := range processingOrder {
if filepath.Ext(file.Name()) != ".json" { jsonDatas, ok := groupedFiles[dataTypeStr]
continue if !ok {
// 如果是必需类型但没有找到文件,则报错
if requiredTypes[dataTypeStr] {
return fmt.Errorf("预设数据校验失败: 缺少必需的预设文件类型: '%s'", dataTypeStr)
}
continue // 非必需类型,跳过
} }
filePath := filepath.Join(presetDir, file.Name())
jsonData, err := os.ReadFile(filePath)
if err != nil {
return fmt.Errorf("读取文件 '%s' 失败: %w", filePath, err)
}
dataType := gjson.GetBytes(jsonData, "type")
if !dataType.Exists() {
logger.Warnf("警告: 文件 '%s' 中缺少 'type' 字段,已跳过", filePath)
continue
}
dataTypeStr := dataType.String()
if existingFile, found := typeToFileMap[dataTypeStr]; found {
return fmt.Errorf("预设数据校验失败: type '%s' 在文件 '%s' 和 '%s' 中重复定义", dataTypeStr, existingFile, filePath)
}
typeToFileMap[dataTypeStr] = filePath
var seederFunc SeederFunc var seederFunc SeederFunc
switch dataTypeStr { switch dataTypeStr {
case "nutrient": case "nutrient":
seederFunc = seedNutrients seederFunc = seedNutrients
case "pig_nutrient_requirements":
seederFunc = seedPigNutrientRequirements
default: default:
logger.Warnf("警告: 文件 '%s' 中存在未知的 type: '%s',已跳过", filePath, dataTypeStr) logger.Warnf("警告: 存在未知的 type: '%s',已跳过", dataTypeStr)
continue continue
} }
if err := seederFunc(tx, jsonData); err != nil { for _, jsonData := range jsonDatas {
return fmt.Errorf("处理文件 '%s' (type: %s) 时发生错误: %w", filePath, dataTypeStr, err) // 获取原始文件路径用于错误报告
originalFilePath := typeToFileMap[dataTypeStr]
if err := seederFunc(tx, jsonData); err != nil {
return fmt.Errorf("处理文件 (type: %s, path: %s) 时发生错误: %w", dataTypeStr, originalFilePath, err)
}
} }
processedTypes[dataTypeStr] = true processedTypes[dataTypeStr] = true
} }
// 校验所有必需的类型是否都已处理 // 校验所有必需的类型是否都已处理
var missingTypes []string var missingTypes []string
for _, reqType := range requiredTypes { for reqType := range requiredTypes {
if !processedTypes[reqType] { if !processedTypes[reqType] {
missingTypes = append(missingTypes, reqType) missingTypes = append(missingTypes, reqType)
} }
@@ -158,6 +185,280 @@ func seedNutrients(tx *gorm.DB, jsonData []byte) error {
return nil return nil
} }
// seedPigNutrientRequirements 先严格校验JSON源文件然后以“有则跳过”的模式播种数据。
func seedPigNutrientRequirements(tx *gorm.DB, jsonData []byte) error {
// 1. 严格校验JSON文件检查内部重复键
parsedData, err := validateAndParsePigNutrientRequirementJSON(jsonData)
if err != nil {
return fmt.Errorf("JSON源文件校验失败: %w", err)
}
// 2. 解析简介信息
descriptionsNode := gjson.GetBytes(jsonData, "descriptions")
pigBreedDescriptions := make(map[string]models.PigBreed)
pigAgeStageDescriptions := make(map[string]models.PigAgeStage)
pigTypeDescriptions := make(map[string]map[string]models.PigType)
if descriptionsNode.Exists() {
// 解析 pig_breeds 描述
descriptionsNode.Get("pig_breeds").ForEach(func(key, value gjson.Result) bool {
var pb models.PigBreed
pb.Name = key.String()
pb.Description = value.Get("description").String()
pb.ParentInfo = value.Get("parent_info").String()
pb.AppearanceFeatures = value.Get("appearance_features").String()
pb.BreedAdvantages = value.Get("breed_advantages").String()
pb.BreedDisadvantages = value.Get("breed_disadvantages").String()
pigBreedDescriptions[key.String()] = pb
return true
})
// 解析 pig_age_stages 描述
descriptionsNode.Get("pig_age_stages").ForEach(func(key, value gjson.Result) bool {
var pas models.PigAgeStage
pas.Name = key.String()
pas.Description = value.String()
pigAgeStageDescriptions[key.String()] = pas
return true
})
// 解析 pig_breed_age_stages (PigType) 描述
descriptionsNode.Get("pig_breed_age_stages").ForEach(func(breedKey, breedValue gjson.Result) bool {
if _, ok := pigTypeDescriptions[breedKey.String()]; !ok {
pigTypeDescriptions[breedKey.String()] = make(map[string]models.PigType)
}
breedValue.ForEach(func(ageStageKey, ageStageValue gjson.Result) bool {
var pt models.PigType
pt.Description = ageStageValue.Get("description").String()
pt.DailyFeedIntake = float32(ageStageValue.Get("daily_feed_intake").Float())
pt.DailyGainWeight = float32(ageStageValue.Get("daily_gain_weight").Float())
pt.MinDays = uint32(ageStageValue.Get("min_days").Uint())
pt.MaxDays = uint32(ageStageValue.Get("max_days").Uint())
pt.MinWeight = float32(ageStageValue.Get("min_weight").Float())
pt.MaxWeight = float32(ageStageValue.Get("max_weight").Float())
pigTypeDescriptions[breedKey.String()][ageStageKey.String()] = pt
return true
})
return true
})
}
// 3. 将通过校验的、干净的数据写入数据库
for breedName, ageStagesData := range parsedData {
var pigBreed models.PigBreed
// 查找或创建 PigBreed
pbDesc := pigBreedDescriptions[breedName]
err := tx.Where(models.PigBreed{Name: breedName}).
FirstOrCreate(&pigBreed, models.PigBreed{
Name: breedName,
Description: pbDesc.Description,
ParentInfo: pbDesc.ParentInfo,
AppearanceFeatures: pbDesc.AppearanceFeatures,
BreedAdvantages: pbDesc.BreedAdvantages,
BreedDisadvantages: pbDesc.BreedDisadvantages,
}).Error
if err != nil {
return fmt.Errorf("预设猪品种 '%s' 失败: %w", breedName, err)
}
for ageStageName, nutrientsData := range ageStagesData {
var pigAgeStage models.PigAgeStage
// 查找或创建 PigAgeStage
pasDesc := pigAgeStageDescriptions[ageStageName]
err := tx.Where(models.PigAgeStage{Name: ageStageName}).
FirstOrCreate(&pigAgeStage, models.PigAgeStage{
Name: ageStageName,
Description: pasDesc.Description,
}).Error
if err != nil {
return fmt.Errorf("预设猪年龄阶段 '%s' 失败: %w", ageStageName, err)
}
var pigType models.PigType
// 查找或创建 PigType
ptDesc := pigTypeDescriptions[breedName][ageStageName]
err = tx.Where(models.PigType{BreedID: pigBreed.ID, AgeStageID: pigAgeStage.ID}).
FirstOrCreate(&pigType, models.PigType{
BreedID: pigBreed.ID,
AgeStageID: pigAgeStage.ID,
Description: ptDesc.Description,
DailyFeedIntake: ptDesc.DailyFeedIntake,
DailyGainWeight: ptDesc.DailyGainWeight,
MinDays: ptDesc.MinDays,
MaxDays: ptDesc.MaxDays,
MinWeight: ptDesc.MinWeight,
MaxWeight: ptDesc.MaxWeight,
}).Error
if err != nil {
return fmt.Errorf("预设猪类型 '%s' - '%s' 失败: %w", breedName, ageStageName, err)
}
for nutrientName, requirement := range nutrientsData {
var nutrient models.Nutrient
// 查找或创建 Nutrient (这里假设 Nutrient 已经在 seedNutrients 中处理,但为了健壮性,再次 FirstOrCreate)
err := tx.Where(models.Nutrient{Name: nutrientName}).
FirstOrCreate(&nutrient, models.Nutrient{
Name: nutrientName,
// Description 字段在 nutrient seeder 中处理,这里不设置
}).Error
if err != nil {
return fmt.Errorf("预设营养素 '%s' 失败: %w", nutrientName, err)
}
linkData := models.PigNutrientRequirement{
PigTypeID: pigType.ID,
NutrientID: nutrient.ID,
MinRequirement: requirement.MinRequirement,
MaxRequirement: requirement.MaxRequirement,
}
// 使用 FirstOrCreate 确保关联的唯一性
if err := tx.Where(models.PigNutrientRequirement{
PigTypeID: pigType.ID,
NutrientID: nutrient.ID,
}).FirstOrCreate(&linkData, linkData).Error; err != nil {
return fmt.Errorf("为猪类型 '%s' - '%s' 和营养素 '%s' 创建营养需求失败: %w", breedName, ageStageName, nutrientName, err)
}
}
}
}
return nil
}
// validateAndParsePigNutrientRequirementJSON 严格校验并解析猪营养需求JSON文件
func validateAndParsePigNutrientRequirementJSON(jsonData []byte) (map[string]map[string]map[string]struct {
MinRequirement float32
MaxRequirement float32
}, error) {
dataNode := gjson.GetBytes(jsonData, "data")
if !dataNode.Exists() {
return nil, errors.New("JSON文件中缺少 'data' 字段")
}
if !dataNode.IsObject() {
return nil, errors.New("'data' 字段必须是一个JSON对象")
}
decoder := json.NewDecoder(bytes.NewReader([]byte(dataNode.Raw)))
decoder.UseNumber()
if t, err := decoder.Token(); err != nil || t != json.Delim('{') {
return nil, fmt.Errorf("'data' 字段解析起始符失败: %v", err)
}
result := make(map[string]map[string]map[string]struct {
MinRequirement float32
MaxRequirement float32
})
seenBreeds := make(map[string]bool)
for decoder.More() {
// 解析 PigBreed 名称
t, err := decoder.Token()
if err != nil {
return nil, fmt.Errorf("解析猪品种名称失败: %w", err)
}
breedName := t.(string)
if seenBreeds[breedName] {
return nil, fmt.Errorf("猪品种名称 '%s' 重复", breedName)
}
seenBreeds[breedName] = true
// 解析该品种的年龄阶段对象
if t, err := decoder.Token(); err != nil || t != json.Delim('{') {
return nil, fmt.Errorf("期望猪品种 '%s' 的值是一个JSON对象", breedName)
}
ageStages := make(map[string]map[string]struct {
MinRequirement float32
MaxRequirement float32
})
seenAgeStages := make(map[string]bool)
for decoder.More() {
// 解析 PigAgeStage 名称
t, err := decoder.Token()
if err != nil {
return nil, fmt.Errorf("在猪品种 '%s' 中解析年龄阶段名称失败: %w", breedName, err)
}
ageStageName := t.(string)
if seenAgeStages[ageStageName] {
return nil, fmt.Errorf("在猪品种 '%s' 中, 年龄阶段名称 '%s' 重复", breedName, ageStageName)
}
seenAgeStages[ageStageName] = true
// 解析该年龄阶段的营养成分对象
if t, err := decoder.Token(); err != nil || t != json.Delim('{') {
return nil, fmt.Errorf("期望年龄阶段 '%s' 的值是一个JSON对象", ageStageName)
}
nutrients := make(map[string]struct {
MinRequirement float32
MaxRequirement float32
})
seenNutrients := make(map[string]bool)
for decoder.More() {
// 解析 Nutrient 名称
t, err := decoder.Token()
if err != nil {
return nil, fmt.Errorf("在年龄阶段 '%s' 中解析营养素名称失败: %w", ageStageName, err)
}
nutrientName := t.(string)
if seenNutrients[nutrientName] {
return nil, fmt.Errorf("在年龄阶段 '%s' 中, 营养素名称 '%s' 重复", ageStageName, nutrientName)
}
seenNutrients[nutrientName] = true
// 解析 min_requirement 和 max_requirement 对象
if t, err := decoder.Token(); err != nil || t != json.Delim('{') {
return nil, fmt.Errorf("期望营养素 '%s' 的值是一个JSON对象", nutrientName)
}
var req struct {
MinRequirement float32
MaxRequirement float32
}
for decoder.More() {
t, err := decoder.Token()
if err != nil {
return nil, fmt.Errorf("解析营养素 '%s' 的需求键失败: %w", nutrientName, err)
}
key := t.(string)
t, err = decoder.Token()
if err != nil {
return nil, fmt.Errorf("解析营养素 '%s' 的需求值失败: %w", nutrientName, err)
}
if value, ok := t.(json.Number); ok {
f64, _ := value.Float64()
if key == "min_requirement" {
req.MinRequirement = float32(f64)
} else if key == "max_requirement" {
req.MaxRequirement = float32(f64)
} else {
return nil, fmt.Errorf("营养素 '%s' 中存在未知键 '%s'", nutrientName, key)
}
} else {
return nil, fmt.Errorf("期望营养素 '%s' 的 '%s' 值是数字, 但实际得到的类型是 %T, 值为 '%v'", nutrientName, key, t, t)
}
}
if t, err := decoder.Token(); err != nil || t != json.Delim('}') {
return nil, fmt.Errorf("解析营养素 '%s' 的值结束符 '}' 失败", nutrientName)
}
nutrients[nutrientName] = req
}
if t, err := decoder.Token(); err != nil || t != json.Delim('}') {
return nil, fmt.Errorf("解析年龄阶段 '%s' 的值结束符 '}' 失败", ageStageName)
}
ageStages[ageStageName] = nutrients
}
if t, err := decoder.Token(); err != nil || t != json.Delim('}') {
return nil, fmt.Errorf("解析猪品种 '%s' 的值结束符 '}' 失败", breedName)
}
result[breedName] = ageStages
}
return result, nil
}
// validateAndParseNutrientJSON 使用 json.Decoder 手动解析,以捕获重复的键。 // validateAndParseNutrientJSON 使用 json.Decoder 手动解析,以捕获重复的键。
func validateAndParseNutrientJSON(jsonData []byte) (map[string]map[string]float32, error) { func validateAndParseNutrientJSON(jsonData []byte) (map[string]map[string]float32, error) {
dataNode := gjson.GetBytes(jsonData, "data") dataNode := gjson.GetBytes(jsonData, "data")

View File

@@ -3,8 +3,12 @@ package models
// PigBreed 猪品种模型 // PigBreed 猪品种模型
type PigBreed struct { type PigBreed struct {
Model Model
Name string `gorm:"size:50;not null;comment:品种名称"` Name string `gorm:"size:50;not null;comment:品种名称"`
Description string `gorm:"size:255;comment:品种描述"` Description string `gorm:"type:text" json:"description"` // 保留描述字段
ParentInfo string `gorm:"type:text" json:"parent_info"` // 父母信息
AppearanceFeatures string `gorm:"type:text" json:"appearance_features"` // 外貌特征
BreedAdvantages string `gorm:"type:text" json:"breed_advantages"` // 品种优点
BreedDisadvantages string `gorm:"type:text" json:"breed_disadvantages"` // 品种缺点
} }
func (PigBreed) TableName() string { func (PigBreed) TableName() string {