计划管理

This commit is contained in:
潘荣晟
2026-01-16 17:03:26 +08:00
parent 38a6b695f0
commit 05de361806
11 changed files with 875 additions and 1 deletions

View File

@@ -0,0 +1,119 @@
package com.zt.plat.module.base.controller.admin.plandate;
import com.zt.plat.module.base.controller.admin.plandate.vo.PlanDatePageReqVO;
import com.zt.plat.module.base.controller.admin.plandate.vo.PlanDateRespVO;
import com.zt.plat.module.base.controller.admin.plandate.vo.PlanDateSaveReqVO;
import com.zt.plat.module.base.dal.dataobject.plandate.PlanDateDO;
import com.zt.plat.module.base.service.plandate.PlanDateService;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import com.zt.plat.framework.business.interceptor.BusinessControllerMarker;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.constraints.*;
import jakarta.validation.*;
import jakarta.servlet.http.*;
import java.util.*;
import java.io.IOException;
import com.zt.plat.framework.common.pojo.vo.BatchDeleteReqVO;
import com.zt.plat.framework.common.pojo.PageParam;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.util.object.BeanUtils;
import static com.zt.plat.framework.common.pojo.CommonResult.success;
import com.zt.plat.framework.excel.core.util.ExcelUtils;
import com.zt.plat.framework.apilog.core.annotation.ApiAccessLog;
import static com.zt.plat.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - 计划数据")
@RestController
@RequestMapping("/base/plan-date")
@Validated
public class PlanDateController implements BusinessControllerMarker {
@Resource
private PlanDateService planDateService;
@PostMapping("/create")
@Operation(summary = "创建计划数据")
@PreAuthorize("@ss.hasPermission('base:plan-date:create')")
public CommonResult<PlanDateRespVO> createPlanDate(@Valid @RequestBody PlanDateSaveReqVO createReqVO) {
return success(planDateService.createPlanDateWithChildren(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新计划数据")
@PreAuthorize("@ss.hasPermission('base:plan-date:update')")
public CommonResult<Boolean> updatePlanDate(@Valid @RequestBody PlanDateSaveReqVO updateReqVO) {
planDateService.updatePlanDate(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除计划数据")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('base:plan-date:delete')")
public CommonResult<Boolean> deletePlanDate(@RequestParam("id") Long id) {
planDateService.deletePlanDate(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除计划数据")
@PreAuthorize("@ss.hasPermission('base:plan-date:delete')")
public CommonResult<Boolean> deletePlanDateList(@RequestBody BatchDeleteReqVO req) {
planDateService.deletePlanDateListByIds(req.getIds());
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得计划数据")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('base:plan-date:query')")
public CommonResult<PlanDateRespVO> getPlanDate(@RequestParam("id") Long id) {
PlanDateDO planDate = planDateService.getPlanDate(id);
return success(BeanUtils.toBean(planDate, PlanDateRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得计划数据分页")
@PreAuthorize("@ss.hasPermission('base:plan-date:query')")
public CommonResult<PageResult<PlanDateRespVO>> getPlanDatePage(@Valid PlanDatePageReqVO pageReqVO) {
PageResult<PlanDateDO> pageResult = planDateService.getPlanDatePage(pageReqVO);
return success(BeanUtils.toBean(pageResult, PlanDateRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出计划数据 Excel")
@PreAuthorize("@ss.hasPermission('base:plan-date:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportPlanDateExcel(@Valid PlanDatePageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<PlanDateDO> list = planDateService.getPlanDatePage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "计划数据.xls", "数据", PlanDateRespVO.class,
BeanUtils.toBean(list, PlanDateRespVO.class));
}
@GetMapping("/tree/list-all")
@Operation(summary = "查询所有计划数据(树形结构)")
@PreAuthorize("@ss.hasPermission('base:plan-date:query')")
public List<PlanDateRespVO> listAllPlanDateTree() {
return planDateService.listPlanDateTree();
}
}

View File

@@ -0,0 +1,78 @@
package com.zt.plat.module.base.controller.admin.plandate.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import com.zt.plat.framework.common.pojo.PageParam;
import java.math.BigDecimal;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static com.zt.plat.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 计划数据分页 Request VO")
@Data
public class PlanDatePageReqVO extends PageParam {
@Schema(description = "计划名称", example = "王五")
private String planName;
@Schema(description = "计划编码")
private String planCoding;
@Schema(description = "父级ID", example = "6059")
private Long parentId;
@Schema(description = "年份")
private String year;
@Schema(description = "初始值")
private BigDecimal initialValue;
@Schema(description = "平均值")
private BigDecimal averageValue;
@Schema(description = "合计值")
private BigDecimal sumValue;
@Schema(description = "一月")
private BigDecimal january;
@Schema(description = "二月")
private BigDecimal february;
@Schema(description = "三月")
private BigDecimal march;
@Schema(description = "四月")
private BigDecimal april;
@Schema(description = "五月")
private BigDecimal may;
@Schema(description = "六月")
private BigDecimal june;
@Schema(description = "七月")
private BigDecimal july;
@Schema(description = "八月")
private BigDecimal august;
@Schema(description = "九月")
private BigDecimal september;
@Schema(description = "十月")
private BigDecimal october;
@Schema(description = "十一月")
private BigDecimal november;
@Schema(description = "十二月")
private BigDecimal december;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@@ -0,0 +1,103 @@
package com.zt.plat.module.base.controller.admin.plandate.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import java.math.BigDecimal;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 计划数据 Response VO")
@Data
@ExcelIgnoreUnannotated
public class PlanDateRespVO {
@Schema(description = "主键 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "10584")
@ExcelProperty("主键 ID")
private Long id;
@Schema(description = "计划名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
@ExcelProperty("计划名称")
private String planName;
@Schema(description = "计划编码", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("计划编码")
private String planCoding;
@Schema(description = "父级ID", example = "6059")
@ExcelProperty("父级ID")
private Long parentId;
@Schema(description = "年份")
@ExcelProperty("年份")
private String year;
@Schema(description = "初始值")
@ExcelProperty("初始值")
private BigDecimal initialValue;
@Schema(description = "平均值")
@ExcelProperty("平均值")
private BigDecimal averageValue;
@Schema(description = "合计值")
@ExcelProperty("合计值")
private BigDecimal sumValue;
@Schema(description = "一月")
@ExcelProperty("一月")
private BigDecimal january;
@Schema(description = "二月")
@ExcelProperty("二月")
private BigDecimal february;
@Schema(description = "三月")
@ExcelProperty("三月")
private BigDecimal march;
@Schema(description = "四月")
@ExcelProperty("四月")
private BigDecimal april;
@Schema(description = "五月")
@ExcelProperty("五月")
private BigDecimal may;
@Schema(description = "六月")
@ExcelProperty("六月")
private BigDecimal june;
@Schema(description = "七月")
@ExcelProperty("七月")
private BigDecimal july;
@Schema(description = "八月")
@ExcelProperty("八月")
private BigDecimal august;
@Schema(description = "九月")
@ExcelProperty("九月")
private BigDecimal september;
@Schema(description = "十月")
@ExcelProperty("十月")
private BigDecimal october;
@Schema(description = "十一月")
@ExcelProperty("十一月")
private BigDecimal november;
@Schema(description = "十二月")
@ExcelProperty("十二月")
private BigDecimal december;
@Schema(description = "创建时间")
@ExcelProperty("创建时间")
private LocalDateTime createTime;
@Schema(description = "子节点")
@ExcelProperty("子节点")
private List<PlanDateRespVO> children;
}

View File

@@ -0,0 +1,78 @@
package com.zt.plat.module.base.controller.admin.plandate.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import jakarta.validation.constraints.*;
import java.math.BigDecimal;
@Schema(description = "管理后台 - 计划数据新增/修改 Request VO")
@Data
public class PlanDateSaveReqVO {
@Schema(description = "主键 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "10584")
private Long id;
@Schema(description = "计划名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
@NotEmpty(message = "计划名称不能为空")
private String planName;
@Schema(description = "计划编码", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "计划编码不能为空")
private String planCoding;
@Schema(description = "父级ID", example = "6059")
private Long parentId;
@Schema(description = "年份")
private String year;
@Schema(description = "初始值")
private BigDecimal initialValue;
@Schema(description = "平均值")
private BigDecimal averageValue;
@Schema(description = "合计值")
private BigDecimal sumValue;
@Schema(description = "一月")
private BigDecimal january;
@Schema(description = "二月")
private BigDecimal february;
@Schema(description = "三月")
private BigDecimal march;
@Schema(description = "四月")
private BigDecimal april;
@Schema(description = "五月")
private BigDecimal may;
@Schema(description = "六月")
private BigDecimal june;
@Schema(description = "七月")
private BigDecimal july;
@Schema(description = "八月")
private BigDecimal august;
@Schema(description = "九月")
private BigDecimal september;
@Schema(description = "十月")
private BigDecimal october;
@Schema(description = "十一月")
private BigDecimal november;
@Schema(description = "十二月")
private BigDecimal december;
@Schema(description = "子节点")
private List<PlanDateSaveReqVO> children;
}

View File

@@ -0,0 +1,47 @@
package com.zt.plat.module.base.dal.dao.plandate;
import java.util.*;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.zt.plat.framework.mybatis.core.mapper.BaseMapperX;
import com.zt.plat.module.base.controller.admin.plandate.vo.PlanDatePageReqVO;
import com.zt.plat.module.base.dal.dataobject.plandate.PlanDateDO;
import org.apache.ibatis.annotations.Mapper;
/**
* 计划数据 Mapper
*
* @author 后台管理-1
*/
@Mapper
public interface PlanDateMapper extends BaseMapperX<PlanDateDO> {
default PageResult<PlanDateDO> selectPage(PlanDatePageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<PlanDateDO>()
.likeIfPresent(PlanDateDO::getPlanName, reqVO.getPlanName())
.eqIfPresent(PlanDateDO::getPlanCoding, reqVO.getPlanCoding())
.eqIfPresent(PlanDateDO::getParentId, reqVO.getParentId())
.eqIfPresent(PlanDateDO::getYear, reqVO.getYear())
.eqIfPresent(PlanDateDO::getInitialValue, reqVO.getInitialValue())
.eqIfPresent(PlanDateDO::getAverageValue, reqVO.getAverageValue())
.eqIfPresent(PlanDateDO::getSumValue, reqVO.getSumValue())
.eqIfPresent(PlanDateDO::getJanuary, reqVO.getJanuary())
.eqIfPresent(PlanDateDO::getFebruary, reqVO.getFebruary())
.eqIfPresent(PlanDateDO::getMarch, reqVO.getMarch())
.eqIfPresent(PlanDateDO::getApril, reqVO.getApril())
.eqIfPresent(PlanDateDO::getMay, reqVO.getMay())
.eqIfPresent(PlanDateDO::getJune, reqVO.getJune())
.eqIfPresent(PlanDateDO::getJuly, reqVO.getJuly())
.eqIfPresent(PlanDateDO::getAugust, reqVO.getAugust())
.eqIfPresent(PlanDateDO::getSeptember, reqVO.getSeptember())
.eqIfPresent(PlanDateDO::getOctober, reqVO.getOctober())
.eqIfPresent(PlanDateDO::getNovember, reqVO.getNovember())
.eqIfPresent(PlanDateDO::getDecember, reqVO.getDecember())
.betweenIfPresent(PlanDateDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(PlanDateDO::getId));
}
}

View File

@@ -0,0 +1,145 @@
package com.zt.plat.module.base.dal.dataobject.plandate;
import lombok.*;
import java.util.*;
import java.math.BigDecimal;
import java.math.BigDecimal;
import java.math.BigDecimal;
import java.math.BigDecimal;
import java.math.BigDecimal;
import java.math.BigDecimal;
import java.math.BigDecimal;
import java.math.BigDecimal;
import java.math.BigDecimal;
import java.math.BigDecimal;
import java.math.BigDecimal;
import java.math.BigDecimal;
import java.math.BigDecimal;
import java.math.BigDecimal;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import com.zt.plat.framework.mybatis.core.dataobject.BusinessBaseDO;
/**
* 计划数据 DO
*
* @author 后台管理-1
*/
@TableName("bse_pln_dt")
@KeySequence("bse_pln_dt_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
/**
* 支持业务基类继承isBusiness=true 时继承 BusinessBaseDO否则继承 BaseDO
*/
public class PlanDateDO extends BusinessBaseDO {
/**
* 主键 ID
*/
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/**
* 计划名称
*/
@TableField("PLN_NAME")
private String planName;
/**
* 计划编码
*/
@TableField("PLN_CDG")
private String planCoding;
/**
* 父级ID
*/
@TableField("PRN_ID")
private Long parentId;
/**
* 年份
*/
@TableField("YR")
private String year;
/**
* 初始值
*/
@TableField("INIT_VAL")
private BigDecimal initialValue;
/**
* 平均值
*/
@TableField("AVG_VAL")
private BigDecimal averageValue;
/**
* 合计值
*/
@TableField("SM_VAL")
private BigDecimal sumValue;
/**
* 一月
*/
@TableField("JAN")
private BigDecimal january;
/**
* 二月
*/
@TableField("FEB")
private BigDecimal february;
/**
* 三月
*/
@TableField("MAR")
private BigDecimal march;
/**
* 四月
*/
@TableField("APRIL")
private BigDecimal april;
/**
* 五月
*/
@TableField("MAY")
private BigDecimal may;
/**
* 六月
*/
@TableField("JUN")
private BigDecimal june;
/**
* 七月
*/
@TableField("JUL")
private BigDecimal july;
/**
* 八月
*/
@TableField("AUG")
private BigDecimal august;
/**
* 九月
*/
@TableField("SEP")
private BigDecimal september;
/**
* 十月
*/
@TableField("OCT")
private BigDecimal october;
/**
* 十一月
*/
@TableField("NOV")
private BigDecimal november;
/**
* 十二月
*/
@TableField("DECEM")
private BigDecimal december;
}

View File

@@ -0,0 +1,78 @@
package com.zt.plat.module.base.service.plandate;
import java.util.*;
import com.zt.plat.module.base.controller.admin.plandate.vo.PlanDatePageReqVO;
import com.zt.plat.module.base.controller.admin.plandate.vo.PlanDateRespVO;
import com.zt.plat.module.base.controller.admin.plandate.vo.PlanDateSaveReqVO;
import com.zt.plat.module.base.dal.dataobject.plandate.PlanDateDO;
import jakarta.validation.*;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.pojo.PageParam;
/**
* 计划数据 Service 接口
*
* @author 后台管理-1
*/
public interface PlanDateService {
/**
* 创建计划数据
*
* @param createReqVO 创建信息
* @return 编号
*/
PlanDateRespVO createPlanDate(@Valid PlanDateSaveReqVO createReqVO);
/**
* 更新计划数据
*
* @param updateReqVO 更新信息
*/
void updatePlanDate(@Valid PlanDateSaveReqVO updateReqVO);
/**
* 删除计划数据
*
* @param id 编号
*/
void deletePlanDate(Long id);
/**
* 批量删除计划数据
*
* @param ids 编号
*/
void deletePlanDateListByIds(List<Long> ids);
/**
* 获得计划数据
*
* @param id 编号
* @return 计划数据
*/
PlanDateDO getPlanDate(Long id);
/**
* 获得计划数据分页
*
* @param pageReqVO 分页查询
* @return 计划数据分页
*/
PageResult<PlanDateDO> getPlanDatePage(PlanDatePageReqVO pageReqVO);
/**
* 创建计划数据
*
* @param createReqVO 创建信息
* @return 编号
*/
PlanDateRespVO createPlanDateWithChildren(PlanDateSaveReqVO createReqVO);
/**
* 获得计划数据树
*
* @return 计划数据树
*/
List<PlanDateRespVO> listPlanDateTree();
}

View File

@@ -0,0 +1,207 @@
package com.zt.plat.module.base.service.plandate;
import cn.hutool.core.collection.CollUtil;
import com.zt.plat.module.base.controller.admin.plandate.vo.PlanDatePageReqVO;
import com.zt.plat.module.base.controller.admin.plandate.vo.PlanDateRespVO;
import com.zt.plat.module.base.controller.admin.plandate.vo.PlanDateSaveReqVO;
import com.zt.plat.module.base.dal.dao.plandate.PlanDateMapper;
import com.zt.plat.module.base.dal.dataobject.plandate.PlanDateDO;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.pojo.PageParam;
import com.zt.plat.framework.common.util.object.BeanUtils;
import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.zt.plat.framework.common.util.collection.CollectionUtils.convertList;
import static com.zt.plat.framework.common.util.collection.CollectionUtils.diffList;
import static com.zt.plat.module.base.enums.ErrorCodeConstants.PLAN_DATE_NOT_EXISTS;
import static com.zt.plat.module.base.enums.PlanConstants.ROOT_PARENT_ID;
/**
* 计划数据 Service 实现类
*
* @author 后台管理-1
*/
@Service
@Validated
public class PlanDateServiceImpl implements PlanDateService {
@Resource
private PlanDateMapper planDateMapper;
@Override
public PlanDateRespVO createPlanDate(PlanDateSaveReqVO createReqVO) {
// 插入
PlanDateDO planDate = BeanUtils.toBean(createReqVO, PlanDateDO.class);
planDateMapper.insert(planDate);
// 返回
return BeanUtils.toBean(planDate, PlanDateRespVO.class);
}
@Override
public void updatePlanDate(PlanDateSaveReqVO updateReqVO) {
// 校验存在
validatePlanDateExists(updateReqVO.getId());
// 更新
PlanDateDO updateObj = BeanUtils.toBean(updateReqVO, PlanDateDO.class);
planDateMapper.updateById(updateObj);
}
@Override
public void deletePlanDate(Long id) {
// 校验存在
validatePlanDateExists(id);
// 删除
planDateMapper.deleteById(id);
}
@Override
public void deletePlanDateListByIds(List<Long> ids) {
// 校验存在
validatePlanDateExists(ids);
// 删除
planDateMapper.deleteByIds(ids);
}
private void validatePlanDateExists(List<Long> ids) {
List<PlanDateDO> list = planDateMapper.selectByIds(ids);
if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
throw exception(PLAN_DATE_NOT_EXISTS);
}
}
private void validatePlanDateExists(Long id) {
if (planDateMapper.selectById(id) == null) {
throw exception(PLAN_DATE_NOT_EXISTS);
}
}
@Override
public PlanDateDO getPlanDate(Long id) {
return planDateMapper.selectById(id);
}
@Override
public PageResult<PlanDateDO> getPlanDatePage(PlanDatePageReqVO pageReqVO) {
return planDateMapper.selectPage(pageReqVO);
}
@Transactional(rollbackFor = Exception.class)
@Override
public PlanDateRespVO createPlanDateWithChildren(PlanDateSaveReqVO createReqVO) {
// 1. 保存根节点(父节点)
PlanDateDO rootPlanDate = BeanUtils.toBean(createReqVO, PlanDateDO.class);
rootPlanDate.setId(null); // 新增时清空ID使用数据库自增
rootPlanDate.setParentId(ROOT_PARENT_ID); // 根节点父ID设为0
planDateMapper.insert(rootPlanDate);
// 2. 递归保存所有子节点
recursiveSaveChildren(createReqVO.getChildren(), rootPlanDate.getId());
// 3. 返回根节点响应
return BeanUtils.toBean(rootPlanDate, PlanDateRespVO.class);
}
/**
* 私有辅助方法:递归保存子节点
* @param childrenVO 子节点VO列表
* @param parentId 父节点ID
*/
private void recursiveSaveChildren(List<PlanDateSaveReqVO> childrenVO, Long parentId) {
// 子节点为空时直接返回
if (CollUtil.isEmpty(childrenVO)) {
return;
}
// 遍历子节点并保存
for (PlanDateSaveReqVO childVO : childrenVO) {
PlanDateDO childPlanDate = BeanUtils.toBean(childVO, PlanDateDO.class);
childPlanDate.setId(null); // 新增时清空ID
childPlanDate.setParentId(parentId); // 设置父节点ID
planDateMapper.insert(childPlanDate);
// 递归保存当前子节点的子节点(孙子节点)
recursiveSaveChildren(childVO.getChildren(), childPlanDate.getId());
}
}
/**
* 查询所有计划数据并构造树形结构(适配前端展示)
* @return 树形结构的计划数据RespVO列表
*/
@Override
public List<PlanDateRespVO> listPlanDateTree() {
// 1. 全量查询所有未删除的计划数据
List<PlanDateDO> allPlanDate = planDateMapper.selectList();
if (CollUtil.isEmpty(allPlanDate)) {
return Collections.emptyList();
}
// 保留你能正常映射的转换方式(无需修改)
List<PlanDateRespVO> allVO = BeanUtils.toBean(allPlanDate, PlanDateRespVO.class);
// 调试日志确认转换后的数据量和父ID可选便于排查
System.out.println("转换后VO数量" + allVO.size());
allVO.forEach(vo -> {
System.out.println("VO ID: " + vo.getId() + ", 父ID: " + vo.getParentId() + ", 名称: " + vo.getPlanName());
});
// 2. 构建父ID -> 子节点列表的映射核心适配父ID=0的根节点
Map<Long, List<PlanDateRespVO>> parentId2Children = allVO.stream()
.collect(Collectors.groupingBy(
PlanDateRespVO::getParentId,
// 按计划名称排序,保证同级节点有序
Collectors.collectingAndThen(Collectors.toList(), list -> {
list.sort(Comparator.comparing(PlanDateRespVO::getPlanName));
return list;
})
));
// 3. 递归构造树形结构根节点为parentId=0的节点核心修正
List<PlanDateRespVO> rootNodes = new ArrayList<>();
for (PlanDateRespVO vo : allVO) {
// 关键匹配根节点父ID=0而非null这是你数据的实际根节点标识
if (ROOT_PARENT_ID.equals(vo.getParentId())) {
// 递归挂载子节点
buildTreeChildren(vo, parentId2Children, 1); // 1代表根节点层级
rootNodes.add(vo);
}
}
// 根节点按名称排序
rootNodes.sort(Comparator.comparing(PlanDateRespVO::getPlanName));
return rootNodes;
}
/**
* 递归为节点挂载子节点,并补充层级信息
* @param parentNode 父节点
* @param parentId2Children 父ID->子节点映射
* @param level 节点层级(用于前端展示缩进)
*/
private void buildTreeChildren(PlanDateRespVO parentNode,
Map<Long, List<PlanDateRespVO>> parentId2Children,
int level) {
// 获取当前父节点的子节点列表
List<PlanDateRespVO> children = parentId2Children.get(parentNode.getId());
if (CollUtil.isEmpty(children)) {
parentNode.setChildren(Collections.emptyList());
return;
}
// 遍历子节点,递归挂载孙子节点
for (PlanDateRespVO child : children) {
buildTreeChildren(child, parentId2Children, level + 1);
}
// 挂载子节点到父节点适配PlanDateRespVO的children字段
parentNode.setChildren(children);
}
}

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zt.plat.module.bse.dal.dao.plandate.PlanDateMapper">
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
</mapper>