feat (farm): 基地,地块
- 新增,修改,删除时添加面积限制
This commit is contained in:
@@ -117,4 +117,6 @@ public interface ErrorCodeConstants {
|
||||
// ========== 设备报警 1_050_035_000 ==========
|
||||
ErrorCode TWO_DICT_NOT_EXISTS = new ErrorCode(1_050_035_000, "字典不存在");
|
||||
|
||||
ErrorCode PLOT_AREA_ERRORS = new ErrorCode(1_050_036_000, "地块面积总和大于基地面积");
|
||||
|
||||
}
|
||||
@@ -13,9 +13,9 @@ import cn.iocoder.yudao.module.farm.dal.mysql.baseinfo.BaseInfoMapper;
|
||||
import cn.iocoder.yudao.module.farm.dal.mysql.gridinfo.GridInfoMapper;
|
||||
import cn.iocoder.yudao.module.farm.dal.mysql.personnelmanagement.PersonnelManagementMapper;
|
||||
import cn.iocoder.yudao.module.farm.dal.mysql.plotinfo.PlotInfoMapper;
|
||||
import cn.iocoder.yudao.module.farm.dal.mysql.productionplan.ProductionPlanMapper;
|
||||
import cn.iocoder.yudao.module.farm.dal.mysql.specieslibrary.SpeciesLibraryMapper;
|
||||
import cn.iocoder.yudao.module.farm.enums.CommonConstants;
|
||||
import cn.iocoder.yudao.module.farm.service.productionplan.ProductionPlanService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import jakarta.annotation.Resource;
|
||||
@@ -48,14 +48,13 @@ public class BaseInfoServiceImpl implements BaseInfoService {
|
||||
@Resource
|
||||
private PlotInfoMapper plotInfoMapper;
|
||||
@Resource
|
||||
private ProductionPlanMapper productionPlanMapper;
|
||||
@Resource
|
||||
private SpeciesLibraryMapper speciesLibraryMapper;
|
||||
@Resource
|
||||
private PersonnelManagementMapper personnelManagementMapper;
|
||||
@Resource
|
||||
private GridInfoMapper gridInfoMapper;
|
||||
|
||||
@Resource
|
||||
private ProductionPlanService productionPlanService;
|
||||
|
||||
@Override
|
||||
public String createBaseInfo(BaseInfoSaveReqVO createReqVO) {
|
||||
@@ -72,19 +71,30 @@ public class BaseInfoServiceImpl implements BaseInfoService {
|
||||
|
||||
@Override
|
||||
public void updateBaseInfo(BaseInfoSaveReqVO updateReqVO) {
|
||||
String baseId = updateReqVO.getId();
|
||||
// 校验存在
|
||||
validateBaseInfoExists(updateReqVO.getId());
|
||||
validateBaseInfoExists(baseId);
|
||||
BaseInfoDO sourceBaseInfoDO = baseInfoMapper.selectById(baseId);
|
||||
BigDecimal oldArea = sourceBaseInfoDO.getArea();
|
||||
BigDecimal newArea = updateReqVO.getArea();
|
||||
// 更新
|
||||
BaseInfoDO updateObj = BeanUtils.toBean(updateReqVO, BaseInfoDO.class);
|
||||
baseInfoMapper.updateById(updateObj);
|
||||
// 同步
|
||||
productionPlanService.syncBaseAreaToAllPlansByBaseId(baseId, newArea, oldArea);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteBaseInfo(String id) {
|
||||
// 校验存在
|
||||
validateBaseInfoExists(id);
|
||||
// 删除
|
||||
baseInfoMapper.deleteById(id);
|
||||
// 校验: 存在在种地块时 不允许删除
|
||||
boolean flag = productionPlanService.validateIncompletePlansBId("base_id",id);
|
||||
if (flag) {
|
||||
// 删除
|
||||
baseInfoMapper.deleteById(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -184,39 +194,47 @@ public class BaseInfoServiceImpl implements BaseInfoService {
|
||||
}
|
||||
|
||||
private void packageBaseInfo(long tenantId,List<BaseInfoRespVO> respVOS, Map<String, String> employeeMap) {
|
||||
|
||||
for (BaseInfoRespVO obj : respVOS) {
|
||||
String baseId = obj.getId();
|
||||
String baseName = obj.getName();
|
||||
BigDecimal baseArea = obj.getArea();
|
||||
List<PlotInfoDO> plotList = plotInfoMapper.selectList("base_id", baseId);
|
||||
|
||||
// 在种作物数量
|
||||
Integer cropCount = speciesLibraryMapper.getSpeciesCount(tenantId,baseId);
|
||||
// 在种地块占比
|
||||
double plotRatio = 0.00;
|
||||
// 在种地块数量
|
||||
int plotCount = 1;
|
||||
// 地块总数
|
||||
int plotTotalCount = plotList.size();
|
||||
if (plotTotalCount > 0) {
|
||||
plotRatio = Math.round((plotCount * 10000.0) / plotTotalCount) / 100.0;
|
||||
}
|
||||
|
||||
obj.setBaseOverview(new BaseInfoRespVO.BaseInfo(baseId,baseName,baseArea,cropCount,plotCount,plotTotalCount,plotRatio));
|
||||
|
||||
// 基地概述
|
||||
BaseInfoRespVO.BaseInfo baseOverview = this.packageBaseOverview(tenantId, baseId, baseName, baseArea, plotList);
|
||||
obj.setBaseOverview(baseOverview);
|
||||
// 地块集合
|
||||
List<BaseInfoRespVO.PlotInfo> targetList = new ArrayList<>();
|
||||
for (PlotInfoDO aDo : plotList) {
|
||||
String plotManager = employeeMap.getOrDefault(aDo.getEmployeeId(), "系统");
|
||||
List<BaseInfoRespVO.GridInfo> gridInfos = this.packageGridInfo(aDo.getId());
|
||||
BaseInfoRespVO.PlotInfo target = new BaseInfoRespVO.PlotInfo(aDo.getId(), aDo.getPlotName(), aDo.getPlotColor(), aDo.getPlotArea(), plotManager,aDo.getPoint(),gridInfos);
|
||||
targetList.add(target);
|
||||
}
|
||||
List<BaseInfoRespVO.PlotInfo> targetList = this.packagePlotInfo(employeeMap, plotList);
|
||||
obj.setPlotOverviewList(targetList);
|
||||
}
|
||||
}
|
||||
|
||||
private BaseInfoRespVO.BaseInfo packageBaseOverview(long tenantId, String baseId, String baseName, BigDecimal baseArea, List<PlotInfoDO> plotList) {
|
||||
// 在种作物数量
|
||||
Integer cropCount = speciesLibraryMapper.getSpeciesCount(tenantId, baseId);
|
||||
// 在种地块占比
|
||||
double plotRatio = 0.00;
|
||||
// 在种地块数量
|
||||
int plotCount = productionPlanService.getGrowingPlotCount(baseId);
|
||||
// 地块总数
|
||||
int plotTotalCount = plotList.size();
|
||||
if (plotTotalCount > 0) {
|
||||
plotRatio = Math.round((plotCount * 10000.0) / plotTotalCount) / 100.0;
|
||||
}
|
||||
return new BaseInfoRespVO.BaseInfo(baseId, baseName, baseArea, cropCount, plotCount, plotTotalCount, plotRatio);
|
||||
}
|
||||
|
||||
private List<BaseInfoRespVO.PlotInfo> packagePlotInfo(Map<String, String> employeeMap, List<PlotInfoDO> plotList) {
|
||||
List<BaseInfoRespVO.PlotInfo> targetList = new ArrayList<>();
|
||||
for (PlotInfoDO aDo : plotList) {
|
||||
String plotManager = employeeMap.getOrDefault(aDo.getEmployeeId(), "系统");
|
||||
List<BaseInfoRespVO.GridInfo> gridInfos = this.packageGridInfo(aDo.getId());
|
||||
BaseInfoRespVO.PlotInfo target = new BaseInfoRespVO.PlotInfo(aDo.getId(), aDo.getPlotName(), aDo.getPlotColor(), aDo.getPlotArea(), plotManager, aDo.getPoint(), gridInfos);
|
||||
targetList.add(target);
|
||||
}
|
||||
return targetList;
|
||||
}
|
||||
|
||||
private List<BaseInfoRespVO.GridInfo> packageGridInfo(String plotId) {
|
||||
List<GridInfoDO> gridList = gridInfoMapper.selectList("plot_id", plotId);
|
||||
if (ObjectUtils.isEmpty(gridList)) {
|
||||
|
||||
@@ -6,17 +6,23 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.security.core.LoginUser;
|
||||
import cn.iocoder.yudao.module.farm.controller.admin.plotinfo.vo.PlotInfoPageReqVO;
|
||||
import cn.iocoder.yudao.module.farm.controller.admin.plotinfo.vo.PlotInfoSaveReqVO;
|
||||
import cn.iocoder.yudao.module.farm.dal.dataobject.baseinfo.BaseInfoDO;
|
||||
import cn.iocoder.yudao.module.farm.dal.dataobject.plotinfo.PlotInfoDO;
|
||||
import cn.iocoder.yudao.module.farm.dal.mysql.baseinfo.BaseInfoMapper;
|
||||
import cn.iocoder.yudao.module.farm.dal.mysql.plotinfo.PlotInfoMapper;
|
||||
import cn.iocoder.yudao.module.farm.service.productionplan.ProductionPlanService;
|
||||
import cn.iocoder.yudao.module.farm.utils.StrHelperUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUser;
|
||||
import static cn.iocoder.yudao.module.farm.enums.ErrorCodeConstants.PLOT_AREA_ERRORS;
|
||||
import static cn.iocoder.yudao.module.farm.enums.ErrorCodeConstants.PLOT_INFO_NOT_EXISTS;
|
||||
|
||||
/**
|
||||
@@ -28,15 +34,26 @@ import static cn.iocoder.yudao.module.farm.enums.ErrorCodeConstants.PLOT_INFO_NO
|
||||
@Validated
|
||||
public class PlotInfoServiceImpl implements PlotInfoService {
|
||||
|
||||
@Resource
|
||||
private BaseInfoMapper baseInfoMapper;
|
||||
@Resource
|
||||
private PlotInfoMapper plotInfoMapper;
|
||||
@Resource
|
||||
private ProductionPlanService productionPlanService;
|
||||
|
||||
@Override
|
||||
public String createPlotInfo(PlotInfoSaveReqVO createReqVO) {
|
||||
LoginUser user = getLoginUser();
|
||||
// 验证地块面积总和 需要小于或等于 基地面积
|
||||
boolean flag = this.validateTotalPlotArea(createReqVO.getBaseId());
|
||||
if (flag) {
|
||||
throw exception(PLOT_AREA_ERRORS);
|
||||
}
|
||||
|
||||
// 插入
|
||||
PlotInfoDO plotInfo = BeanUtils.toBean(createReqVO, PlotInfoDO.class);
|
||||
plotInfo.setId(IdUtil.fastUUID());
|
||||
plotInfo.setPlotId(StrHelperUtil.generate());
|
||||
plotInfo.setTenantId(String.valueOf(user.getTenantId()));
|
||||
plotInfoMapper.insert(plotInfo);
|
||||
|
||||
@@ -48,17 +65,31 @@ public class PlotInfoServiceImpl implements PlotInfoService {
|
||||
public void updatePlotInfo(PlotInfoSaveReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
validatePlotInfoExists(updateReqVO.getId());
|
||||
// PlotInfoDO sourcePlotInfoDO = plotInfoMapper.selectById(updateReqVO.getId());
|
||||
// String plotId = sourcePlotInfoDO.getPlotId();
|
||||
// BigDecimal oldArea = sourcePlotInfoDO.getPlotArea();
|
||||
// BigDecimal newArea = updateReqVO.getPlotArea();
|
||||
|
||||
// 更新
|
||||
PlotInfoDO updateObj = BeanUtils.toBean(updateReqVO, PlotInfoDO.class);
|
||||
plotInfoMapper.updateById(updateObj);
|
||||
// 同步
|
||||
// productionPlanService.syncPlotAreaToAllPlansByBaseId(plotId,newArea,oldArea);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deletePlotInfo(String id) {
|
||||
// 校验存在
|
||||
validatePlotInfoExists(id);
|
||||
PlotInfoDO obj = plotInfoMapper.selectById(id);
|
||||
if (obj == null) {
|
||||
throw exception(PLOT_INFO_NOT_EXISTS);
|
||||
}
|
||||
// 校验: 存在在种地块时 不允许删除
|
||||
boolean flag = productionPlanService.validateIncompletePlansBId("plot_id",obj.getPlotId());
|
||||
// 删除
|
||||
plotInfoMapper.deleteById(id);
|
||||
if (flag) {
|
||||
plotInfoMapper.deleteById(id);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -100,4 +131,25 @@ public class PlotInfoServiceImpl implements PlotInfoService {
|
||||
return plotInfoMapper.selectOne(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证: 地块总面积不得大于基地面积
|
||||
* @param baseId 基地面积
|
||||
*/
|
||||
private boolean validateTotalPlotArea(String baseId){
|
||||
BaseInfoDO baseObj = baseInfoMapper.selectOne("id", baseId);
|
||||
BigDecimal baseArea = baseObj.getArea();
|
||||
|
||||
List<PlotInfoDO> plotInfoDOS = plotInfoMapper.selectList("base_id", baseId);
|
||||
if (plotInfoDOS == null || plotInfoDOS.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
BigDecimal plotTotalArea = plotInfoDOS.stream()
|
||||
.map(PlotInfoDO::getPlotArea)
|
||||
.filter(area -> area != null) // 重要:过滤null值
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
return plotTotalArea.compareTo(baseArea) > 0 ;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.farm.dal.dataobject.productionplan.ProductionPlan
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -74,4 +75,40 @@ public interface ProductionPlanService {
|
||||
*/
|
||||
List<BaseNamePlanRespVO> getBaseNameAndPlanList();
|
||||
|
||||
/**
|
||||
* 用于: 修改基地面积
|
||||
* 1. 基地面积不可以小于地块面积总和.
|
||||
* 2. 基地面积不同步到每个关联生产计划中.
|
||||
*
|
||||
* @param baseId 基地编号
|
||||
* @param newArea 更新后的基地面积
|
||||
* @param oldArea 更新前的基地面积
|
||||
*/
|
||||
void syncBaseAreaToAllPlansByBaseId(String baseId, BigDecimal newArea, BigDecimal oldArea);
|
||||
|
||||
/**
|
||||
* 用于: 修改地块面积
|
||||
* 1. 地块总面积不可大于基地面积 且 不可小于在种地块面积之和
|
||||
* 2. 基地面积不同步到每个关联生产计划中.
|
||||
*
|
||||
* @param plotId 地块编号 ,不是ID
|
||||
* @param newArea 新地块面积
|
||||
* @param oldArea 旧地块面积
|
||||
*/
|
||||
void syncPlotAreaToAllPlansByBaseId(String plotId, BigDecimal newArea, BigDecimal oldArea);
|
||||
|
||||
/**
|
||||
* 用于: 删除基地
|
||||
* 需要先验证改基地下属地块是否关联未完成的计划. 存在则不可删除.
|
||||
*
|
||||
* @param baseId 基地ID
|
||||
*/
|
||||
boolean validateIncompletePlansBId(String field, String baseId);
|
||||
|
||||
/**
|
||||
* 获取在种地块数量
|
||||
* @param baseId
|
||||
* @return
|
||||
*/
|
||||
int getGrowingPlotCount(String baseId);
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.farm.controller.admin.baseinfo.vo.BaseNamePlanRes
|
||||
import cn.iocoder.yudao.module.farm.controller.admin.productionplan.vo.ProductionPlanPageReqVO;
|
||||
import cn.iocoder.yudao.module.farm.controller.admin.productionplan.vo.ProductionPlanSaveReqVO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@@ -19,13 +20,13 @@ import cn.iocoder.yudao.framework.security.core.LoginUser;
|
||||
|
||||
import cn.iocoder.yudao.module.farm.dal.mysql.productionplan.ProductionPlanMapper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUser;
|
||||
import static cn.iocoder.yudao.module.farm.enums.CommonConstants.*;
|
||||
import static cn.iocoder.yudao.module.farm.enums.ErrorCodeConstants.PRODUCTION_PLAN_NOT_EXISTS;
|
||||
|
||||
/**
|
||||
@@ -156,4 +157,45 @@ public class ProductionPlanServiceImpl implements ProductionPlanService {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncBaseAreaToAllPlansByBaseId(String baseId, BigDecimal newArea, BigDecimal oldArea) {
|
||||
if (oldArea.compareTo(newArea) == 0) {
|
||||
return ;
|
||||
}
|
||||
|
||||
List<ProductionPlanDO> planList = productionPlanMapper.selectList("base_id", baseId);
|
||||
planList.forEach(e -> e.setTotalArea(newArea.doubleValue()));
|
||||
productionPlanMapper.updateBatch(planList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncPlotAreaToAllPlansByBaseId(String plotId, BigDecimal newArea, BigDecimal oldArea) {
|
||||
// if (oldArea.compareTo(newArea) == 0) {
|
||||
// return ;
|
||||
// }
|
||||
// List<ProductionPlanDO> planList = productionPlanMapper.selectList("plot_id", plotId);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateIncompletePlansBId(String field,String baseId) {
|
||||
List<ProductionPlanDO> planList = productionPlanMapper.selectList(field, baseId);
|
||||
Set<Integer> planStatusSet = planList.stream()
|
||||
.filter(e -> !ObjectUtils.notEqual(e.getPlanStatus(), PLAN_STATUS_3))
|
||||
.map(ProductionPlanDO::getPlanStatus)
|
||||
.collect(Collectors.toSet());
|
||||
// 存在未完成状态的计划 不可删除
|
||||
if (planStatusSet.size() > 0) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGrowingPlotCount(String baseId) {
|
||||
List<ProductionPlanDO> planList = productionPlanMapper.selectList("base_id", baseId);
|
||||
long count = planList.stream().filter(e -> Objects.equals(e.getPlanStatus(), PLAN_STATUS_2)).count();
|
||||
return (int) count;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user