diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/modelmanagement/ModelManagementController.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/modelmanagement/ModelManagementController.java index f965158f..02f1128b 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/modelmanagement/ModelManagementController.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/modelmanagement/ModelManagementController.java @@ -56,7 +56,7 @@ public class ModelManagementController { } @PutMapping("/is-release") - @Operation(summary = "更新模型管理") + @Operation(summary = "发布状态") public CommonResult isRelease(@Valid @RequestBody ModelManagementSaveReqVO updateReqVO) { modelManagementService.isRelease(updateReqVO); return success(true); diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/specieslibrary/SpeciesLibraryController.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/specieslibrary/SpeciesLibraryController.java index a4101905..6b869208 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/specieslibrary/SpeciesLibraryController.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/specieslibrary/SpeciesLibraryController.java @@ -90,6 +90,41 @@ public class SpeciesLibraryController { return success(speciesLibraryService.getSpeciesThreeLevelTree()); } + @GetMapping("/two/tree") + @Operation(summary = "物种库二级树") + public CommonResult> getSpeciesTwoLevelTree(SpeciesTwoLevelTreeReqVO req) { + return success(speciesLibraryService.getSpeciesTwoTree(req)); + } + + @GetMapping("/two/tree/get") + @Operation(summary = "物种库二级树-详情") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + public CommonResult getSpeciesTwoLevelTree(@RequestParam String id) { + return speciesLibraryService.getSpeciesTwoTreeForOne(id); + } + + @PostMapping("/two/tree") + @Operation(summary = "物种库二级树-新增") + public CommonResult createSpeciesTwoLevelTree(@RequestBody SpeciesTwoLevelTreeSaveReqVO req) { + boolean flag = speciesLibraryService.createSpeciesTwoLevelTree(req); + return success(flag); + } + + @PutMapping("/two/tree") + @Operation(summary = "物种库二级树-修改") + public CommonResult updateSpeciesTwoLevelTree(@RequestBody SpeciesTwoLevelTreeSaveReqVO req) { + boolean flag = speciesLibraryService.updateSpeciesTwoLevelTree(req); + return success(flag); + } + + @DeleteMapping("/two/tree") + @Operation(summary = "物种库二级树-删除") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + public CommonResult deleteSpeciesTwoLevelTree(@RequestParam String id) { + boolean flag = speciesLibraryService.deleteSpeciesTwoLevelTree(id); + return success(flag); + } + @GetMapping("/tree-model") @Operation(summary = "物种库三级树-模型(speciesName1->speciesName2->cultivarName->modelName)") public CommonResult> getSpeciesAndModelTree() { diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/specieslibrary/vo/SpeciesTwoLevelTreeDetailsRespVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/specieslibrary/vo/SpeciesTwoLevelTreeDetailsRespVO.java new file mode 100644 index 00000000..2ddf00f2 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/specieslibrary/vo/SpeciesTwoLevelTreeDetailsRespVO.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.farm.controller.admin.specieslibrary.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @description: TODO + * @author: binda + * @date: 2025/9/6 16:48 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SpeciesTwoLevelTreeDetailsRespVO { + + @Schema(description = "排序ID") + private int sort; + @Schema(description = "节点ID(叶子为品种ID,非叶子为空)") + private Long id; + @Schema(description = "父节点ID") + private Long parentId; + @Schema(description = "节点名称") + private String name; + @Schema(description = "使用状态 (1: 启用; 0:停用)") + private Integer useStatus; + @Schema(description = "逻辑删除 (1: 已删除; 0:未删除)") + private Integer deleted; + +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/specieslibrary/vo/SpeciesTwoLevelTreeReqVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/specieslibrary/vo/SpeciesTwoLevelTreeReqVO.java new file mode 100644 index 00000000..8db94245 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/specieslibrary/vo/SpeciesTwoLevelTreeReqVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.farm.controller.admin.specieslibrary.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @description: 二级物种菜单 请求实体 + * @author: binda + * @date: 2025/9/6 17:32 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SpeciesTwoLevelTreeReqVO { + @Schema(description = "节点名称") + private String name; + @Schema(description = "使用状态 (1: 启用; 0:停用)") + private Integer useStatus; +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/specieslibrary/vo/SpeciesTwoLevelTreeRespVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/specieslibrary/vo/SpeciesTwoLevelTreeRespVO.java new file mode 100644 index 00000000..8a3f8a96 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/specieslibrary/vo/SpeciesTwoLevelTreeRespVO.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.farm.controller.admin.specieslibrary.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @description: 二级物种菜单 相应实体 + * @author: binda + * @date: 2025/9/6 14:58 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SpeciesTwoLevelTreeRespVO { + + @Schema(description = "排序ID") + private int sort; + @Schema(description = "节点ID(叶子为品种ID,非叶子为空)") + private Long id; + @Schema(description = "父节点ID") + private Long parentId; + @Schema(description = "节点名称") + private String name; + @Schema(description = "使用状态 (1: 启用; 0:停用)") + private Integer useStatus; + @Schema(description = "子节点") + private List children; + +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/specieslibrary/vo/SpeciesTwoLevelTreeSaveReqVO.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/specieslibrary/vo/SpeciesTwoLevelTreeSaveReqVO.java new file mode 100644 index 00000000..867c9c36 --- /dev/null +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/specieslibrary/vo/SpeciesTwoLevelTreeSaveReqVO.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.farm.controller.admin.specieslibrary.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @description: TODO + * @author: binda + * @date: 2025/9/6 15:30 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SpeciesTwoLevelTreeSaveReqVO { + + @Schema(description = "排序ID") + private int sort; + @Schema(description = "节点ID(叶子为品种ID,非叶子为空)") + private Long id; + @Schema(description = "父节点ID") + private Long parentId; + @Schema(description = "节点名称") + private String name; + @Schema(description = "使用状态 (1: 启用; 0:停用)") + private Integer useStatus; + @Schema(description = "逻辑删除 (1: 已删除; 0:未删除)") + private Integer deleted; + +} diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/enums/ErrorCodeConstants.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/enums/ErrorCodeConstants.java index e58f82e6..c3058ff4 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/enums/ErrorCodeConstants.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/enums/ErrorCodeConstants.java @@ -128,5 +128,8 @@ public interface ErrorCodeConstants { ErrorCode GENERAL_DISASTER_NAME_NON_UNIQUE_ERROR = new ErrorCode(1_050_039_000, "一般灾害名称重复"); ErrorCode WEATHER_DISASTER_NAME_NON_UNIQUE_ERROR = new ErrorCode(1_050_040_000, "气象灾害名称重复"); + ErrorCode DUPLICATE_SPECIES_NAMES_ERROR = new ErrorCode(1_050_041_000, "气象灾害名称重复"); + ErrorCode NOT_EXIST = new ErrorCode(1_050_042_000, "节点不存在或已被删除"); + } \ No newline at end of file diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/cropFarmingCenter/CropFarmingCenterServiceImpl.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/cropFarmingCenter/CropFarmingCenterServiceImpl.java index 8aeda857..f6884da2 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/cropFarmingCenter/CropFarmingCenterServiceImpl.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/cropFarmingCenter/CropFarmingCenterServiceImpl.java @@ -503,15 +503,17 @@ public class CropFarmingCenterServiceImpl implements CropFarmingCenterService { public BasePlanOverviewRespVO getBaseOverview(String baseId) { LoginUser user = getLoginUser(); Long tenantId = user.getTenantId(); - BigDecimal totalArea = baseInfoMapper.getTotalBaseArea(baseId,tenantId); - - if (totalArea != null) { - ProductionPlanRespVO.PlanOverview source = productionPlanMapper.getPlanOverview(baseId); - source.setTotalArea(totalArea); - return BeanUtils.toBean(source, BasePlanOverviewRespVO.class); - } else { + BigDecimal totalArea = baseInfoMapper.getTotalBaseArea(baseId, tenantId); + if (totalArea == null) { return null; } + + ProductionPlanRespVO.PlanOverview source = productionPlanMapper.getPlanOverview(baseId); + return new BasePlanOverviewRespVO().setTotalArea(totalArea) + .setPlanCount(source.getPlanCount()) + .setPlanCompletedCount(source.getPlanCompletedCount()) + .setPlanInProgressCount(source.getPlanInProgressCount()) + .setPlanOverdueCount(source.getPlanOverdueCount()); } @Override diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/environmentindexconfig/EnvironmentIndexConfigServiceImpl.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/environmentindexconfig/EnvironmentIndexConfigServiceImpl.java index 019db077..0015f145 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/environmentindexconfig/EnvironmentIndexConfigServiceImpl.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/environmentindexconfig/EnvironmentIndexConfigServiceImpl.java @@ -1,28 +1,24 @@ package cn.iocoder.yudao.module.farm.service.environmentindexconfig; -import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.IdUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; 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.environmentindexconfig.vo.EnvironmentIndexConfigPageReqVO; import cn.iocoder.yudao.module.farm.controller.admin.environmentindexconfig.vo.EnvironmentIndexConfigSaveReqVO; +import cn.iocoder.yudao.module.farm.dal.dataobject.specieslibrary.SpeciesLibraryDO; +import cn.iocoder.yudao.module.farm.dal.mysql.specieslibrary.SpeciesLibraryMapper; import org.springframework.stereotype.Service; import jakarta.annotation.Resource; import org.springframework.validation.annotation.Validated; -import org.springframework.transaction.annotation.Transactional; import cn.iocoder.yudao.module.farm.dal.dataobject.environmentindexconfig.EnvironmentIndexConfigDO; -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.farm.dal.mysql.environmentindexconfig.EnvironmentIndexConfigMapper; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUser; import static cn.iocoder.yudao.module.farm.enums.ErrorCodeConstants.ENVIRONMENT_INDEX_CONFIG_NOT_EXISTS; @@ -37,14 +33,20 @@ public class EnvironmentIndexConfigServiceImpl implements EnvironmentIndexConfig @Resource private EnvironmentIndexConfigMapper environmentIndexConfigMapper; + @Resource + private SpeciesLibraryMapper speciesLibraryMapper; + @Override public String createEnvironmentIndexConfig(EnvironmentIndexConfigSaveReqVO createReqVO) { LoginUser user = getLoginUser(); + // 物种类型 + SpeciesLibraryDO speciesLibraryDO = speciesLibraryMapper.selectOne("cultivar_name", createReqVO.getCultivarName()); // 插入 EnvironmentIndexConfigDO environmentIndexConfig = BeanUtils.toBean(createReqVO, EnvironmentIndexConfigDO.class); environmentIndexConfig.setId(IdUtil.fastUUID()); environmentIndexConfig.setTenantId(String.valueOf(user.getTenantId())); + environmentIndexConfig.setCultivarName(speciesLibraryDO.getSpeciesName()); environmentIndexConfigMapper.insert(environmentIndexConfig); // 返回 diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/specieslibrary/SpeciesLibraryService.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/specieslibrary/SpeciesLibraryService.java index 6f547bc7..b0d1d31c 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/specieslibrary/SpeciesLibraryService.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/specieslibrary/SpeciesLibraryService.java @@ -1,10 +1,8 @@ package cn.iocoder.yudao.module.farm.service.specieslibrary; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.farm.controller.admin.specieslibrary.vo.SpeciesAndModelTreeRespVO; -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.specieslibrary.vo.*; import cn.iocoder.yudao.module.farm.dal.dataobject.specieslibrary.SpeciesLibraryDO; import jakarta.validation.Valid; @@ -74,6 +72,7 @@ public interface SpeciesLibraryService { List getSpeciesTwoLevelTree(); + List getSpeciesTwoTree(SpeciesTwoLevelTreeReqVO req); /** * 物种与模型 * @return @@ -86,4 +85,12 @@ public interface SpeciesLibraryService { * @return */ Integer getCropTotalCount(String tenantId); + + boolean createSpeciesTwoLevelTree(SpeciesTwoLevelTreeSaveReqVO req); + + boolean updateSpeciesTwoLevelTree(SpeciesTwoLevelTreeSaveReqVO req); + + boolean deleteSpeciesTwoLevelTree(String id); + + CommonResult getSpeciesTwoTreeForOne(String id); } \ No newline at end of file diff --git a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/specieslibrary/SpeciesLibraryServiceImpl.java b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/specieslibrary/SpeciesLibraryServiceImpl.java index ff16769d..53165922 100644 --- a/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/specieslibrary/SpeciesLibraryServiceImpl.java +++ b/yudao-module-farm/src/main/java/cn/iocoder/yudao/module/farm/service/specieslibrary/SpeciesLibraryServiceImpl.java @@ -1,14 +1,13 @@ package cn.iocoder.yudao.module.farm.service.specieslibrary; import cn.hutool.core.util.IdUtil; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.security.core.LoginUser; import cn.iocoder.yudao.module.farm.controller.admin.dict.vo.sys.SysDictReqVO; -import cn.iocoder.yudao.module.farm.controller.admin.specieslibrary.vo.SpeciesAndModelTreeRespVO; -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.specieslibrary.vo.*; 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; @@ -16,29 +15,27 @@ import cn.iocoder.yudao.module.farm.dal.dataobject.twodict.TwoDictDO; import cn.iocoder.yudao.module.farm.dal.mysql.modelmanagement.ModelManagementMapper; import cn.iocoder.yudao.module.farm.dal.mysql.specieslibrary.SpeciesLibraryMapper; import cn.iocoder.yudao.module.farm.dal.mysql.sysDict.SysDictDO; +import cn.iocoder.yudao.module.farm.dal.mysql.twodict.TwoDictMapper; 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 com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import jakarta.annotation.Resource; import org.apache.commons.lang3.ObjectUtils; 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.*; 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.DICT_TYPE_CODE_3; -import static cn.iocoder.yudao.module.farm.enums.ErrorCodeConstants.SPECIES_LIBRARY_NOT_EXISTS; +import static cn.iocoder.yudao.module.farm.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.farm.utils.StrHelperUtil.generate; -import static com.baomidou.mybatisplus.core.toolkit.Wrappers.lambdaQuery; /** * 物种库维护 Service 实现类 @@ -57,6 +54,8 @@ public class SpeciesLibraryServiceImpl implements SpeciesLibraryService { private ModelManagementMapper modelManagementMapper; @Resource private TwoDictService twoDictService; + @Resource + private TwoDictMapper twoDictMapper; @Override public String createSpeciesLibrary(SpeciesLibrarySaveReqVO createReqVO) { @@ -376,6 +375,129 @@ public class SpeciesLibraryServiceImpl implements SpeciesLibraryService { return ""; } + @Override + public List getSpeciesTwoTree(SpeciesTwoLevelTreeReqVO req) { + + LambdaQueryWrapperX wrapperX = new LambdaQueryWrapperX<>(); + wrapperX.eq(TwoDictDO::getTenantId, String.valueOf(getLoginUser().getTenantId())); + wrapperX.eqIfPresent(TwoDictDO::getStatus,req.getUseStatus()); + wrapperX.orderByDesc(TwoDictDO::getId); + List allDicts = twoDictMapper.selectList(wrapperX); + + // 查找匹配的节点 + List matchedDicts = allDicts.stream().filter(dict -> dict.getName().equals(req.getName())).collect(Collectors.toList()); + if (matchedDicts.isEmpty()) { + return Collections.emptyList(); + } + + // 构建完整的树结构用于查询 + List fullTree = buildTree(allDicts); + + Set resultIds = new HashSet<>(); + List result = new ArrayList<>(); + + for (TwoDictDO matchedDict : matchedDicts) { + if (matchedDict.getParentId() == null) { + // 查询的是父级:找到该父级节点及其所有子节点 + SpeciesTwoLevelTreeRespVO parentNode = findNodeById(fullTree, matchedDict.getId()); + if (parentNode != null) { + result.add(parentNode); + } + } else { + // 查询的是子类:找到该子类的父级节点 + SpeciesTwoLevelTreeRespVO parentNode = findParentNode(fullTree, matchedDict.getParentId()); + if (parentNode != null && !resultIds.contains(parentNode.getId())) { + resultIds.add(parentNode.getId()); + result.add(parentNode); + } + } + } + + return result; + } + + /** + * 根据ID在树中查找节点 + */ + private SpeciesTwoLevelTreeRespVO findNodeById(List tree, Long id) { + for (SpeciesTwoLevelTreeRespVO node : tree) { + if (node.getId().equals(id)) { + return node; + } + if (node.getChildren() != null && !node.getChildren().isEmpty()) { + SpeciesTwoLevelTreeRespVO found = findNodeById(node.getChildren(), id); + if (found != null) { + return found; + } + } + } + return null; + } + + /** + * 根据父级ID在树中查找父节点 + */ + private SpeciesTwoLevelTreeRespVO findParentNode(List tree, Long parentId) { + for (SpeciesTwoLevelTreeRespVO node : tree) { + if (node.getId().equals(parentId)) { + return node; + } + if (node.getChildren() != null && !node.getChildren().isEmpty()) { + SpeciesTwoLevelTreeRespVO found = findParentNode(node.getChildren(), parentId); + if (found != null) { + return found; + } + } + } + return null; + } + + /** + * 构建完整的树形结构(之前的实现) + */ + private List buildTree(List allDicts) { + Map> childrenMap = allDicts.stream() + .filter(dict -> dict.getParentId() != null) + .collect(Collectors.groupingBy(TwoDictDO::getParentId)); + + return allDicts.stream() + .filter(dict -> dict.getParentId() == null) + .sorted(Comparator.comparing(TwoDictDO::getId)) + .map(parent -> buildNode(parent, childrenMap, 1)) + .collect(Collectors.toList()); + } + + private SpeciesTwoLevelTreeRespVO buildNode(TwoDictDO dict, Map> childrenMap, int sort) { + SpeciesTwoLevelTreeRespVO vo = convertToVO(dict); + vo.setSort(sort); + + List children = childrenMap.get(dict.getId()); + if (children != null) { + List sortedChildren = children.stream() + .sorted(Comparator.comparing(TwoDictDO::getId)) + .collect(Collectors.toList()); + + List childNodes = new ArrayList<>(); + for (int i = 0; i < sortedChildren.size(); i++) { + childNodes.add(buildNode(sortedChildren.get(i), childrenMap, i + 1)); + } + vo.setChildren(childNodes); + } else { + vo.setChildren(new ArrayList<>()); + } + + return vo; + } + + private SpeciesTwoLevelTreeRespVO convertToVO(TwoDictDO dict) { + SpeciesTwoLevelTreeRespVO vo = new SpeciesTwoLevelTreeRespVO(); + vo.setId(dict.getId()); + vo.setParentId(dict.getParentId() != null ? dict.getParentId() : 0L); + vo.setName(dict.getName()); + vo.setUseStatus(dict.getStatus() ? 1 :0); + return vo; + } + @Override public List getSpeciesAndModelTree() { List sourceTree = this.getSpeciesThreeLevelTree(); @@ -425,4 +547,118 @@ public class SpeciesLibraryServiceImpl implements SpeciesLibraryService { } return 0; } + + @Override + public boolean createSpeciesTwoLevelTree(SpeciesTwoLevelTreeSaveReqVO req) { + try { + TwoDictDO one = twoDictMapper.selectOne("name", req.getName()); + if (one != null) { + throw exception(DUPLICATE_SPECIES_NAMES_ERROR); + } + + TwoDictDO twoDictDO = BeanUtils.toBean(req, TwoDictDO.class); + twoDictDO.setTenantId(String.valueOf(getLoginUser().getTenantId())); + twoDictMapper.insert(twoDictDO); + return true; + } catch (Exception e) { + return false; + } + } + + @Override + public boolean updateSpeciesTwoLevelTree(SpeciesTwoLevelTreeSaveReqVO req) { + try { + Long id = req.getId(); + // 1. 首先检查当前节点是否存在 + TwoDictDO current = twoDictMapper.selectById(req.getId()); + if (current == null || current.getDeleted()) { + throw exception(NOT_EXIST); + } + + // 2. 判断是否为父节点(是否有子节点) + boolean hasChildren = hasChildren(id); + + if (hasChildren) { + // 3. 如果是父节点,更新自身及其所有子节点 + updateSelfAndChildren(id, req.getUseStatus() == 1); + } else { + // 4. 如果是子节点,只更新自身 + this.updateSelf(id,req.getName(),req.getUseStatus() ==1); + } + return true; + } catch (Exception e) { + return false; + } + } + + private boolean hasChildren(Long id) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("parent_id", id) + .eq("deleted", 0); + return twoDictMapper.selectCount(queryWrapper) > 0; + } + + /** + * 更新自身节点 + */ + private void updateSelf(Long id, String name, boolean status) { + TwoDictDO updateEntity = new TwoDictDO(); + updateEntity.setId(id); + updateEntity.setStatus(status); + updateEntity.setName(name); + twoDictMapper.updateById(updateEntity); + } + + /** + * 更新自身及其所有子节点(递归更新) + */ + private void updateSelfAndChildren(Long id,boolean status) { + // 先更新自身 + updateSelf(id,null,status); + // 递归更新所有子节点 + updateChildrenRecursively(id, status); + } + + /** + * 递归更新所有子节点 + */ + private void updateChildrenRecursively(Long parentId, boolean useStatus) { + // 查询所有直接子节点 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("parent_id", parentId) + .eq("deleted", 0); + List children = twoDictMapper.selectList(queryWrapper); + + for (TwoDictDO child : children) { + // 更新当前子节点 + updateSelf(child.getId(),null, useStatus); + + // 递归更新当前子节点的子节点(如果有) + if (hasChildren(child.getId())) { + updateChildrenRecursively(child.getId(), useStatus); + } + } + } + + @Override + public boolean deleteSpeciesTwoLevelTree(String id) { + try { + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.eq(TwoDictDO::getId, id) + .eq(TwoDictDO::getDeleted, false) // 只更新未删除的记录 + .set(TwoDictDO::getDeleted, true); // 设置删除状态 + twoDictMapper.update(updateWrapper); + return true; + } catch (Exception e) { + return false; + } + } + + @Override + public CommonResult getSpeciesTwoTreeForOne(String id) { + TwoDictDO one = twoDictMapper.selectOne(TwoDictDO::getId, id); + SpeciesTwoLevelTreeDetailsRespVO res = BeanUtils.toBean(one, SpeciesTwoLevelTreeDetailsRespVO.class); + res.setUseStatus(one.getStatus() ? 1 : 0); + return CommonResult.success(res); + } } \ No newline at end of file