farm模块-二级字典抽取
This commit is contained in:
@@ -26,6 +26,8 @@ import cn.iocoder.yudao.module.farm.controller.admin.inputlibrary.vo.InputLibrar
|
||||
import cn.iocoder.yudao.module.farm.controller.admin.specieslibrary.vo.SpeciesLibraryPageReqVO;
|
||||
import cn.iocoder.yudao.module.farm.controller.admin.specieslibrary.vo.SpeciesLibraryRespVO;
|
||||
import cn.iocoder.yudao.module.farm.controller.admin.specieslibrary.vo.SpeciesLibrarySaveReqVO;
|
||||
import cn.iocoder.yudao.module.farm.controller.admin.specieslibrary.vo.SpeciesThreeLevelTreeRespVO;
|
||||
import cn.iocoder.yudao.module.farm.controller.admin.twodict.vo.TwoDictTreeRespVO;
|
||||
import cn.iocoder.yudao.module.farm.dal.dataobject.disasterdata.DisasterDataDO;
|
||||
import cn.iocoder.yudao.module.farm.dal.dataobject.farmingnamemaintenance.FarmingNameMaintenanceDO;
|
||||
import cn.iocoder.yudao.module.farm.dal.dataobject.farmingtypemaintenance.FarmingTypeMaintenanceDO;
|
||||
@@ -41,6 +43,7 @@ import cn.iocoder.yudao.module.farm.service.productionplan.ProductionPlanService
|
||||
import cn.iocoder.yudao.module.farm.service.speciesclassifylibrary.SpeciesClassifyLibraryService;
|
||||
import cn.iocoder.yudao.module.farm.service.specieslibrary.SpeciesLibraryService;
|
||||
import cn.iocoder.yudao.module.farm.service.sysDict.SysDictService;
|
||||
import cn.iocoder.yudao.module.farm.service.twodict.TwoDictService;
|
||||
import cn.iocoder.yudao.module.farm.utils.TreeStructureUtil;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@@ -82,8 +85,9 @@ public class DictController {
|
||||
private final ProductionPlanService productionPlanService;
|
||||
private final BaseInfoService baseInfoService;
|
||||
private final FarmingTypeMaintenanceService farmingTypeMaintenanceService;
|
||||
private final TwoDictService twoDictService;
|
||||
|
||||
public DictController(SpeciesLibraryService speciesLibraryService, SpeciesClassifyLibraryService speciesClassifyLibraryService, InputLibraryService inputLibraryService, DisasterDataService disasterDataService, SysDictService sysDictService, ProductionPlanService productionPlanService, BaseInfoService baseInfoService, FarmingTypeMaintenanceService farmingTypeMaintenanceService) {
|
||||
public DictController(SpeciesLibraryService speciesLibraryService, SpeciesClassifyLibraryService speciesClassifyLibraryService, InputLibraryService inputLibraryService, DisasterDataService disasterDataService, SysDictService sysDictService, ProductionPlanService productionPlanService, BaseInfoService baseInfoService, FarmingTypeMaintenanceService farmingTypeMaintenanceService, TwoDictService twoDictService) {
|
||||
this.speciesLibraryService = speciesLibraryService;
|
||||
this.speciesClassifyLibraryService = speciesClassifyLibraryService;
|
||||
this.inputLibraryService = inputLibraryService;
|
||||
@@ -92,6 +96,7 @@ public class DictController {
|
||||
this.productionPlanService = productionPlanService;
|
||||
this.baseInfoService = baseInfoService;
|
||||
this.farmingTypeMaintenanceService = farmingTypeMaintenanceService;
|
||||
this.twoDictService = twoDictService;
|
||||
}
|
||||
|
||||
// 农事类型
|
||||
@@ -290,14 +295,9 @@ public class DictController {
|
||||
|
||||
@Operation(summary = "字典数据维护-下拉框列表-三级物种类别")
|
||||
@GetMapping("/list/three-library")
|
||||
public CommonResult<List<SpeciesClassifyLibraryRespVO>> getTreeLibraryList() {
|
||||
public CommonResult<List<SpeciesThreeLevelTreeRespVO>> getTreeLibraryList() {
|
||||
try {
|
||||
// 获取物种生命周期
|
||||
Map<String, String> lifeCycMap = speciesLibraryService.getSpeciesLibraryForLifeCycMap();
|
||||
// 获取物种类别字典数据
|
||||
List<SysDictDO> dictList = sysDictService.getByTypeCode(CommonConstants.DICT_TYPE_CODE_3);
|
||||
// 使用工具类构建树结构
|
||||
List<SpeciesClassifyLibraryRespVO> threeList = TreeStructureUtil.buildSpeciesClassifyTree(dictList,lifeCycMap);
|
||||
List<SpeciesThreeLevelTreeRespVO> threeList = speciesLibraryService.getSpeciesThreeLevelTree();
|
||||
return success(threeList);
|
||||
} catch (Exception e) {
|
||||
log.error("获取三级物种类别列表失败", e);
|
||||
|
||||
@@ -135,7 +135,7 @@ public class ModelManagementServiceImpl implements ModelManagementService {
|
||||
newModelCase.setType(CommonConstants.MODEL_TYPE_2); // 设置为引用案例类型
|
||||
newModelCase.setTaskId(taskId);
|
||||
newModelCase.setModelName(modelManagementDO.getModelName());
|
||||
|
||||
newModelCase.setQuoteCount(0);
|
||||
// 3. 保存新的模型引用案例
|
||||
modelManagementMapper.insert(newModelCase);
|
||||
|
||||
@@ -202,8 +202,8 @@ public class ModelManagementServiceImpl implements ModelManagementService {
|
||||
if (existing == null) {
|
||||
return;
|
||||
}
|
||||
SysDictThreeLvRespVO dictByField3Code = sysDictService.getDictByField3Code(existing.getSpeciesId());
|
||||
existing.setSpeciesName(dictByField3Code.getNames());
|
||||
SpeciesLibraryDO speciesLibrary = speciesLibraryService.getSpeciesLibrary(updateReqVO.getSpeciesId());
|
||||
existing.setSpeciesName(speciesLibrary.getSpeciesName() + "/" + speciesLibrary.getCultivarName());
|
||||
// 基础字段:仅当请求中非空时才覆盖
|
||||
if (updateReqVO.getModelName() != null) existing.setModelName(updateReqVO.getModelName());
|
||||
if (updateReqVO.getSpeciesId() != null) existing.setSpeciesId(updateReqVO.getSpeciesId());
|
||||
|
||||
@@ -10,6 +10,7 @@ import cn.iocoder.yudao.module.farm.controller.admin.specieslibrary.vo.SpeciesAn
|
||||
import cn.iocoder.yudao.module.farm.controller.admin.specieslibrary.vo.SpeciesLibraryPageReqVO;
|
||||
import cn.iocoder.yudao.module.farm.controller.admin.specieslibrary.vo.SpeciesLibrarySaveReqVO;
|
||||
import cn.iocoder.yudao.module.farm.controller.admin.specieslibrary.vo.SpeciesThreeLevelTreeRespVO;
|
||||
import cn.iocoder.yudao.module.farm.controller.admin.twodict.vo.TwoDictTreeRespVO;
|
||||
import cn.iocoder.yudao.module.farm.dal.dataobject.modelmanagement.ModelManagementDO;
|
||||
import cn.iocoder.yudao.module.farm.dal.dataobject.specieslibrary.SpeciesLibraryDO;
|
||||
import cn.iocoder.yudao.module.farm.dal.mysql.modelmanagement.ModelManagementMapper;
|
||||
@@ -17,6 +18,7 @@ import cn.iocoder.yudao.module.farm.dal.mysql.specieslibrary.SpeciesLibraryMappe
|
||||
import cn.iocoder.yudao.module.farm.dal.mysql.sysDict.SysDictDO;
|
||||
import cn.iocoder.yudao.module.farm.enums.CommonConstants;
|
||||
import cn.iocoder.yudao.module.farm.service.sysDict.SysDictService;
|
||||
import cn.iocoder.yudao.module.farm.service.twodict.TwoDictService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
@@ -24,8 +26,10 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
@@ -49,7 +53,8 @@ public class SpeciesLibraryServiceImpl implements SpeciesLibraryService {
|
||||
private SysDictService sysDictService;
|
||||
@Resource
|
||||
private ModelManagementMapper modelManagementMapper;
|
||||
|
||||
@Resource
|
||||
private TwoDictService twoDictService;
|
||||
|
||||
@Override
|
||||
public String createSpeciesLibrary(SpeciesLibrarySaveReqVO createReqVO) {
|
||||
@@ -233,30 +238,71 @@ public class SpeciesLibraryServiceImpl implements SpeciesLibraryService {
|
||||
|
||||
@Override
|
||||
public List<SpeciesThreeLevelTreeRespVO> getSpeciesThreeLevelTree() {
|
||||
List<SpeciesLibraryDO> list = speciesLibraryMapper.selectList();
|
||||
Map<String, Map<String, List<SpeciesLibraryDO>>> grouped = list.stream().collect(Collectors.groupingBy(
|
||||
e -> splitSpeciesName(e.getSpeciesName(), 0),
|
||||
Collectors.groupingBy(e -> splitSpeciesName(e.getSpeciesName(), 1))
|
||||
));
|
||||
List<TwoDictTreeRespVO> dictTree = twoDictService.getTwoDictTree();
|
||||
if (dictTree == null || dictTree.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
return grouped.entrySet().stream().map(level1 -> {
|
||||
SpeciesThreeLevelTreeRespVO n1 = new SpeciesThreeLevelTreeRespVO();
|
||||
n1.setName(level1.getKey());
|
||||
List<SpeciesThreeLevelTreeRespVO> childrenLv2 = level1.getValue().entrySet().stream().map(level2 -> {
|
||||
SpeciesThreeLevelTreeRespVO n2 = new SpeciesThreeLevelTreeRespVO();
|
||||
n2.setName(level2.getKey());
|
||||
List<SpeciesThreeLevelTreeRespVO> childrenLv3 = level2.getValue().stream().map(leaf -> {
|
||||
SpeciesThreeLevelTreeRespVO n3 = new SpeciesThreeLevelTreeRespVO();
|
||||
n3.setName(leaf.getCultivarName());
|
||||
n3.setId(leaf.getId());
|
||||
return n3;
|
||||
}).collect(Collectors.toList());
|
||||
n2.setChildren(childrenLv3);
|
||||
return n2;
|
||||
}).collect(Collectors.toList());
|
||||
n1.setChildren(childrenLv2);
|
||||
return n1;
|
||||
}).collect(Collectors.toList());
|
||||
// 1级:parentId == null 的节点
|
||||
List<TwoDictTreeRespVO> level1Nodes = dictTree.stream()
|
||||
.filter(n -> n != null && n.getParentId() == null)
|
||||
.sorted(java.util.Comparator.comparing(TwoDictTreeRespVO::getName, java.util.Comparator.nullsLast(String::compareTo)))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 收集所有二级分类ID,一次性查询物种,避免 N+1
|
||||
List<Long> level2Ids = dictTree.stream()
|
||||
.filter(n -> n != null && n.getParentId() != null) // 非根即二级(在当前两级分类中)
|
||||
.map(TwoDictTreeRespVO::getId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Map<String, List<SpeciesLibraryDO>> categoryToSpeciesMap;
|
||||
if (level2Ids.isEmpty()) {
|
||||
categoryToSpeciesMap = java.util.Collections.emptyMap();
|
||||
} else {
|
||||
level2Ids.forEach(level2Id -> {
|
||||
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
List<SpeciesThreeLevelTreeRespVO> result = new ArrayList<>();
|
||||
for (TwoDictTreeRespVO lvl1 : level1Nodes) {
|
||||
SpeciesThreeLevelTreeRespVO lvl1Vo = new SpeciesThreeLevelTreeRespVO();
|
||||
lvl1Vo.setName(lvl1.getName());
|
||||
lvl1Vo.setId(lvl1.getId().toString());
|
||||
List<SpeciesThreeLevelTreeRespVO> lvl2Vos = new ArrayList<>();
|
||||
if (lvl1.getChildren() != null && !lvl1.getChildren().isEmpty()) {
|
||||
// 二级按名称排序
|
||||
List<TwoDictTreeRespVO> lvl2Children = new ArrayList<>(lvl1.getChildren());
|
||||
lvl2Children.sort(java.util.Comparator.comparing(TwoDictTreeRespVO::getName, java.util.Comparator.nullsLast(String::compareTo)));
|
||||
for (TwoDictTreeRespVO lvl2 : lvl2Children) {
|
||||
SpeciesThreeLevelTreeRespVO lvl2Vo = new SpeciesThreeLevelTreeRespVO();
|
||||
lvl2Vo.setName(lvl2.getName());
|
||||
lvl2Vo.setId(lvl2.getId().toString());
|
||||
// 三级:该二级分类下的品种(物种库)
|
||||
LambdaQueryWrapper<SpeciesLibraryDO> qwAll = new LambdaQueryWrapper<>();
|
||||
qwAll.eq(SpeciesLibraryDO::getCategory, lvl2.getId().toString());
|
||||
qwAll.eq(SpeciesLibraryDO::getTenantId, String.valueOf(getLoginUser().getTenantId()));
|
||||
List<SpeciesLibraryDO> speciesList = speciesLibraryMapper.selectList(qwAll);
|
||||
|
||||
|
||||
List<SpeciesThreeLevelTreeRespVO> lvl3Vos = new ArrayList<>(speciesList.size());
|
||||
for (SpeciesLibraryDO sp : speciesList) {
|
||||
SpeciesThreeLevelTreeRespVO lvl3Vo = new SpeciesThreeLevelTreeRespVO();
|
||||
lvl3Vo.setName(sp.getCultivarName());
|
||||
lvl3Vo.setId(sp.getId());
|
||||
lvl3Vos.add(lvl3Vo);
|
||||
}
|
||||
lvl2Vo.setChildren(lvl3Vos);
|
||||
lvl2Vos.add(lvl2Vo);
|
||||
}
|
||||
}
|
||||
lvl1Vo.setChildren(lvl2Vos);
|
||||
result.add(lvl1Vo);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private String splitSpeciesName(String speciesName, int index) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package cn.iocoder.yudao.module.farm.utils;
|
||||
|
||||
import cn.iocoder.yudao.module.farm.controller.admin.dict.vo.SpeciesClassifyLibraryRespVO;
|
||||
import cn.iocoder.yudao.module.farm.controller.admin.twodict.vo.TwoDictTreeRespVO;
|
||||
import cn.iocoder.yudao.module.farm.dal.mysql.sysDict.SysDictDO;
|
||||
|
||||
import java.util.*;
|
||||
@@ -17,35 +18,72 @@ public class TreeStructureUtil {
|
||||
|
||||
/**
|
||||
* 构建物种类别树结构(支持三级分类)
|
||||
*
|
||||
* @param dictList 字典数据列表
|
||||
* @return 树形结构列表
|
||||
* 说明:该方法基于 TwoDictTreeRespVO 的树(id/name/children)来生成
|
||||
* SpeciesClassifyLibraryRespVO 的三级树。其中:
|
||||
* - 一级:root 节点(parentId == null)
|
||||
* - 二级:root.children
|
||||
* - 三级:child.children,并在第三级填充生命周期(lifeCycle)
|
||||
*/
|
||||
public static List<SpeciesClassifyLibraryRespVO> buildSpeciesClassifyTree(List<SysDictDO> dictList, Map<String, String> lifeCycMap) {
|
||||
public static List<SpeciesClassifyLibraryRespVO> buildSpeciesClassifyTree(List<TwoDictTreeRespVO> dictList,
|
||||
Map<String, String> lifeCycMap) {
|
||||
if (dictList == null || dictList.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
try {
|
||||
// 按一级分类分组
|
||||
Map<String, List<SysDictDO>> groupedByLevel1 = dictList.stream()
|
||||
.filter(dict -> isValidLevel1Node(dict))
|
||||
.collect(Collectors.groupingBy(
|
||||
SysDictDO::getField1Code,
|
||||
Collectors.toList()
|
||||
));
|
||||
// 兜底,避免 NPE
|
||||
Map<String, String> safeLifeMap = lifeCycMap != null ? lifeCycMap : Collections.emptyMap();
|
||||
|
||||
// 构建三级树形结构
|
||||
return groupedByLevel1.entrySet().stream()
|
||||
.map(entry -> buildLevel1Node(entry.getKey(), entry.getValue(), dictList,lifeCycMap))
|
||||
// 找到所有根节点(parentId == null)
|
||||
List<TwoDictTreeRespVO> level1Nodes = dictList.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.sorted(Comparator.comparing(SpeciesClassifyLibraryRespVO::getSpeciesClassName))
|
||||
.filter(n -> n.getParentId() == null)
|
||||
.sorted(Comparator.comparing(TwoDictTreeRespVO::getName, Comparator.nullsLast(String::compareTo)))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
} catch (Exception e) {
|
||||
// 记录错误日志,返回空列表
|
||||
return new ArrayList<>();
|
||||
List<SpeciesClassifyLibraryRespVO> result = new ArrayList<>();
|
||||
for (TwoDictTreeRespVO lvl1 : level1Nodes) {
|
||||
if (lvl1.getId() == null || lvl1.getName() == null || lvl1.getName().trim().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
SpeciesClassifyLibraryRespVO lvl1Vo = new SpeciesClassifyLibraryRespVO(String.valueOf(lvl1.getId()), lvl1.getName());
|
||||
|
||||
// 二级
|
||||
List<SpeciesClassifyLibraryRespVO> lvl2Vos = new ArrayList<>();
|
||||
List<TwoDictTreeRespVO> lvl2Children = lvl1.getChildren();
|
||||
if (lvl2Children != null && !lvl2Children.isEmpty()) {
|
||||
// 按名称排序,提升观感
|
||||
lvl2Children.sort(Comparator.comparing(TwoDictTreeRespVO::getName, Comparator.nullsLast(String::compareTo)));
|
||||
for (TwoDictTreeRespVO lvl2 : lvl2Children) {
|
||||
if (lvl2 == null || lvl2.getId() == null || lvl2.getName() == null || lvl2.getName().trim().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
SpeciesClassifyLibraryRespVO lvl2Vo = new SpeciesClassifyLibraryRespVO(String.valueOf(lvl2.getId()), lvl2.getName());
|
||||
|
||||
// 三级
|
||||
List<SpeciesClassifyLibraryRespVO> lvl3Vos = new ArrayList<>();
|
||||
List<TwoDictTreeRespVO> lvl3Children = lvl2.getChildren();
|
||||
if (lvl3Children != null && !lvl3Children.isEmpty()) {
|
||||
lvl3Children.sort(Comparator.comparing(TwoDictTreeRespVO::getName, Comparator.nullsLast(String::compareTo)));
|
||||
for (TwoDictTreeRespVO lvl3 : lvl3Children) {
|
||||
if (lvl3 == null || lvl3.getId() == null || lvl3.getName() == null || lvl3.getName().trim().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
// lifeCycMap 的 key 为第三级数据的 ID
|
||||
String lifeCycle = safeLifeMap.get(String.valueOf(lvl3.getId()));
|
||||
lvl3Vos.add(new SpeciesClassifyLibraryRespVO(String.valueOf(lvl3.getId()), lvl3.getName(), lifeCycle));
|
||||
}
|
||||
}
|
||||
lvl2Vo.setChildren(lvl3Vos);
|
||||
lvl2Vos.add(lvl2Vo);
|
||||
}
|
||||
}
|
||||
lvl1Vo.setChildren(lvl2Vos);
|
||||
result.add(lvl1Vo);
|
||||
}
|
||||
|
||||
// 一级按名称排序
|
||||
result.sort(Comparator.comparing(SpeciesClassifyLibraryRespVO::getSpeciesClassName, Comparator.nullsLast(String::compareTo)));
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user