当前位置: 首页 > news >正文

递归遍历树结构,前端传入一整颗树,后端处理这个树,包括生成树的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;@Overridepublic 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 {@AutowiredIProductFlowStepService productFlowStepService;@AutowiredProductFlowStepMapper productFlowStepMapper;@AutowiredProducttAssociationFlowMapper producttAssociationFlowMapper;@AutowiredProductFlowMapper productFlowMapper;@AutowiredCodeProductFlowBatchStepDataMapper flowBatchStepDataMapper;@AutowiredProductFlowBatchStepMapper productFlowBatchStepMapper;@Overridepublic 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);}@Overridepublic 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<>();//处理树结构后的数据 添加到集合 listAllflowStepTree.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;}// 详情@Overridepublic 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 产品型号@Overridepublic 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 );}}

相关文章:

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

递归逻辑 递归遍历树结构&#xff0c;将树结构转换list集合 并添加到 flowStepTree 集合 // 递归遍历树结构&#xff0c;将树结构转换list集合 并添加到 flowStepTree 集合private static void settingTree(ProductFlowStepVO node, Long parentId, String ancestors, List<…...

Nginx详解(超级详细)

目录 Nginx简介 1. 为什么使用Nginx 2. 安装Nginx Nginx的核心功能 1. Nginx反向代理功能 2. Nginx的负载均衡 3 Nginx动静分离 Nginx简介 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器&#xff0c;在BSD-like 协…...

postman使用旧版本报错version mismatch detected

卸载 postman又重装了别的版本&#xff0c;打开后遇到了这个报错&#xff0c;解决办法如下&#xff1a; 删除缓存文件 C:\Users\Administrator\AppData\Roaming\Postman 下载PostMan 提取码&#xff1a;6k51...

探索数据的隐藏维度:使用Scikit-Learn进行特征交互性预测

探索数据的隐藏维度&#xff1a;使用Scikit-Learn进行特征交互性预测 在机器学习中&#xff0c;特征交互性是指不同特征之间可能存在的复杂关系&#xff0c;这些关系对预测结果有着重要影响。Scikit-Learn&#xff08;简称sklearn&#xff09;&#xff0c;作为Python中广受欢迎…...

首个WebAgent在线评测框架和流程数据管理平台来了,GPT-4、Qwen登顶闭源和开源榜首!

在当今科技迅速发展的时代&#xff0c;大型语言模型&#xff08;Large Language Model&#xff0c;LLM&#xff09;正以前所未有的速度改变着我们与数字世界的互动方式。基于LLM的智能代理&#xff08;LLM Agent&#xff09;&#xff0c;从简单的信息搜索到复杂的网页操作&…...

UE TSharedPtr

文章目录 概述TSharedPtrTSharedPtr包含2部分 构造&#xff0c;析构&#xff0c;拷贝构造&#xff0c;移动构造构造拷贝构造移动构造 小结 概述 之前写过一篇c的智能指针的&#xff0c;这篇写下ue的。本质上来说是差不多的&#xff0c;可以简单看看。 TSharedPtr 如下图&…...

基于X86+FPGA+AI的远程医疗系统,支持12/13代 Intel Core处理器

工控主板&#xff1a;支持12/13代 Intel Core处理器&#xff0c;适用于远程医疗系统 顺应数字化、网络化、智能化发展趋势&#xff0c;国内医疗产业改革正在积极推进&#xff0c;远程医疗、智慧医疗等新模式新业态创新发展和应用&#xff0c;市场空间不断扩大&#xff0c;而基…...

微信小程序开发入门指南

文章目录 一、微信小程序简介二、微信小程序开发准备三、微信小程序开发框架四、微信小程序开发实例六、微信小程序开发进阶6.1 组件化开发6.2 API调用6.3 云开发 七、微信小程序开发注意事项7.1 遵守规范7.2 注意性能7.3 保护用户隐私 八、总结 大家好&#xff0c;今天将为大家…...

一个非常好的美图展示网站整站打包源码,集成了wordpress和开源版ripro主题,可以完美运营。

一个非常好的美图展示网站整站打包源码&#xff0c;集成了wordpress和开源版ripro主题&#xff0c;可以完美运营。 自带了5个多g的美图资源&#xff0c;让网站内容看起来非常大气丰富&#xff0c;可以快速投入运营。 这个代码包&#xff0c;原网站已经稳定运营多年&#xff0…...

MySQL:mysql的数据类型

MySQL 作为一个流行的关系型数据库管理系统&#xff0c;支持多种数据类型以满足不同的数据处理和存储需求。正确理解和使用这些数据类型对于提高数据库性能、确保数据完整性和准确性至关重要。 MySQL 数据类型 数据类型定义了列中可以存储什么数据以及该数据怎样存储的规则。…...

IPython魔法命令的深入应用

目录 IPython魔法命令的深入应用 一、魔法命令基础 1. 魔法命令的分类 2. 基本使用 二、高级应用技巧 1. 数据交互与处理 2. 交互式编程与调试 三、魔法命令的进阶操作 1. 自定义魔法命令 2. 利用魔法命令优化工作流程 四、总结与展望 IPython魔法命令的深入应用 IP…...

Yum包下载

1. 起因 内网有一台服务器需要升级php版本,维护的同学又不想二进制安装.服务器只有一个光盘的yum仓库 2. 解决方法 解决思路如下: 外网找一台机器配置php8.3.8的仓库外网服务器下载软件集并打包内网服务器上传并解压实现升级 2.1 下载php8.3.8仓库 配置php仓库 rootcent…...

数据结构代码

文章目录 线性表的插入线性表的删除单链表的建立栈的顺序存储队列的顺序存储串的顺序存储树的存储二叉树遍历前序遍历中序遍历后序遍历 二分法插入排序利用普里姆算法构造最小生成树 线性表的插入 #a: 列表&#xff0c;pos: 要插入的位置&#xff0c;key: 要插入的数据&#x…...

环信IM x 亚马逊云科技,助力出海企业实现可靠通讯服务

随着全球化进程的加速&#xff0c;越来越多的企业选择出海&#xff0c;拓展国际市场。然而&#xff0c;面对不同国家和地区的用户&#xff0c;企业在即时通讯方面遇到了诸多挑战。为了帮助企业克服这些困难&#xff0c;环信IM与亚马逊云科技强强联手&#xff0c;共同推出了一套…...

R语言画散点图-饼图-折线图-柱状图-箱线图-直方图-等高线图-曲线图-热力图-雷达图-韦恩图(二D)

R语言画散点图-饼图-折线图-柱状图-箱线图-直方图-等高线图-曲线图-热力图-雷达图-韦恩图&#xff08;二D&#xff09; 散点图示例解析效果 饼图示例解析效果 折线图示例解析效果 柱状图示例解析效果 箱线图示例解析效果 直方图示例解析效果 等高线图使用filled.contour函数示例…...

go中map

文章目录 Map简介哈希表与Map的概念Go语言内建的Map类型Map的声明Map的初始化Map的访问Map的添加和修改Map的删除Map的遍历 Map的基本使用Map的声明与初始化Map的访问与操作Map的删除Map的遍历Map的并发问题实现线程安全的Map 3. Map的访问与操作3.1 访问Map元素代码示例&#…...

02-用户画像-技术架构+业务划分

技术架构 python开发 es flume 流数据读取写入kafka文件 kafka 消息队列 sqoop 将数据导入数仓hive StructureStream 动态画像的处理 SparkSQL 静态画像的处理 &#xff0c;批数据处理 读取kafka获取用户行为数据 fineBI 数据展示 业务划分 离线业务 静态画像 …...

HarmonyOS应用开发者高级认证,Next版本发布后最新题库 - 单选题序号1

本来打算找到工作再整理高级的题库&#xff0c;但一直没什么面试机会。宅在家里也不知道干些什么。索性就把高级的题库整理出来了。也算有头有尾。高级的题库更新之后&#xff0c;专业性更强了&#xff0c;不是真正从事这一行的&#xff0c;很难做出来。本人就是个小菜鸡&#…...

敲详细的springboot中使用RabbitMQ的源码解析

这里介绍的源码主要是涉及springboot框架下的rabbitmq客户端代码&#xff08;具体在springframework.amqp.rabbit包下&#xff0c;区分一下不由springboot直接接管的spring-rabbit的内容&#xff09;&#xff0c;springboot基于RabbitMQ的Java客户端建立了简便易用的框架。 sp…...

《Nginx核心技术》第04章:生成缩略图

作者&#xff1a;冰河 星球&#xff1a;http://m6z.cn/6aeFbs 博客&#xff1a;https://binghe.gitcode.host 文章汇总&#xff1a;https://binghe.gitcode.host/md/all/all.html 星球项目地址&#xff1a;https://binghe.gitcode.host/md/zsxq/introduce.html 沉淀&#xff0c…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...