NutritionDataUtil.java 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. package org.dromara.web.service;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import java.util.regex.Matcher;
  5. import java.util.regex.Pattern;
  6. /**
  7. * 营养代谢基础值查询工具类
  8. * 支持通过营养素名称、性别和年龄查询推荐值
  9. */
  10. public class NutritionDataUtil {
  11. // 营养素数据映射表
  12. private static final Map<String, Map<String, String>> NUTRIENT_MAP = new HashMap<>();
  13. // 年龄范围映射表
  14. private static final Map<String, AgeRange> AGE_RANGE_MAP = new HashMap<>();
  15. // 年龄范围类
  16. private static class AgeRange {
  17. final int min;
  18. final int max;
  19. final String groupName;
  20. AgeRange(int min, int max, String groupName) {
  21. this.min = min;
  22. this.max = max;
  23. this.groupName = groupName;
  24. }
  25. boolean contains(int age) {
  26. return age >= min && age <= max;
  27. }
  28. }
  29. static {
  30. // 初始化年龄范围映射
  31. initializeAgeRanges();
  32. // 初始化营养素数据
  33. initializeNutrientData();
  34. }
  35. // 初始化年龄范围
  36. private static void initializeAgeRanges() {
  37. AGE_RANGE_MAP.put("0-6月", new AgeRange(0, 0, "0-6月"));
  38. AGE_RANGE_MAP.put("7-12月", new AgeRange(0, 1, "7-12月"));
  39. AGE_RANGE_MAP.put("1-3岁", new AgeRange(1, 3, "1-3岁"));
  40. AGE_RANGE_MAP.put("4-6岁", new AgeRange(4, 6, "4-6岁"));
  41. AGE_RANGE_MAP.put("7-10岁", new AgeRange(7, 10, "7-10岁"));
  42. AGE_RANGE_MAP.put("11-13岁", new AgeRange(11, 13, "11-13岁"));
  43. AGE_RANGE_MAP.put("14-17岁", new AgeRange(14, 17, "14-17岁"));
  44. AGE_RANGE_MAP.put("18-49岁", new AgeRange(18, 49, "18-49岁"));
  45. AGE_RANGE_MAP.put("50-64岁", new AgeRange(50, 64, "50-64岁"));
  46. AGE_RANGE_MAP.put("≥65岁", new AgeRange(65, Integer.MAX_VALUE, "≥65岁"));
  47. AGE_RANGE_MAP.put("孕妇", new AgeRange(-1, -1, "孕妇(中期/晚期)"));
  48. AGE_RANGE_MAP.put("乳母", new AgeRange(-1, -1, "乳母"));
  49. }
  50. // 初始化营养素数据
  51. private static void initializeNutrientData() {
  52. // 常量元素
  53. addNutrientData("钙", "mg", "300 (AI)", "350 (AI)", "600", "800", "1000", "1200", "1000", "800", "1000", "1000", "1000/1200", "1000");
  54. addNutrientData("磷", "mg", "160 (AI)", "280 (AI)", "400", "500", "600", "800", "700", "700", "700", "700", "700", "700");
  55. addNutrientData("钾", "mg", "350 (AI)", "450 (AI)", "700", "900", "1300", "1800", "2000", "2000", "2000", "2000", "2000", "2000");
  56. addNutrientData("钠", "mg", "170 (AI)", "350 (AI)", "700", "900", "1200", "1500", "1500", "1500", "1500", "1500", "1500", "1500");
  57. addNutrientData("镁", "mg", "25 (AI)", "40 (AI)", "100", "120", "150", "200", "250", "330", "330", "330", "350", "350");
  58. addNutrientData("氯", "mg", "270 (AI)", "540 (AI)", "1000", "1200", "1700", "2300", "2300", "2300", "2300", "2300", "2300", "2300");
  59. // 微量元素
  60. addNutrientData("铁", "mg", "0.3 (AI)", "10", "9", "10", "12", "男16/女20", "男15/女20", "男12/女20", "12", "12", "24", "13");
  61. addNutrientData("锌", "mg", "1.5 (AI)", "3 (AI)", "4", "5", "7", "男10/女9", "男12.5/女7.5", "男12.5/女7.5", "男12.5/女7.5", "男12.5/女7.5", "10/12.5", "16.5");
  62. addNutrientData("硒", "μg", "15 (AI)", "20 (AI)", "20", "25", "30", "40", "50", "60", "60", "60", "65", "75");
  63. addNutrientData("铜", "mg", "0.2 (AI)", "0.3 (AI)", "0.8", "0.9", "1", "1.1", "1.1", "0.8", "0.8", "0.8", "1.3", "1.3");
  64. addNutrientData("锰", "mg", "0.05 (AI)", "0.08 (AI)", "1.5", "2.5", "3.5", "4.5", "4.5", "4.5", "4.5", "4.5", "4.5", "4.5");
  65. addNutrientData("碘", "μg", "85 (AI)", "115 (AI)", "90", "90", "120", "120", "120", "120", "120", "120", "230", "240");
  66. addNutrientData("氟", "mg", "0.01 (AI)", "0.05 (AI)", "0.7", "1", "1.5", "2", "2.5", "3", "3", "3", "3", "3");
  67. addNutrientData("铬", "μg", "5 (AI)", "10 (AI)", "15", "20", "25", "30", "30", "50", "50", "50", "50", "50");
  68. addNutrientData("钼", "μg", "2 (AI)", "4 (AI)", "6", "8", "10", "12", "15", "30", "30", "30", "30", "30");
  69. // 脂溶性维生素
  70. addNutrientData("维生素A", "μg RE", "400 (AI)", "400 (AI)", "400", "500", "600", "700", "700", "800", "700", "700", "800/900", "1200");
  71. addNutrientData("维生素D", "μg", "10 (AI)", "10 (AI)", "10", "10", "10", "10", "10", "10", "10", "10", "10", "10");
  72. addNutrientData("维生素E", "mg α-TE", "3 (AI)", "4 (AI)", "6", "7", "9", "11", "14", "14", "14", "14", "14", "14");
  73. addNutrientData("维生素K", "μg", "2 (AI)", "2.5 (AI)", "25", "30", "40", "50", "60", "80", "80", "80", "80", "80");
  74. // 水溶性维生素
  75. addNutrientData("维生素B1", "mg", "0.2 (AI)", "0.3 (AI)", "0.6", "0.8", "1", "男1.2/女1.0", "男1.3/女1.1", "男1.4/女1.2", "男1.4/女1.2", "男1.4/女1.2", "1.5/1.6", "1.6");
  76. addNutrientData("维生素B2", "mg", "0.2 (AI)", "0.3 (AI)", "0.6", "0.8", "1", "男1.2/女1.0", "男1.3/女1.1", "男1.4/女1.2", "男1.4/女1.2", "男1.4/女1.2", "1.5/1.6", "1.7");
  77. addNutrientData("维生素B6", "mg", "0.1 (AI)", "0.2 (AI)", "0.6", "0.8", "1", "男1.2/女1.0", "男1.4/女1.2", "男1.4/女1.2", "男1.4/女1.2", "男1.4/女1.2", "1.8", "2");
  78. addNutrientData("维生素B12", "μg", "0.3 (AI)", "0.4 (AI)", "0.7", "1", "1.3", "1.6", "2", "2.4", "2.4", "2.4", "2.6", "2.8");
  79. addNutrientData("烟酸", "mg NE", "2 (AI)", "3 (AI)", "6", "8", "11", "男14/女12", "男16/女14", "男18/女14", "男18/女14", "男18/女14", "18", "18");
  80. addNutrientData("维生素C", "mg", "40 (AI)", "50 (AI)", "60", "70", "80", "90", "100", "100", "100", "100", "115/130", "150");
  81. addNutrientData("叶酸", "μg DFE", "65 (AI)", "80 (AI)", "150", "200", "250", "300", "350", "400", "400", "400", "600", "500");
  82. addNutrientData("胆碱", "mg", "125 (AI)", "150 (AI)", "175", "200", "250", "300", "350", "400", "400", "400", "450", "550");
  83. addNutrientData("生物素", "μg", "5 (AI)", "6 (AI)", "8", "12", "15", "20", "25", "30", "30", "30", "30", "35");
  84. addNutrientData("泛酸", "mg", "1.7 (AI)", "2.0 (AI)", "3", "4", "4", "5", "5", "5", "5", "5", "6", "7");
  85. // 其他
  86. addNutrientData("膳食纤维", "g", "-", "-", "13", "14", "15", "18", "20", "25", "25", "25", "25", "25");
  87. }
  88. // 添加营养素数据
  89. private static void addNutrientData(String nutrient, String... values) {
  90. Map<String, String> dataMap = new HashMap<>();
  91. String[] ageGroups = {
  92. "0-6月", "7-12月", "1-3岁", "4-6岁", "7-10岁",
  93. "11-13岁", "14-17岁", "18-49岁", "50-64岁", "≥65岁",
  94. "孕妇(中期/晚期)", "乳母"
  95. };
  96. for (int i = 0; i < values.length && i < ageGroups.length; i++) {
  97. dataMap.put(ageGroups[i], values[i] + (values[i].equals("-") ? "" : " " ));
  98. }
  99. NUTRIENT_MAP.put(nutrient, dataMap);
  100. }
  101. /**
  102. * 根据整数年龄获取营养推荐值
  103. *
  104. * @param nutrient 营养素名称
  105. * @param gender 性别 (男/女,当不需要区分性别时可传null)
  106. * @param age 实际年龄 (整数)
  107. * @return 对应的营养值 (带单位),未找到返回null
  108. */
  109. public static String getValueByAge(String nutrient, String gender, int age) {
  110. String ageGroup = findAgeGroup(age);
  111. return getValue(nutrient, gender, ageGroup);
  112. }
  113. /**
  114. * 根据年龄组名称获取营养推荐值
  115. *
  116. * @param nutrient 营养素名称
  117. * @param gender 性别 (男/女,当不需要区分性别时可传null)
  118. * @param ageGroup 年龄组名称
  119. * @return 对应的营养值 (带单位),未找到返回null
  120. */
  121. public static String getValue(String nutrient, String gender, String ageGroup) {
  122. // 获取标准化的年龄组
  123. String normalizedAgeGroup = normalizeAgeGroup(ageGroup);
  124. // 获取营养素数据
  125. Map<String, String> nutrientData = NUTRIENT_MAP.get(nutrient);
  126. if (nutrientData == null) return null;
  127. // 获取原始值
  128. String rawValue = nutrientData.get(normalizedAgeGroup);
  129. if (rawValue == null) return null;
  130. // 处理带斜杠的值
  131. if (rawValue.contains("/")) {
  132. // 处理孕妇中期/晚期
  133. if ("孕妇(中期/晚期)".equals(normalizedAgeGroup)) {
  134. String[] parts = rawValue.split(" ")[0].split("/");
  135. return parts.length > 1 ? parts[0] + " (中期)" + "/" + parts[1] + " (晚期)" : rawValue;
  136. }
  137. // 处理性别区分值
  138. if (gender != null && rawValue.contains("男") && rawValue.contains("女")) {
  139. return extractGenderSpecificValue(rawValue, gender);
  140. }
  141. }
  142. return rawValue;
  143. }
  144. // 根据年龄查找对应的年龄组
  145. private static String findAgeGroup(int age) {
  146. // 特殊处理婴儿(0岁)
  147. if (age == 0) return "0-6月";
  148. for (Map.Entry<String, AgeRange> entry : AGE_RANGE_MAP.entrySet()) {
  149. AgeRange range = entry.getValue();
  150. if (range.contains(age)) {
  151. return entry.getKey();
  152. }
  153. }
  154. return "18-49岁"; // 默认值
  155. }
  156. // 标准化年龄组
  157. private static String normalizeAgeGroup(String ageGroup) {
  158. if (AGE_RANGE_MAP.containsKey(ageGroup)) {
  159. return AGE_RANGE_MAP.get(ageGroup).groupName;
  160. }
  161. return ageGroup;
  162. }
  163. // 提取性别特定值
  164. private static String extractGenderSpecificValue(String rawValue, String gender) {
  165. // 分离值和单位
  166. String[] parts = rawValue.split(" ");
  167. String valuePart = parts[0];
  168. String unit = parts.length > 1 ? " " + parts[1] : "";
  169. Pattern pattern = Pattern.compile("男([^/]+)/女([^/]+)");
  170. Matcher matcher = pattern.matcher(valuePart);
  171. if (matcher.find()) {
  172. String maleValue = matcher.group(1).trim();
  173. String femaleValue = matcher.group(2).trim();
  174. return ("男".equals(gender) ? maleValue : femaleValue) + unit;
  175. }
  176. return rawValue;
  177. }
  178. // 获取所有支持查询的营养素列表
  179. public static String[] getAvailableNutrients() {
  180. return NUTRIENT_MAP.keySet().toArray(new String[0]);
  181. }
  182. }