fix (farm): 首页,基地维护

- 展示网箱占比
- 户主导入功能,加入租赁费
- 户主租赁状态,地块颜色对照问题修复
This commit is contained in:
达富斌
2025-11-19 14:36:49 +08:00
parent 4320d7bd19
commit c3d5bc45a8
7 changed files with 160 additions and 111 deletions

View File

@@ -1,11 +1,12 @@
package cn.iocoder.yudao.module.farm.controller.admin.managementcenter.baseinfo; package cn.iocoder.yudao.module.farm.controller.admin.managementcenter.baseinfo;
import cn.iocoder.yudao.module.farm.controller.admin.managementcenter.baseinfo.vo.wx.BaseInfoForWxRespVO;
import cn.iocoder.yudao.module.farm.controller.admin.managementcenter.baseinfo.vo.*; import cn.iocoder.yudao.module.farm.controller.admin.managementcenter.baseinfo.vo.*;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.util.List; import java.util.List;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
@@ -21,6 +22,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
@@ -120,7 +122,7 @@ public class BaseInfoController {
@Operation(summary = "基地列表") @Operation(summary = "基地列表")
public CommonResult<List<BaseNamesRespVO>> getBaseList() { public CommonResult<List<BaseNamesRespVO>> getBaseList() {
List<BaseInfoDO> baseInfos = baseInfoService.getBaseInfos(); List<BaseInfoDO> baseInfos = baseInfoService.getBaseInfos();
List<BaseNamesRespVO> res = baseInfos.stream().map(e -> new BaseNamesRespVO(e.getId(),e.getName())).toList(); List<BaseNamesRespVO> res = baseInfos.stream().map(e -> new BaseNamesRespVO(e.getId(), e.getName())).toList();
return success(res); return success(res);
} }

View File

@@ -99,6 +99,9 @@ public class CommonConstants {
public final static Integer MESSAGE_TYPE_2 = 2; public final static Integer MESSAGE_TYPE_2 = 2;
public final static Integer MESSAGE_TYPE_3 = 3; public final static Integer MESSAGE_TYPE_3 = 3;
public final static String PLOT_COLOR_BLUE = "#14a3ff"; // 已租,蓝色
public final static String PLOT_COLOR_GREEN = "#5ede84"; // 未租,绿色
public static Map<Integer, String> PLAN_MAP = new HashMap<>(); public static Map<Integer, String> PLAN_MAP = new HashMap<>();
public static Map<String, String> LIFE_CYCLE_MAP = new HashMap<>(); public static Map<String, String> LIFE_CYCLE_MAP = new HashMap<>();
public static Map<String, String> GRID_TYPE = new HashMap<>(); public static Map<String, String> GRID_TYPE = new HashMap<>();

View File

@@ -19,7 +19,6 @@ import cn.iocoder.yudao.module.farm.dal.dataobject.baseinfo.BaseInfoDO;
import cn.iocoder.yudao.module.farm.dal.dataobject.companyinfo.CompanyInfoDO; import cn.iocoder.yudao.module.farm.dal.dataobject.companyinfo.CompanyInfoDO;
import cn.iocoder.yudao.module.farm.dal.dataobject.personnelmanagement.PersonnelManagementDO; import cn.iocoder.yudao.module.farm.dal.dataobject.personnelmanagement.PersonnelManagementDO;
import cn.iocoder.yudao.module.farm.dal.dataobject.plotinfo.PlotInfoDO; import cn.iocoder.yudao.module.farm.dal.dataobject.plotinfo.PlotInfoDO;
import cn.iocoder.yudao.module.farm.dal.dataobject.productionplan.ProductionPlanDO;
import cn.iocoder.yudao.module.farm.dal.mysql.baseinfo.BaseInfoMapper; import cn.iocoder.yudao.module.farm.dal.mysql.baseinfo.BaseInfoMapper;
import cn.iocoder.yudao.module.farm.dal.mysql.personnelmanagement.PersonnelManagementMapper; import cn.iocoder.yudao.module.farm.dal.mysql.personnelmanagement.PersonnelManagementMapper;
import cn.iocoder.yudao.module.farm.dal.mysql.specieslibrary.SpeciesLibraryMapper; import cn.iocoder.yudao.module.farm.dal.mysql.specieslibrary.SpeciesLibraryMapper;
@@ -44,6 +43,7 @@ import org.springframework.validation.annotation.Validated;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -140,29 +140,6 @@ public class BaseInfoServiceImpl implements BaseInfoService {
baseInfoMapper.deleteByIds(ids); baseInfoMapper.deleteByIds(ids);
} }
private void validateBaseInfoExists(String id) {
if (baseInfoMapper.selectById(id) == null) {
throw exception(BASE_INFO_NOT_EXISTS);
}
}
private void validateBaseArea(String baseName) {
BaseInfoDO one = baseInfoMapper.selectOne("name", baseName);
if (ObjectUtils.isNotEmpty(one)) {
throw exception(BASE_NAME_ERROR);
}
}
/**
* 修改后的基地面积 不可小于 其地块面积总和
* @param id
* @param updateBaseArea
*/
private void validateBaseArea(String id,BigDecimal updateBaseArea) {
if (plotInfoService.validateTotalPlotArea(id,updateBaseArea)) {
throw exception(BASE_PLOT_AREA_ERRORS);
}
}
@Override @Override
public BaseInfoDO getBaseInfo(String id) { public BaseInfoDO getBaseInfo(String id) {
@@ -254,102 +231,27 @@ public class BaseInfoServiceImpl implements BaseInfoService {
List<PersonnelManagementDO> personnels = personnelManagementMapper.selectList("tenant_id", tenantId); List<PersonnelManagementDO> personnels = personnelManagementMapper.selectList("tenant_id", tenantId);
int employeeCount = personnels.size(); int employeeCount = personnels.size();
Map<String, String> employeeMap = personnels.stream().collect(Collectors.toMap(PersonnelManagementDO::getId, PersonnelManagementDO::getName, (v1, v2) -> v1)); Map<String, String> employeeMap = personnels.stream().collect(Collectors.toMap(PersonnelManagementDO::getId, PersonnelManagementDO::getName, (v1, v2) -> v1));
// 租户 // 租户
TenantInfoRespVO.TenantInfo tenantInfo = this.getTenantInfo(tenantId, employeeCount); TenantInfoRespVO.TenantInfo tenantInfo = this.getTenantInfo(tenantId, employeeCount);
// 基地 // 基地
List<BaseInfoDO> pageResult = this.getList(new BaseInfoPageReqVO()); List<BaseInfoDO> pageResult = this.getList(new BaseInfoPageReqVO());
List<BaseInfoRespVO> baseList = BeanUtils.toBean(pageResult, BaseInfoRespVO.class); List<BaseInfoRespVO> baseList = BeanUtils.toBean(pageResult, BaseInfoRespVO.class);
this.packageBaseInfo(tenantId, baseList, employeeMap); this.packageBaseInfo(tenantId, baseList, employeeMap);
// 基地面积 取整 // 基地面积 取整
baseList.forEach(e -> e.setArea(BigDecimalUtil.roundedViaMath(e.getArea()))); baseList.forEach(e -> e.setArea(BigDecimalUtil.roundedViaMath(e.getArea())));
return new TenantInfoRespVO(tenantInfo, baseList); return new TenantInfoRespVO(tenantInfo, baseList);
} }
private TenantInfoRespVO.TenantInfo getTenantInfo(long tenantId, Integer employeeCount) {
// 基地总数
Integer baseCount = baseInfoMapper.getBaseCount(tenantId);
// 在种作物总数
Integer cropCount = productionPlanService.getGrowingCropCountByTenantId(String.valueOf(tenantId));
// 基地总面积
BigDecimal areaCount = new BigDecimal("0.00");
if (baseCount > 0) {
QueryWrapper<BaseInfoDO> wrapper = new QueryWrapper<>();
wrapper.eq("tenant_id", tenantId);
wrapper.select("SUM(area) as total_area");
Object result = baseInfoMapper.selectObjs(wrapper).stream().findFirst().orElse(BigDecimal.ZERO);
areaCount = (BigDecimal) result;
}
// 租户公司名称
CompanyInfoDO companyInfo = companyInfoService.getCompanyInfo();
String compName = ObjectUtils.isEmpty(companyInfo) ? "" : companyInfo.getName();
return new TenantInfoRespVO.TenantInfo(compName,baseCount, cropCount, areaCount, employeeCount);
}
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 = BigDecimalUtil.roundedViaMath(obj.getArea());
List<PlotInfoDO> plotList = plotInfoService.getPlotInfos(baseId);
// 基地概述
BaseInfoRespVO.BaseInfo baseOverview = this.packageBaseOverview(tenantId, baseId, baseName, baseArea, plotList);
obj.setBaseOverview(baseOverview);
// 地块集合
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) {
// 网箱
List<ProductionPlanGridRespVO> gridInfos = this.packageGridInfo(aDo.getPlotId());
// 户主
List<PlotLesseeDetailsRespVO> lesseeList = plotLesseeService.getPlotLesseeList(aDo.getId());
String plotManager = employeeMap.getOrDefault(aDo.getEmployeeId(), "系统");
BaseInfoRespVO.PlotInfo target = new BaseInfoRespVO.PlotInfo(
aDo.getId(),
aDo.getPlotName(),
aDo.getPlotColor(),
BigDecimalUtil.roundedViaMath( aDo.getPlotArea()),
plotManager,
aDo.getPoint(),
aDo.getPlotLeaseStatus(),
LEASE_STATUS_MAP.get(aDo.getPlotLeaseStatus()),
aDo.getGridNumber(),
gridInfos,
lesseeList);
targetList.add(target);
}
return targetList;
}
@Override @Override
public List<ProductionPlanGridRespVO> getGridInfo(String plotId) { public List<ProductionPlanGridRespVO> getGridInfo(String plotId) {
String plotCode = plotId; String plotCode = plotId;
return this.packageGridInfo(plotCode); return this.packageGridInfo(plotCode);
} }
private List<ProductionPlanGridRespVO> packageGridInfo(String plotId) {
return productionPlanService.getGridForPlanList(plotId);
}
@Override @Override
public CommonResult<FarmBaseOverviewRespVO> getBaseOverview(FarmBaseOverviewReqVO req) { public CommonResult<FarmBaseOverviewRespVO> getBaseOverview(FarmBaseOverviewReqVO req) {
String tenantId = req.getTenantId(); String tenantId = req.getTenantId();
@@ -380,11 +282,6 @@ public class BaseInfoServiceImpl implements BaseInfoService {
return CommonResult.success(new FarmBaseOverviewRespVO(tenantInfo, baseInfo)); return CommonResult.success(new FarmBaseOverviewRespVO(tenantInfo, baseInfo));
} }
private String getAdministratorName(String tenantId, String manager) {
List<PersonnelManagementDO> personnelList = personnelManagementMapper.selectList("tenant_id", tenantId);
Map<String, String> employeeMap = personnelList.stream().collect(Collectors.toMap(PersonnelManagementDO::getId, PersonnelManagementDO::getName, (v1, v2) -> v1));
return personnelManagementService.getEmployeeNameMap(employeeMap, manager);
}
@Override @Override
public Double getBaseTotalArea(String tenantId) { public Double getBaseTotalArea(String tenantId) {
@@ -492,4 +389,121 @@ public class BaseInfoServiceImpl implements BaseInfoService {
return new BaseCountInfoRespVO(bCount,pCount); return new BaseCountInfoRespVO(bCount,pCount);
} }
/*
* =================私有方法=================
*/
private void validateBaseInfoExists(String id) {
if (baseInfoMapper.selectById(id) == null) {
throw exception(BASE_INFO_NOT_EXISTS);
}
}
private void validateBaseArea(String baseName) {
BaseInfoDO one = baseInfoMapper.selectOne("name", baseName);
if (ObjectUtils.isNotEmpty(one)) {
throw exception(BASE_NAME_ERROR);
}
}
/**
* 修改后的基地面积 不可小于 其地块面积总和
* @param id
* @param updateBaseArea
*/
private void validateBaseArea(String id,BigDecimal updateBaseArea) {
if (plotInfoService.validateTotalPlotArea(id,updateBaseArea)) {
throw exception(BASE_PLOT_AREA_ERRORS);
}
}
private String getAdministratorName(String tenantId, String manager) {
List<PersonnelManagementDO> personnelList = personnelManagementMapper.selectList("tenant_id", tenantId);
Map<String, String> employeeMap = personnelList.stream().collect(Collectors.toMap(PersonnelManagementDO::getId, PersonnelManagementDO::getName, (v1, v2) -> v1));
return personnelManagementService.getEmployeeNameMap(employeeMap, manager);
}
private TenantInfoRespVO.TenantInfo getTenantInfo(long tenantId, Integer employeeCount) {
// 基地总数
Integer baseCount = baseInfoMapper.getBaseCount(tenantId);
// 在种作物总数
Integer cropCount = productionPlanService.getGrowingCropCountByTenantId(String.valueOf(tenantId));
// 基地总面积
BigDecimal areaCount = new BigDecimal("0.00");
if (baseCount > 0) {
QueryWrapper<BaseInfoDO> wrapper = new QueryWrapper<>();
wrapper.eq("tenant_id", tenantId);
wrapper.select("SUM(area) as total_area");
Object result = baseInfoMapper.selectObjs(wrapper).stream().findFirst().orElse(BigDecimal.ZERO);
areaCount = (BigDecimal) result;
}
// 租户公司名称
CompanyInfoDO companyInfo = companyInfoService.getCompanyInfo();
String compName = ObjectUtils.isEmpty(companyInfo) ? "" : companyInfo.getName();
return new TenantInfoRespVO.TenantInfo(compName,baseCount, cropCount, areaCount, employeeCount);
}
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 = BigDecimalUtil.roundedViaMath(obj.getArea());
List<PlotInfoDO> plotList = plotInfoService.getPlotInfos(baseId);
// 基地概述
BaseInfoRespVO.BaseInfo baseOverview = this.packageBaseOverview(tenantId, baseId, baseName, baseArea, plotList);
obj.setBaseOverview(baseOverview);
// 地块集合
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) {
// 网箱
// List<ProductionPlanGridRespVO> gridInfos = this.packageGridInfo(aDo.getPlotId());
List<ProductionPlanGridRespVO> gridInfos = Collections.EMPTY_LIST;
// 户主
List<PlotLesseeDetailsRespVO> lesseeList = plotLesseeService.getPlotLesseeList(aDo.getId());
String plotManager = employeeMap.getOrDefault(aDo.getEmployeeId(), "系统");
BaseInfoRespVO.PlotInfo target = new BaseInfoRespVO.PlotInfo(
aDo.getId(),
aDo.getPlotName(),
aDo.getPlotColor(),
BigDecimalUtil.roundedViaMath( aDo.getPlotArea()),
plotManager,
aDo.getPoint(),
aDo.getPlotLeaseStatus(),
LEASE_STATUS_MAP.get(aDo.getPlotLeaseStatus()),
aDo.getGridNumber(),
gridInfos,
lesseeList);
targetList.add(target);
}
return targetList;
}
private List<ProductionPlanGridRespVO> packageGridInfo(String plotId) {
return productionPlanService.getGridForPlanList(plotId);
}
} }

View File

@@ -314,7 +314,7 @@ public class HomeServiceImpl implements HomeService {
// 物种数量 // 物种数量
// int speciesNum = modelManagementService.getSpeciesNum(getLoginUser().getTenantId().toString()); // int speciesNum = modelManagementService.getSpeciesNum(getLoginUser().getTenantId().toString());
// 网箱使用占比 // 网箱使用占比
String gridRatio = "100/500"; // TODO: 2025/11/6 String gridRatio = productionPlanService.getGridRatio(e.getPlotId());
PlotOrCropInfo t = new PlotOrCropInfo(); PlotOrCropInfo t = new PlotOrCropInfo();
t.setLabel(label); t.setLabel(label);

View File

@@ -122,6 +122,7 @@ public class PlotLesseeServiceImpl implements PlotLesseeService {
if (this.isEmpty(pl)) { if (this.isEmpty(pl)) {
p.setPlotLeaseStatus(NO_CODE); p.setPlotLeaseStatus(NO_CODE);
p.setPlotColor(PLOT_COLOR_GREEN);
plotInfoMapper.updateById(p); plotInfoMapper.updateById(p);
sourcePObj.setLeaseStatus(NO_CODE); sourcePObj.setLeaseStatus(NO_CODE);
@@ -252,6 +253,7 @@ public class PlotLesseeServiceImpl implements PlotLesseeService {
return ChronoUnit.DAYS.between(today, leaseEndDate); return ChronoUnit.DAYS.between(today, leaseEndDate);
} }
private void pInsert(PlotInfoDO p, PlotLesseeForImportExcelRespVO pl, Map<String, String> baseNameMap) { private void pInsert(PlotInfoDO p, PlotLesseeForImportExcelRespVO pl, Map<String, String> baseNameMap) {
PlotLesseeDO target = new PlotLesseeDO(); PlotLesseeDO target = new PlotLesseeDO();
target.setLeaseName(pl.getLeaseName()); target.setLeaseName(pl.getLeaseName());
@@ -259,6 +261,7 @@ public class PlotLesseeServiceImpl implements PlotLesseeService {
target.setLeasePhone(pl.getLeasePhone()); target.setLeasePhone(pl.getLeasePhone());
target.setLeaseStartDate(pl.getLeaseStartDate()); target.setLeaseStartDate(pl.getLeaseStartDate());
target.setLeaseEndDate(pl.getLeaseEndDate()); target.setLeaseEndDate(pl.getLeaseEndDate());
target.setLeaseRental(pl.getLeaseRental());
target.setId(IdUtil.fastUUID()); target.setId(IdUtil.fastUUID());
target.setTenantId(String.valueOf(getLoginUser().getTenantId())); target.setTenantId(String.valueOf(getLoginUser().getTenantId()));
@@ -271,6 +274,7 @@ public class PlotLesseeServiceImpl implements PlotLesseeService {
plotLesseeMapper.insert(target); plotLesseeMapper.insert(target);
p.setPlotLeaseStatus(YES_CODE); p.setPlotLeaseStatus(YES_CODE);
p.setPlotColor(PLOT_COLOR_BLUE);
plotInfoMapper.updateById(p); plotInfoMapper.updateById(p);
} }

View File

@@ -224,6 +224,13 @@ public interface ProductionPlanService {
List<YieldStatisticsRespVO> getCultivatingYieldInfo(String baseId, String year); List<YieldStatisticsRespVO> getCultivatingYieldInfo(String baseId, String year);
/**
* 获取计划网箱比例
* @param plotId
* @return
*/
String getGridRatio(String plotId);
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor

View File

@@ -477,6 +477,25 @@ public class ProductionPlanServiceImpl implements ProductionPlanService {
return null; return null;
} }
@Override
public String getGridRatio(String plotId) {
QueryWrapper<ProductionPlanDO> x = new QueryWrapper<>();
x.eq("plot_id", plotId);
List<ProductionPlanDO> planDOList = productionPlanMapper.selectList(x);
int sum = planDOList.stream()
.filter(plan -> plan.getPlanStatus() == 2)
.mapToInt(ProductionPlanDO::getPredictedGridNumber)
.sum();
Integer total = planDOList.stream()
.filter(plan -> plan.getPlanStatus() == 2)
.map(ProductionPlanDO::getPlotGridNumber)
.findAny()
.orElse(0);
return sum + "/" + total;
}
@Override @Override
public ProductionPlanGridRespVO getGridForPlan(String planNumber) { public ProductionPlanGridRespVO getGridForPlan(String planNumber) {
List<ProductionPlanUsedGridDO> pugList = productionPlanUsedGridMapperMapper.selectList(ProductionPlanUsedGridDO::getPlanNumber, planNumber); List<ProductionPlanUsedGridDO> pugList = productionPlanUsedGridMapperMapper.selectList(ProductionPlanUsedGridDO::getPlanNumber, planNumber);