递归遍历树结构,前端传入一整颗树,后端处理这个树,包括生成树的id和pid等信息,

递归逻辑

递归遍历树结构,将树结构转换list集合 并添加到 flowStepTree 集合

	// 递归遍历树结构,将树结构转换list集合 并添加到 flowStepTree 集合
	private static void settingTree(ProductFlowStepVO node, Long parentId, String ancestors, List<ProductFlowStepVO> flowStepTree) {
		long currentId = IdWorker.getId();
		node.setId(currentId);
		node.setParentId(parentId);
		node.setAncestors(ancestors + "," + node.getParentId());  // 层级码 通过 , 号隔离
		flowStepTree.add(node);
		List<ProductFlowStepVO> children = node.getChildren();
		if (CollectionUtils.isNotEmpty(children)) {
			children.forEach(c -> settingTree(c, currentId, ancestors + "," + node.getParentId(), flowStepTree));
		}
	}

接收前端树的结构 ProductFlowVO   由于除了树结构还有其他参数,

接收的树结构 ProductFlowVO  和其他数据

package com.bluebird.code.vo;

import com.bluebird.code.entity.ProductFlowEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.util.List;

/**
 * 赋码 -产品流程表 视图实体类 
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class ProductFlowVO extends ProductFlowEntity {
	private static final long serialVersionUID = 1L;

	@ApiModelProperty(value = "树子元素")
	private List<ProductFlowStepVO> flowStepTree;

	//详情返回使用
	@ApiModelProperty(value = "集合转树结构")
	private List<ProductFlowStepTreeVO> listTree;

	/**
	 * 产品名称
	 */
	@ApiModelProperty(value = "产品名称")
	private String codeProName;

	@ApiModelProperty(value = "开始更新时间")
	private String startUpdateDate;

	@ApiModelProperty(value = "结束更新时间")
	private String endUpdateDate;

	@ApiModelProperty(value = "产品id集合")
	private String productIds;

	/**
	 * 产品名称集合
	 */
	@ApiModelProperty(value = "产品名称集合Id")
	private String productIdList;


}

继承的实体类 ProductFlowEntity 

package com.bluebird.code.entity;

import com.baomidou.mybatisplus.annotation.TableName;
import com.bluebird.core.tenant.mp.TenantEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * 赋码 -产品流程表 实体类 
 */
@Data
@TableName("t_code_product_flow")
@ApiModel(value = "ProductFlow对象", description = "赋码 -产品流程表")
@EqualsAndHashCode(callSuper = true)
public class ProductFlowEntity extends TenantEntity {

	/**
	 * 企业Id
	 */
	@ApiModelProperty(value = "企业Id")
	private Long enterpriseId;
	/**
	 * 产品ID
	 */
	@ApiModelProperty(value = "产品ID")
	private Long proId;
	/**
	 * 流程步骤名称
	 */
	@ApiModelProperty(value = "流程步骤名称")
	private String stepName;
	/**
	 * 排序
	 */
	@ApiModelProperty(value = "排序")
	private Integer sort;
	/**
	 * 备注
	 */
	@ApiModelProperty(value = "备注")
	private String remark;
	/**
	 * 类型 1:公司 2:部门 3:小组 0:其他
	 */
	@ApiModelProperty(value = "类型 1:公司 2:部门 3:小组 0:其他")
	private Integer category;
	/**
	 * 产品id
	 */
	@ApiModelProperty(value = "产品id")
	private Long productId;

	@ApiModelProperty(value = "产品名字集合")
	private String productName;

	@ApiModelProperty(value = "创建人名称")
	private String createName;


}

树结构的对象和继承类

package com.bluebird.code.vo;

import com.bluebird.code.entity.ProductFlowStepEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.util.List;

// 接收前端树的结构
@Data
@EqualsAndHashCode(callSuper = true)
public class ProductFlowStepVO extends ProductFlowStepEntity {
	private static final long serialVersionUID = 1L;

	private List<ProductFlowStepVO> children;

}

继承的实体类 ProductFlowStepEntity

package com.bluebird.code.entity;

import com.baomidou.mybatisplus.annotation.TableName;
import com.bluebird.core.tenant.mp.TenantEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * 赋码 -产品流程步骤表 实体类
 * 
 */
@Data
@TableName("t_code_product_flow_step")
@ApiModel(value = "ProductFlowStep对象", description = "赋码 -产品流程步骤表")
@EqualsAndHashCode(callSuper = true)
public class ProductFlowStepEntity extends TenantEntity {

	/**
	 * 企业Id
	 */
	@ApiModelProperty(value = "企业Id")
	private Long enterpriseId;
	/**
	 * 产品流程ID
	 */
	@ApiModelProperty(value = "产品流程ID")
	private Long flowId;
	/**
	 * 父主键
	 */
	@ApiModelProperty(value = "父主键")
	private Long parentId;
	/**
	 * 目录名
	 */
	@ApiModelProperty(value = "目录名")
	private String name;
	/**
	 * 全称
	 */
	@ApiModelProperty(value = "全称")
	private String fullName;
	/**
	 * 祖级列表
	 */
	@ApiModelProperty(value = "祖级列表")
	private String ancestors;
	/**
	 * 备注
	 */
	@ApiModelProperty(value = "备注")
	private String remark;
	/**
	 * 是否公开 (0:否 1:是 2:草稿 9:其他)
	 */
	@ApiModelProperty(value = "是否公开 (0:否 1:是 2:草稿 9:其他)")
	private Integer isPublic;
	/**
	 * 是否继承 (0:否 1:是)
	 */
	@ApiModelProperty(value = "是否继承 (0:否 1:是)")
	private Integer isInherit;
	/**
	 * 排序
	 */
	@ApiModelProperty(value = "排序")
	private Integer sort;
	/**
	 * 类型 1:公司 2:部门 3:小组 0:其他
	 */
	@ApiModelProperty(value = "类型 1:公司 2:部门 3:小组 0:其他")
	private Integer category;
	/**
	 * 产品id
	 */
	@ApiModelProperty(value = "产品id")
	private Long productId;

}

组装树结构 ProductFlowStepTreeVO对象(一般返回前端组装数据使用)

package com.bluebird.code.vo;

import com.bluebird.code.entity.CodeProductFlowBatchStepDataEntity;
import com.bluebird.core.tool.node.INode;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.util.ArrayList;
import java.util.List;

/**
 * 赋码 -产品流程树 用户详情回显使用
 *
 */
@Data
@EqualsAndHashCode()
@ApiModel(value = "ProductFilesVO对象", description = "ProductFilesVO对象")
public class ProductFlowStepTreeVO  implements INode<ProductFlowStepTreeVO> {


	private static final long serialVersionUID = 1L;


	/**
	 * 主键ID
	 */
	@JsonSerialize(using = ToStringSerializer.class)
	private Long id;

	/**
	 * 父节点ID
	 */
	@JsonSerialize(using = ToStringSerializer.class)
	private Long parentId;

	/**
	 * 子孙节点
	 */
	@JsonInclude(JsonInclude.Include.NON_EMPTY)
	private List<ProductFlowStepTreeVO> children;

	/**
	 * 是否有子孙节点
	 */
	@JsonInclude(JsonInclude.Include.NON_EMPTY)
	private Boolean hasChildren;

	@Override
	public List<ProductFlowStepTreeVO> getChildren() {
		if (this.children == null) {
			this.children = new ArrayList<>();
		}
		return this.children;
	}


	/**
	 * 名称
	 */
	private String name;

	/**
	 * 是否公开 (0:否 1:是 2:草稿 9:其他)
	 */
	private Integer isPublic;

	// 产品批次流程步骤数据表
	List<CodeProductFlowBatchStepDataEntity> flowBatchStepDataList;


}

整个service实现类

package com.bluebird.code.service.impl;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.bluebird.code.entity.*;
import com.bluebird.code.excel.ProductFlowExcel;
import com.bluebird.code.mapper.*;
import com.bluebird.code.service.IProductFlowService;
import com.bluebird.code.service.IProductFlowStepService;
import com.bluebird.code.vo.ProductFlowStepTreeVO;
import com.bluebird.code.vo.ProductFlowStepVO;
import com.bluebird.code.vo.ProductFlowVO;
import com.bluebird.code.vo.ProductVO;
import com.bluebird.common.constant.CommonConstant;
import com.bluebird.common.enums.common.EYn;
import com.bluebird.common.utils.IotAuthUtil;
import com.bluebird.core.log.exception.ServiceException;
import com.bluebird.core.mp.base.BaseServiceImpl;
import com.bluebird.core.tool.constant.HulkConstant;
import com.bluebird.core.tool.node.ForestNodeMerger;
import com.bluebird.core.tool.utils.StringPool;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 赋码 -产品流程表 服务实现类 
 */
@Service
public class ProductFlowServiceImpl extends BaseServiceImpl<ProductFlowMapper, ProductFlowEntity> implements IProductFlowService {

	@Autowired
	IProductFlowStepService productFlowStepService;

	@Autowired
	ProductFlowStepMapper productFlowStepMapper;

	@Autowired
	ProducttAssociationFlowMapper producttAssociationFlowMapper;

	@Autowired
	ProductFlowMapper productFlowMapper;

	@Autowired
	CodeProductFlowBatchStepDataMapper flowBatchStepDataMapper;

	@Autowired
	ProductFlowBatchStepMapper productFlowBatchStepMapper;


	@Override
	public IPage<ProductFlowVO> selectProductFlowPage(IPage<ProductFlowVO> page, ProductFlowVO productFlow) {
		String tenantId = IotAuthUtil.getTenantId();
		if (tenantId.equals(CommonConstant.ADMIN_TENANT_ID)) {
			productFlow.setTenantId(null);
			productFlow.setEnterpriseId(null);
		} else {
			if (!tenantId.equals(CommonConstant.ADMIN_TENANT_ID) && IotAuthUtil.getEnterpriseId().equals(EYn.YES.getValue())) {
				productFlow.setTenantId(tenantId);
				productFlow.setEnterpriseId(null);
			} else {
				productFlow.setTenantId(tenantId);
				productFlow.setEnterpriseId(IotAuthUtil.getEnterpriseId());
			}
		}
		List<ProductFlowVO> list = baseMapper.selectProductFlowPage(page, productFlow);
		/*if (list != null && list.size() > 0) {
			for (ProductFlowVO flowVO : list) {
				List<ProductVO> listProductName = productFlowMapper.selectProductFlowById(flowVO.getId());
				if (listProductName != null && listProductName.size() > 0) {
					flowVO.setCodeProNameList(listProductName.stream().map(ProductVO::getCodeProName).collect(Collectors.joining(",")));
					flowVO.setProductIdList(listProductName.stream().map(ProductVO::getProductId).map(String::valueOf).collect(Collectors.joining(",")));
				}
			}
		}*/
		return page.setRecords(list);
	}


	@Override
	public List<ProductFlowExcel> exportProductFlow(Wrapper<ProductFlowEntity> queryWrapper) {
		List<ProductFlowExcel> productFlowList = baseMapper.exportProductFlow(queryWrapper);
		//productFlowList.forEach(productFlow -> {
		//	productFlow.setTypeName(DictCache.getValue(DictEnum.YES_NO, ProductFlow.getType()));
		//});
		return productFlowList;
	}

	// 新增 产品流程和流程步骤
	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean saveProductFlowAndStep(ProductFlowVO productFlowVO) {
		Long enterpriseId = IotAuthUtil.getEnterpriseId();
		String tenantId = IotAuthUtil.getTenantId();
		Long userId = IotAuthUtil.getUserId();
		String deptId = IotAuthUtil.getDeptId();
		//添加流程
		ProductFlowEntity productFlow = new ProductFlowEntity();
		BeanUtils.copyProperties(productFlowVO, productFlow);
		productFlow.setEnterpriseId(enterpriseId);
		productFlow.setCreateName(IotAuthUtil.getNickName());
		save(productFlow);
		// 处理绑定的流程
		List<Long> listProductId = Arrays.stream(productFlowVO.getProductIds().split(",")).map(Long::valueOf).collect(Collectors.toList());
		for (Long productId : listProductId) {
			ProducttAssociationFlowEntity entity = new ProducttAssociationFlowEntity();
			entity.setProductId(productId);
			entity.setFlowId(productFlow.getId());
			producttAssociationFlowMapper.insert(entity);
		}
		//添加流程步骤 接收树结构
		List<ProductFlowStepVO> flowStepTree = productFlowVO.getFlowStepTree();

		List<ProductFlowStepVO> listAll = new ArrayList<>();
		//处理树结构后的数据 添加到集合 listAll
		flowStepTree.forEach(node -> settingTree(node, 0L, "", listAll));
		List<ProductFlowStepEntity> list = new ArrayList<>();
		for (ProductFlowStepVO flowStepVO : listAll) {
			ProductFlowStepEntity productFlowStep = new ProductFlowStepEntity();
			BeanUtils.copyProperties(flowStepVO, productFlowStep);
			if (EYn.NO.getValue().equals(flowStepVO.getIsDeleted())) { // 前端有可能添加3个数据,删除2个数据,又添加 1 个数据,最后实际有效的数据的是 2 条
				productFlowStep.setFlowId(productFlow.getId());
				productFlowStep.setProductId(productFlowVO.getProductId());
				productFlowStep.setCreateUser(userId);
				productFlowStep.setCreateTime(new Date());
				productFlowStep.setUpdateUser(userId);
				productFlowStep.setUpdateTime(new Date());
				productFlowStep.setCreateDept(Long.valueOf(deptId));
				productFlowStep.setEnterpriseId(enterpriseId);
				productFlowStep.setTenantId(tenantId);
				productFlowStep.setIsDeleted(HulkConstant.DB_NOT_DELETED);
				list.add(productFlowStep);
			}
		}
		productFlowStepService.saveBatch(list);
		return true;
	}


	// 修改 产品流程和流程步骤
	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean updateProductFlowAndStepById(ProductFlowVO productFlowVO) {
		Long enterpriseId = IotAuthUtil.getEnterpriseId();
		String tenantId = IotAuthUtil.getTenantId();
		Long userId = IotAuthUtil.getUserId();
		String deptId = IotAuthUtil.getDeptId();
		//修改流程
		ProductFlowEntity productFlow = new ProductFlowEntity();
		BeanUtils.copyProperties(productFlowVO, productFlow);
		productFlowMapper.updateById(productFlow);
		// 处理流程产品关联表
		LambdaQueryWrapper<ProducttAssociationFlowEntity> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(ProducttAssociationFlowEntity::getFlowId, productFlow.getId());
		producttAssociationFlowMapper.delete(queryWrapper);
		List<Long> listProductId = Arrays.stream(productFlowVO.getProductIds().split(",")).map(Long::valueOf).collect(Collectors.toList());
		for (Long productId : listProductId) {
			ProducttAssociationFlowEntity entity = new ProducttAssociationFlowEntity();
			entity.setProductId(productId);
			entity.setFlowId(productFlow.getId());
			producttAssociationFlowMapper.insert(entity);
		}

		//修改流程步骤 包括 新增/修改/删除
		List<ProductFlowStepEntity> addList = new ArrayList<>();
		List<ProductFlowStepEntity> updateList = new ArrayList<>();
		List<ProductFlowStepEntity> deleteList = new ArrayList<>();

		List<ProductFlowStepVO> list = productFlowVO.getFlowStepTree();
		List<ProductFlowStepVO> listAdd = new ArrayList<>();
		List<ProductFlowStepVO> listUpdate = new ArrayList<>();
		list.forEach(node -> settingTreeAddOrUpdate(node, 0L, "", listAdd, listUpdate));
		for (ProductFlowStepVO flowStepVO : listAdd) {
			ProductFlowStepEntity productFlowStep = new ProductFlowStepEntity();
			BeanUtils.copyProperties(flowStepVO, productFlowStep);
			productFlowStep.setFlowId(productFlow.getId());
			productFlowStep.setProductId(productFlowVO.getProductId());
			productFlowStep.setCreateUser(userId);
			productFlowStep.setCreateTime(new Date());
			productFlowStep.setUpdateUser(userId);
			productFlowStep.setUpdateTime(new Date());
			productFlowStep.setCreateDept(Long.valueOf(deptId));
			productFlowStep.setEnterpriseId(enterpriseId);
			productFlowStep.setTenantId(tenantId);
			productFlowStep.setIsDeleted(HulkConstant.DB_NOT_DELETED);
			addList.add(productFlowStep);
		}
		for (ProductFlowStepVO flowStepVO : listUpdate) {
			ProductFlowStepEntity productFlowStep = new ProductFlowStepEntity();
			BeanUtils.copyProperties(flowStepVO, productFlowStep);
			if (Objects.equals(flowStepVO.getIsDeleted(), HulkConstant.DB_NOT_DELETED)) {
				updateList.add(productFlowStep);
			} else {
				deleteList.add(productFlowStep);
			}
		}
		if (addList != null && addList.size() > 0) {
			productFlowStepService.saveBatch(addList);
		}
		if (updateList != null && updateList.size() > 0) {
			//处理修改
			productFlowStepService.updateBatchById(updateList);
		}
		if (deleteList != null && deleteList.size() > 0) {
			//  删除 判断是否有流程步骤的数据
			for (ProductFlowStepEntity flowStep : deleteList) {
				LambdaQueryWrapper<CodeProductFlowBatchStepDataEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
				lambdaQueryWrapper.eq(CodeProductFlowBatchStepDataEntity::getIsDeleted, HulkConstant.DB_NOT_DELETED);
				lambdaQueryWrapper.eq(CodeProductFlowBatchStepDataEntity::getOneStepId, flowStep.getId());
				lambdaQueryWrapper.eq(CodeProductFlowBatchStepDataEntity::getEnterpriseId, IotAuthUtil.getEnterpriseId());
				Long count = flowBatchStepDataMapper.selectCount(lambdaQueryWrapper);
				if (count > 0) {
					throw new ServiceException(flowStep.getName() + " 流程步骤下有流程步骤数据,请先删除流程步骤数据!");
				}
			}
			productFlowStepService.removeBatchByIds(deleteList);
		}
		return true;
	}

	// 详情
	@Override
	public ProductFlowVO getDetail(ProductFlowEntity flowEntity) {
		ProductFlowVO productFlowVO = new ProductFlowVO();
		ProductFlowEntity productFlow = getById(flowEntity.getId());
		BeanUtils.copyProperties(productFlow, productFlowVO);
		List<ProductVO> listProductName = productFlowMapper.selectProductFlowById(flowEntity.getId());
		if (listProductName != null && listProductName.size() > 0) {
			productFlowVO.setProductIdList(listProductName.stream().map(ProductVO::getProductId).map(String::valueOf).collect(Collectors.joining(",")));
		}
		// 查询树集合
		List<ProductFlowStepTreeVO> list = productFlowStepMapper.selectListFlowStep(flowEntity.getId());
		List<ProductFlowStepTreeVO> merge = ForestNodeMerger.merge(list);
		productFlowVO.setListTree(merge);
		return productFlowVO;
	}

	// 根据流程 id 查询 产品名称 产品id 产品型号
	@Override
	public List<ProductVO> selectProductByFlowId(Long flowId) {
		List<ProductVO> listProductName = productFlowMapper.selectProductFlowById(flowId);
		return listProductName;
	}


	//  产品流程表 判断流程是否有树 树下面是否有溯源数据
	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean deleteProductFlow(List<Long> toLongList) {
		//  判断流程是否有树 树下面是否有溯源数据
		LambdaQueryWrapper<ProductFlowStepEntity> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.in(ProductFlowStepEntity::getFlowId, toLongList);
		List<ProductFlowStepEntity> list = productFlowStepService.list(queryWrapper);
		List<Long> listStepId = new ArrayList<>();
		if (list != null && list.size() > 0) {
			for (ProductFlowStepEntity step : list) {
				//  删除 判断是否有流程步骤的数据
				LambdaQueryWrapper<CodeProductFlowBatchStepDataEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
				lambdaQueryWrapper.eq(CodeProductFlowBatchStepDataEntity::getIsDeleted, HulkConstant.DB_NOT_DELETED);
				lambdaQueryWrapper.eq(CodeProductFlowBatchStepDataEntity::getOneStepId, step.getId());
				lambdaQueryWrapper.eq(CodeProductFlowBatchStepDataEntity::getEnterpriseId, IotAuthUtil.getEnterpriseId());
				Long count = flowBatchStepDataMapper.selectCount(lambdaQueryWrapper);
				if (count > 0) {
					throw new ServiceException(step.getName() + " 流程步骤下有流程步骤数据,请先删除流程步骤数据!");
				}
				listStepId.add(step.getId());
			}
		}
		// 判断流程下面是否有数据维护的数据
		for (Long flowId : toLongList) {
			LambdaQueryWrapper<ProductFlowBatchStepEntity> queryWrapperFlowBatchStep = new LambdaQueryWrapper<>();
			queryWrapperFlowBatchStep.eq(ProductFlowBatchStepEntity::getFlowId, flowId);
			queryWrapperFlowBatchStep.eq(ProductFlowBatchStepEntity::getIsDeleted, HulkConstant.DB_NOT_DELETED);
			queryWrapperFlowBatchStep.eq(ProductFlowBatchStepEntity::getEnterpriseId, IotAuthUtil.getEnterpriseId());
			List<ProductFlowBatchStepEntity> listFlowBatchStep = productFlowBatchStepMapper.selectList(queryWrapperFlowBatchStep);
			if (listFlowBatchStep != null && listFlowBatchStep.size() > 0) {
				ProductFlowEntity productFlow = getById(flowId);
				String stepName = "";
				if (productFlow != null) {
					stepName = productFlow.getStepName();
				}
				for (ProductFlowBatchStepEntity flowBatchStep : listFlowBatchStep) {
					throw new ServiceException("该流程下有流程名称为【" + stepName + "】的数据维护,请先删除数据维护!");
				}
			}
		}

		// 删除流程
		boolean remove = removeByIds(toLongList);
		//删除流程下面的树
		productFlowStepService.removeBatchByIds(listStepId);
		// 删除产品和流程的关联表
		LambdaQueryWrapper<ProducttAssociationFlowEntity> queryWrapperFlow = new LambdaQueryWrapper();
		queryWrapperFlow.in(ProducttAssociationFlowEntity::getFlowId, toLongList);
		producttAssociationFlowMapper.delete(queryWrapperFlow);
		return remove;
	}


	// 修改调用  因为修改涉及 添加/删除和修改
	private static void settingTreeAddOrUpdate(ProductFlowStepVO node, Long parentId, String ancestors, List<ProductFlowStepVO> addList, List<ProductFlowStepVO> updateList) {
		if (node.getId() == null) {
			long currentId = IdWorker.getId();
			node.setId(currentId);
			node.setParentId(parentId);
			node.setAncestors(ancestors + StringPool.COMMA + node.getParentId());
			addList.add(node);
			List<ProductFlowStepVO> children = node.getChildren();
			if (CollectionUtils.isNotEmpty(children)) {
				children.forEach(c -> settingTreeAddOrUpdate(c, currentId, ancestors + StringPool.COMMA + node.getParentId(), addList, updateList));
			}
		} else {
			Long currentId = node.getId();
			node.setParentId(parentId);
			node.setAncestors(ancestors + StringPool.COMMA + node.getParentId());
			updateList.add(node);
			List<ProductFlowStepVO> children = node.getChildren();
			if (CollectionUtils.isNotEmpty(children)) {
				children.forEach(c -> settingTreeAddOrUpdate(c, currentId, ancestors + StringPool.COMMA + node.getParentId(), addList, updateList));
			}
		}
	}

	// 递归遍历树结构,将树结构转换list集合 并添加到 flowStepTree 集合
	private static void settingTree(ProductFlowStepVO node, Long parentId, String ancestors, List<ProductFlowStepVO> flowStepTree) {
		long currentId = IdWorker.getId();
		node.setId(currentId);
		node.setParentId(parentId);
		node.setAncestors(ancestors + "," + node.getParentId());  // 层级码 通过 , 号隔离
		flowStepTree.add(node);
		List<ProductFlowStepVO> children = node.getChildren();
		if (CollectionUtils.isNotEmpty(children)) {
			children.forEach(c -> settingTree(c, currentId, ancestors + "," + node.getParentId(), flowStepTree));
		}
	}

}

前端传参树结构的数据格式,包括其他数据,

{
    "stepName": "测试流程",
    "productName": "汽车制造",
    "flowStepTree": [
        {
            "key": 1,
            "name": "第一步1",
            "parentKey": 0,
            "isDeleted": 0,
            "children": [
                {
                    "key": 2,
                    "name": "第一步2",
                    "parentKey": 1,
                    "isDeleted": 0
                }
            ]
        },
        {
            "key": 3,
            "name": "第二步1",
            "parentKey": 0,
            "isDeleted": 0,
            "children": [
                {
                    "key": 4,
                    "name": "第二步2",
                    "parentKey": 3,
                    "isDeleted": 0
                },
                {
                    "key": 5,
                    "name": "第二步3-删除",
                    "parentKey": 3,
                    "isDeleted": 1
                },
                {
                    "key": 6,
                    "name": "第二步4",
                    "parentKey": 3,
                    "isDeleted": 0
                }
            ]
        }
    ],
    "productIds": "1808434897288286210"
}

控制器 ProductFlowController 

package com.bluebird.code.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.bluebird.code.entity.ProductFlowEntity;
import com.bluebird.code.excel.ProductFlowExcel;
import com.bluebird.code.service.IProductFlowService;
import com.bluebird.code.service.IProductFlowStepService;
import com.bluebird.code.util.MyEnterpriseUtils;
import com.bluebird.code.vo.ProductFlowVO;
import com.bluebird.code.vo.ProductVO;
import com.bluebird.code.wrapper.ProductFlowWrapper;
import com.bluebird.common.utils.IotAuthUtil;
import com.bluebird.core.boot.ctrl.HulkController;
import com.bluebird.core.excel.util.ExcelUtil;
import com.bluebird.core.mp.support.Condition;
import com.bluebird.core.mp.support.Query;
import com.bluebird.core.secure.HulkUser;
import com.bluebird.core.tool.api.R;
import com.bluebird.core.tool.constant.HulkConstant;
import com.bluebird.core.tool.utils.DateUtil;
import com.bluebird.core.tool.utils.Func;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;

/**
 * 赋码 -产品流程表 控制器
 */
@RestController
@AllArgsConstructor
@RequestMapping("/productFlow")
@Api(value = "赋码 -产品流程表", tags = "赋码 -产品流程表接口")
public class ProductFlowController extends HulkController {

	private final IProductFlowService productFlowService;

	private final IProductFlowStepService productFlowStepService;

	/**
	 * 赋码 -产品流程表 详情
	 */
	@GetMapping("/detail")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "详情", notes = "传入productFlow")
	public R<ProductFlowVO> detail(ProductFlowEntity productFlow) {
		ProductFlowVO detail = productFlowService.getDetail(productFlow);
		return R.data(ProductFlowWrapper.build().entityVO(detail));
	}

	/**
	 * 赋码 -产品流程表 分页
	 */
	@GetMapping("/list")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "分页", notes = "传入productFlow")
	public R<IPage<ProductFlowVO>> list(@ApiIgnore @RequestParam Map<String, Object> productFlow, Query query) {
		IPage<ProductFlowEntity> pages = productFlowService.page(Condition.getPage(query), Condition.getQueryWrapper(productFlow, ProductFlowEntity.class));
		return R.data(ProductFlowWrapper.build().pageVO(pages));
	}

	/**
	 * 赋码 -产品流程表 自定义分页
	 */
	@GetMapping("/page")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "分页", notes = "传入productFlow")
	public R<IPage<ProductFlowVO>> page(ProductFlowVO productFlow, Query query) {
		IPage<ProductFlowVO> pages = productFlowService.selectProductFlowPage(Condition.getPage(query), productFlow);
		return R.data(pages);
	}

	/**
	 * 赋码 -产品流程表 新增
	 */
	@PostMapping("/save")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "新增", notes = "传入productFlow")
	public R save(@Valid @RequestBody ProductFlowVO productFlow) {
		String toData = MyEnterpriseUtils.determineIsEnterprise("产品流程");
		if (Func.isNotBlank(toData)) {
			return R.fail(toData);
		}
		if (Func.isEmpty(productFlow.getStepName())) {
			return R.fail("流程名称不能为空!");
		}
		if (Func.isEmpty(productFlow.getProductIds())) {
			return R.fail("请先选择产品!");
		}
		if (Func.isEmpty(productFlow.getFlowStepTree())) {
			return R.fail("流程步骤不能为空!");
		}
		//判断产品流程名称是否重复
		Long count = new LambdaQueryChainWrapper<>(productFlowService.getBaseMapper())
			.eq(ProductFlowEntity::getStepName, productFlow.getStepName())
			.eq(ProductFlowEntity::getEnterpriseId, IotAuthUtil.getEnterpriseId()).count();
		if (count > 0) {
			return R.fail("流程名称已存在,不能重复!");
		}
		return R.status(productFlowService.saveProductFlowAndStep(productFlow));
	}

	/**
	 * 赋码 -产品流程表 修改
	 */
	@PostMapping("/update")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "修改", notes = "传入productFlow")
	public R update(@Valid @RequestBody ProductFlowVO productFlow) {
		String toData = MyEnterpriseUtils.determineIsEnterprise("产品流程");
		if (Func.isNotBlank(toData)) {
			return R.fail(toData);
		}
		if (Func.isEmpty(productFlow.getStepName())) {
			return R.fail("流程名称不能为空!");
		}
		if (Func.isEmpty(productFlow.getProductIds())) {
			return R.fail("请先选择产品!");
		}
		if (Func.isEmpty(productFlow.getFlowStepTree())) {
			return R.fail("流程步骤不能为空!");
		}
		//判断产品流程名称是否重复
		Long count = new LambdaQueryChainWrapper<>(productFlowService.getBaseMapper())
			.ne(ProductFlowEntity::getId, productFlow.getId())
			.eq(ProductFlowEntity::getStepName, productFlow.getStepName())
			.eq(ProductFlowEntity::getEnterpriseId, IotAuthUtil.getEnterpriseId()).count();
		if (count > 0) {
			return R.fail("流程名称已存在,不能重复!");
		}
		return R.status(productFlowService.updateProductFlowAndStepById(productFlow));
	}

	/**
	 * 赋码 -产品流程表 新增或修改
	 */
	@PostMapping("/submit")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "新增或修改", notes = "传入productFlow")
	public R submit(@Valid @RequestBody ProductFlowEntity productFlow) {
		return R.status(productFlowService.saveOrUpdate(productFlow));
	}

	/**
	 * 赋码 -产品流程表 删除
	 */
	@PostMapping("/remove")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		return R.status(productFlowService.deleteProductFlow(Func.toLongList(ids)));
	}


	/**
	 * 导出数据
	 */
	@GetMapping("/export-productFlow")
	@ApiOperationSupport(order = 9)
	@ApiOperation(value = "导出数据", notes = "传入productFlow")
	public void exportProductFlow(@ApiIgnore @RequestParam Map<String, Object> productFlow, HulkUser hulkUser, HttpServletResponse response) {
		QueryWrapper<ProductFlowEntity> queryWrapper = Condition.getQueryWrapper(productFlow, ProductFlowEntity.class);
		//if (!AuthUtil.isAdministrator()) {
		//	queryWrapper.lambda().eq(ProductFlow::getTenantId, hulkUser.getTenantId());
		//}
		queryWrapper.lambda().eq(ProductFlowEntity::getIsDeleted, HulkConstant.DB_NOT_DELETED);
		List<ProductFlowExcel> list = productFlowService.exportProductFlow(queryWrapper);
		ExcelUtil.export(response, "赋码 -产品流程表数据" + DateUtil.time(), "赋码 -产品流程表数据表", list, ProductFlowExcel.class);
	}



	/**
	 * 根据流程 id 查询 产品名称 产品id 产品型号
	 */
	@GetMapping("/selectProductByFlowId")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "根据流程 id 查询 产品名称/产品id/产品型号", notes = "传入productFlow")
	public R<List<ProductVO>> selectProductByFlowId(@RequestParam Long flowId) {
		List<ProductVO> productVO = productFlowService.selectProductByFlowId(flowId);
		return R.data( productVO );
	}


}

相关推荐

  1. 二叉|前中

    2024-07-18 21:48:01       66 阅读
  2. 每日二叉

    2024-07-18 21:48:01       45 阅读
  3. 二叉

    2024-07-18 21:48:01       51 阅读
  4. 二叉前、中与迭代实现

    2024-07-18 21:48:01       40 阅读
  5. 二叉(法)

    2024-07-18 21:48:01       46 阅读
  6. 前序思路

    2024-07-18 21:48:01       24 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-18 21:48:01       49 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-18 21:48:01       53 阅读
  3. 在Django里面运行非项目文件

    2024-07-18 21:48:01       41 阅读
  4. Python语言-面向对象

    2024-07-18 21:48:01       52 阅读

热门阅读

  1. Html_Css问答集(8)

    2024-07-18 21:48:01       15 阅读
  2. APP开发者选择苹果企业签名的理由是什么?

    2024-07-18 21:48:01       18 阅读
  3. 负载均衡轮询逻辑

    2024-07-18 21:48:01       15 阅读
  4. swift小知识点(二)

    2024-07-18 21:48:01       15 阅读
  5. Redis常见阻塞原因

    2024-07-18 21:48:01       19 阅读
  6. Pandas库学习之DataFrame.replace()函数

    2024-07-18 21:48:01       16 阅读
  7. ros2--插件

    2024-07-18 21:48:01       19 阅读
  8. 探索 Flask:从入门到精通的完整学习指南

    2024-07-18 21:48:01       16 阅读
  9. antd使用踩坑记录

    2024-07-18 21:48:01       15 阅读
  10. 数组 59.螺旋矩阵Ⅱ

    2024-07-18 21:48:01       18 阅读
  11. 无人机反制:车载侦测干扰一体设备技术详解

    2024-07-18 21:48:01       18 阅读