Compare commits

..

2 Commits

Author SHA1 Message Date
HashMap
fba29a69a1 Merge branch 'feature/feeding-management-20250801' 2025-08-26 12:02:50 +08:00
HashMap
ec79fcd9b4 fix(module/feed): 修复配料清单和饲喂量统计存在的逻辑错误
+ 修复了配料清单的分组逻辑错误:
    + 配料清单先将在原基础上再根据饲喂计划中的日期分组
    + 缓存与同步逻辑重写, 以适配新的分组逻辑
+ 修复了饲喂量统计的部分逻辑错误:
    + 解决了羊舍信息的SQL与Service层统计错误
    + 修改了缓存查询逻辑以适配新的清单缓存
2025-08-26 12:02:00 +08:00
7 changed files with 109 additions and 21 deletions

View File

@ -1,6 +1,8 @@
package com.zhyc.module.feed.controller; package com.zhyc.module.feed.controller;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -63,19 +65,19 @@ public class SgFeedListController extends BaseController {
List<SgFeedList> list = sgFeedListService.selectSgFeedListList(sgFeedList); List<SgFeedList> list = sgFeedListService.selectSgFeedListList(sgFeedList);
// map 中已有的数据替换 list 中的元素 // map 中已有的数据替换 list 中的元素
List<SgFeedList> replacedList = new ArrayList<>(); List<SgFeedList> replacedList = new ArrayList<>();
for (SgFeedList item : list) { for (SgFeedList item : list) {
String key = item.getFormulaId() + "_" + item.getFormulaBatchId(); String key = item.getFormulaId() + "_" + item.getFormulaBatchId() + "_" + item.getDeployDate();
// 从缓存中取出完整对象 // 从缓存中取出完整对象
SgFeedList itemInCache = SgFeedListServiceImpl.getSgFeedListMap().getOrDefault(key, item); SgFeedList itemInCache = SgFeedListServiceImpl.getSgFeedListMap().getOrDefault(key, item);
// 将数据库查询的基本信息替换掉缓存中去除的内容 - 前端展示与修改需要 // 将数据库查询的基本信息替换掉缓存中去除的内容 - 前端展示与修改需要
itemInCache.setId(item.getId()); itemInCache.setId(item.getId());
itemInCache.setFormulaBatchId(item.getFormulaBatchId()); itemInCache.setFormulaBatchId(item.getFormulaBatchId());
itemInCache.setFormulaId(item.getFormulaId()); itemInCache.setFormulaId(item.getFormulaId());
itemInCache.setZookeeper(item.getZookeeper()); itemInCache.setZookeeper(item.getZookeeper());
itemInCache.setDeployDate(item.getDeployDate()); itemInCache.setDeployDate(item.getDeployDate());
// 替换为 map 中的对象 // 替换为 map 中的对象
replacedList.add(itemInCache); replacedList.add(itemInCache);
} }
return getDataTable(replacedList); return getDataTable(replacedList);
} }
@ -117,6 +119,7 @@ public class SgFeedListController extends BaseController {
@Log(title = "配料清单", businessType = BusinessType.UPDATE) @Log(title = "配料清单", businessType = BusinessType.UPDATE)
@PutMapping @PutMapping
public AjaxResult edit(@RequestBody SgFeedList sgFeedList) { public AjaxResult edit(@RequestBody SgFeedList sgFeedList) {
return toAjax(sgFeedListService.updateSgFeedList(sgFeedList)); return toAjax(sgFeedListService.updateSgFeedList(sgFeedList));
} }

View File

@ -53,6 +53,8 @@ public class SgFeedList extends BaseEntity
private List<SgFormulaList> formulaList; private List<SgFormulaList> formulaList;
private List<SgFeedPlan> planList;
@Override @Override
public String toString() { public String toString() {

View File

@ -60,4 +60,7 @@ public interface SgFeedListMapper
* @return 结果 * @return 结果
*/ */
int deleteSgFeedListByIds(Long[] ids); int deleteSgFeedListByIds(Long[] ids);
// 清空所有
int deleteAll();
} }

View File

@ -1,8 +1,6 @@
package com.zhyc.module.feed.service.impl; package com.zhyc.module.feed.service.impl;
import java.util.HashMap; import java.util.*;
import java.util.List;
import java.util.Map;
import com.zhyc.module.feed.domain.SgFeedPlan; import com.zhyc.module.feed.domain.SgFeedPlan;
import com.zhyc.module.feed.domain.SgFormulaManagement; import com.zhyc.module.feed.domain.SgFormulaManagement;
@ -32,6 +30,12 @@ public class SgFeedListServiceImpl implements ISgFeedListService {
this.sgFeedListMapper = sgFeedListMapper; this.sgFeedListMapper = sgFeedListMapper;
this.sgFormulaManagementService = sgFormulaManagementService; this.sgFormulaManagementService = sgFormulaManagementService;
this.sgFeedPlanService = sgFeedPlanService; this.sgFeedPlanService = sgFeedPlanService;
// 构造时将数据库初始数据写入缓存
List<SgFeedList> feedListsFromDataBase = this.selectSgFeedListList(new SgFeedList());
for (SgFeedList sgFeedListItem : feedListsFromDataBase) {
String key = sgFeedListItem.getFormulaId() + "_" + sgFeedListItem.getFormulaBatchId() + "_" + sgFeedListItem.getDeployDate();
sgFeedListMap.put(key, sgFeedListItem);
}
} }
/** /**
@ -100,7 +104,7 @@ public class SgFeedListServiceImpl implements ISgFeedListService {
return sgFeedListMapper.deleteSgFeedListById(id); return sgFeedListMapper.deleteSgFeedListById(id);
} }
public void SyncFeedList() { public void SyncFeedList_old() {
// 清空旧缓存 // 清空旧缓存
sgFeedListMap.clear(); sgFeedListMap.clear();
// 获取配方管理和现有配料清单内容 // 获取配方管理和现有配料清单内容
@ -153,6 +157,74 @@ public class SgFeedListServiceImpl implements ISgFeedListService {
} }
} }
public void SyncFeedList() {
HashMap<String, SgFeedList> cacheTemp = new HashMap<>(sgFeedListMap);
// 清空旧缓存
sgFeedListMap.clear();
List<SgFeedPlan> sgFeedPlans = sgFeedPlanService.selectSgFeedPlanList(new SgFeedPlan());
List<List<SgFeedPlan>> planGroups = new ArrayList<>();
List<SgFeedPlan> currentFeedPlan = new ArrayList<>();
if (!sgFeedPlans.isEmpty()) {
String currentFormulaId = sgFeedPlans.get(0).getFormulaId();
String currentBatchId = sgFeedPlans.get(0).getBatchId();
Date currentDate = sgFeedPlans.get(0).getPlanDate();
// 对饲喂计划进行分组
for (SgFeedPlan sgFeedPlan : sgFeedPlans) {
if (sgFeedPlan.getBatchId() != null && !sgFeedPlan.getBatchId().equals("0")) {
if (sgFeedPlan.getFormulaId().equals(currentFormulaId) && sgFeedPlan.getBatchId().equals(currentBatchId) && sgFeedPlan.getPlanDate().equals(currentDate)) {
currentFeedPlan.add(sgFeedPlan);
} else {
currentDate = sgFeedPlan.getPlanDate();
currentBatchId = sgFeedPlan.getBatchId();
currentFormulaId = sgFeedPlan.getFormulaId();
planGroups.add(currentFeedPlan);
currentFeedPlan = new ArrayList<>();
// 立即插入否则会丢失该元素
currentFeedPlan.add(sgFeedPlan);
}
}
}
// 插入最后一个列表 - 否则该列表会丢失
planGroups.add(currentFeedPlan);
// 注册数据 - 每一个List为一个清单
for (List<SgFeedPlan> sgFeedPlanList : planGroups) {
SgFeedList sgFeedList = new SgFeedList();
// 计算饲喂总和
SgFeedPlan rootPlan = computePlanTotal(sgFeedPlanList);
sgFeedList.setRootPlan(rootPlan);
sgFeedList.setPlanList(sgFeedPlanList);
// 写入信息
sgFeedList.setFormulaId(sgFeedPlanList.get(0).getFormulaId());
sgFeedList.setFormulaBatchId(sgFeedPlanList.get(0).getBatchId());
sgFeedList.setDeployDate(sgFeedPlanList.get(0).getPlanDate());
// 写入配方管理信息
SgFormulaManagement formulaManagementQuery = new SgFormulaManagement();
formulaManagementQuery.setFormulaId(sgFeedList.getFormulaId());
formulaManagementQuery.setBatchId(sgFeedList.getFormulaBatchId());
List<SgFormulaManagement> formulaManagements = sgFormulaManagementService.selectSgFormulaManagementList(formulaManagementQuery);
if (!formulaManagements.isEmpty()) {
sgFeedList.setRootFormula(formulaManagements.get(0));
sgFeedList.setFormulaList(formulaManagements.get(0).getSgFormulaList());
}
String cacheKey = sgFeedList.getFormulaId() + "_" + sgFeedList.getFormulaBatchId() + "_" + sgFeedList.getDeployDate();
// 从就缓存中查找如果存在则更新可修改的值
if (cacheTemp.containsKey(cacheKey)) {
SgFeedList cacheItem = cacheTemp.get(cacheKey);
sgFeedList.setZookeeper(cacheItem.getZookeeper());
}
sgFeedListMap.put(cacheKey, sgFeedList);
}
List<SgFeedList> toDataBase = new ArrayList<>(sgFeedListMap.values());
// 清空再写入
this.sgFeedListMapper.deleteAll();
// 处理结果写入数据库
for (SgFeedList recordItem : toDataBase) {
this.insertSgFeedList(recordItem);
}
}
}
/** /**
* 计算某个配方某个批次的总和值 * 计算某个配方某个批次的总和值
* *
@ -176,7 +248,8 @@ public class SgFeedListServiceImpl implements ISgFeedListService {
planFeedAfternoonSize += sgFeedPlan.getPlanAfternoonSize(); planFeedAfternoonSize += sgFeedPlan.getPlanAfternoonSize();
planFeedTotalSize += sgFeedPlan.getPlanFeedTotal(); planFeedTotalSize += sgFeedPlan.getPlanFeedTotal();
} }
rootPlan.setFormulaId(sgFeedPlans.get(0).getFormulaId());
rootPlan.setBatchId(sgFeedPlans.get(0).getBatchId());
rootPlan.setSheepCount(sheepCountTotal); rootPlan.setSheepCount(sheepCountTotal);
rootPlan.setPlanDailySize(sheepDailySize); rootPlan.setPlanDailySize(sheepDailySize);
rootPlan.setPlanMorningSize(planFeedMorningSize); rootPlan.setPlanMorningSize(planFeedMorningSize);

View File

@ -119,7 +119,7 @@ public class SgFeedStatisticServiceImpl implements ISgFeedStatisticService {
sgFeedListService.SyncFeedList(); sgFeedListService.SyncFeedList();
// 从缓存获取完整配方清单 // 从缓存获取完整配方清单
String cacheKey = sgFeedStatistic.getFormulaId() + "_" + sgFeedStatistic.getFormulaBatchId(); String cacheKey = sgFeedStatistic.getFormulaId() + "_" + sgFeedStatistic.getFormulaBatchId() + "_" + sgFeedStatistic.getFeedDate();
SgFeedList sgFeedList = SgFeedListServiceImpl.getSgFeedListMap().get(cacheKey); SgFeedList sgFeedList = SgFeedListServiceImpl.getSgFeedListMap().get(cacheKey);
if (sgFeedList != null && sgFeedList.getFormulaList() != null) { if (sgFeedList != null && sgFeedList.getFormulaList() != null) {
@ -148,7 +148,7 @@ public class SgFeedStatisticServiceImpl implements ISgFeedStatisticService {
SgFeedPlan sgFeedPlanQuery = new SgFeedPlan(); SgFeedPlan sgFeedPlanQuery = new SgFeedPlan();
sgFeedPlanQuery.setFormulaId(sgFeedStatistic.getFormulaId()); sgFeedPlanQuery.setFormulaId(sgFeedStatistic.getFormulaId());
sgFeedPlanQuery.setBatchId(sgFeedStatistic.getFormulaBatchId()); sgFeedPlanQuery.setBatchId(sgFeedStatistic.getFormulaBatchId());
sgFeedPlanQuery.setPlanDate(sgFeedStatistic.getFeedDate());
List<SgFeedPlan> sgFeedPlans = sgFeedPlanService.selectSgFeedPlanList(sgFeedPlanQuery); List<SgFeedPlan> sgFeedPlans = sgFeedPlanService.selectSgFeedPlanList(sgFeedPlanQuery);
if (!sgFeedPlans.isEmpty()) { if (!sgFeedPlans.isEmpty()) {

View File

@ -24,6 +24,7 @@
<if test="zookeeper != null and zookeeper != ''"> and zookeeper = #{zookeeper}</if> <if test="zookeeper != null and zookeeper != ''"> and zookeeper = #{zookeeper}</if>
<if test="deployDate != null "> and deploy_date = #{deployDate}</if> <if test="deployDate != null "> and deploy_date = #{deployDate}</if>
</where> </where>
ORDER BY deploy_date ASC, formula_id ASC, formula_batch_id ASC
</select> </select>
<select id="selectSgFeedListById" parameterType="Long" resultMap="SgFeedListResult"> <select id="selectSgFeedListById" parameterType="Long" resultMap="SgFeedListResult">
@ -68,4 +69,8 @@
#{id} #{id}
</foreach> </foreach>
</delete> </delete>
<delete id="deleteAll">
DELETE FROM sg_feed_list;
</delete>
</mapper> </mapper>

View File

@ -37,9 +37,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include refid="selectSgFeedPlanVo"/> <include refid="selectSgFeedPlanVo"/>
<where> <where>
<if test="formulaId != null and formulaId != ''"> and formula_id = #{formulaId}</if> <if test="formulaId != null and formulaId != ''"> and formula_id = #{formulaId}</if>
<if test="batchId != null and batchId != ''"> and batch_id = #{batchId}</if>
<if test="sheepHouseId != null "> and sheep_house_id = #{sheepHouseId}</if> <if test="sheepHouseId != null "> and sheep_house_id = #{sheepHouseId}</if>
<if test="planDate != null "> and plan_date = #{planDate}</if>
</where> </where>
ORDER BY formula_id ASC, plan_date ASC ORDER BY plan_date ASC, formula_id ASC , batch_id ASC
</select> </select>
<select id="selectSgFeedPlanByCreateDate" parameterType="Date" resultMap="SgFeedPlanResult"> <select id="selectSgFeedPlanByCreateDate" parameterType="Date" resultMap="SgFeedPlanResult">