递归遍历树结构,前端传入一整颗树,后端处理这个树,包括生成树的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等信息,
递归逻辑 递归遍历树结构,将树结构转换list集合 并添加到 flowStepTree 集合 // 递归遍历树结构,将树结构转换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 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协…...
postman使用旧版本报错version mismatch detected
卸载 postman又重装了别的版本,打开后遇到了这个报错,解决办法如下: 删除缓存文件 C:\Users\Administrator\AppData\Roaming\Postman 下载PostMan 提取码:6k51...
探索数据的隐藏维度:使用Scikit-Learn进行特征交互性预测
探索数据的隐藏维度:使用Scikit-Learn进行特征交互性预测 在机器学习中,特征交互性是指不同特征之间可能存在的复杂关系,这些关系对预测结果有着重要影响。Scikit-Learn(简称sklearn),作为Python中广受欢迎…...
首个WebAgent在线评测框架和流程数据管理平台来了,GPT-4、Qwen登顶闭源和开源榜首!
在当今科技迅速发展的时代,大型语言模型(Large Language Model,LLM)正以前所未有的速度改变着我们与数字世界的互动方式。基于LLM的智能代理(LLM Agent),从简单的信息搜索到复杂的网页操作&…...
UE TSharedPtr
文章目录 概述TSharedPtrTSharedPtr包含2部分 构造,析构,拷贝构造,移动构造构造拷贝构造移动构造 小结 概述 之前写过一篇c的智能指针的,这篇写下ue的。本质上来说是差不多的,可以简单看看。 TSharedPtr 如下图&…...
基于X86+FPGA+AI的远程医疗系统,支持12/13代 Intel Core处理器
工控主板:支持12/13代 Intel Core处理器,适用于远程医疗系统 顺应数字化、网络化、智能化发展趋势,国内医疗产业改革正在积极推进,远程医疗、智慧医疗等新模式新业态创新发展和应用,市场空间不断扩大,而基…...
微信小程序开发入门指南
文章目录 一、微信小程序简介二、微信小程序开发准备三、微信小程序开发框架四、微信小程序开发实例六、微信小程序开发进阶6.1 组件化开发6.2 API调用6.3 云开发 七、微信小程序开发注意事项7.1 遵守规范7.2 注意性能7.3 保护用户隐私 八、总结 大家好,今天将为大家…...
一个非常好的美图展示网站整站打包源码,集成了wordpress和开源版ripro主题,可以完美运营。
一个非常好的美图展示网站整站打包源码,集成了wordpress和开源版ripro主题,可以完美运营。 自带了5个多g的美图资源,让网站内容看起来非常大气丰富,可以快速投入运营。 这个代码包,原网站已经稳定运营多年࿰…...
MySQL:mysql的数据类型
MySQL 作为一个流行的关系型数据库管理系统,支持多种数据类型以满足不同的数据处理和存储需求。正确理解和使用这些数据类型对于提高数据库性能、确保数据完整性和准确性至关重要。 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: 列表,pos: 要插入的位置,key: 要插入的数据&#x…...
环信IM x 亚马逊云科技,助力出海企业实现可靠通讯服务
随着全球化进程的加速,越来越多的企业选择出海,拓展国际市场。然而,面对不同国家和地区的用户,企业在即时通讯方面遇到了诸多挑战。为了帮助企业克服这些困难,环信IM与亚马逊云科技强强联手,共同推出了一套…...
R语言画散点图-饼图-折线图-柱状图-箱线图-直方图-等高线图-曲线图-热力图-雷达图-韦恩图(二D)
R语言画散点图-饼图-折线图-柱状图-箱线图-直方图-等高线图-曲线图-热力图-雷达图-韦恩图(二D) 散点图示例解析效果 饼图示例解析效果 折线图示例解析效果 柱状图示例解析效果 箱线图示例解析效果 直方图示例解析效果 等高线图使用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 静态画像的处理 ,批数据处理 读取kafka获取用户行为数据 fineBI 数据展示 业务划分 离线业务 静态画像 …...
HarmonyOS应用开发者高级认证,Next版本发布后最新题库 - 单选题序号1
本来打算找到工作再整理高级的题库,但一直没什么面试机会。宅在家里也不知道干些什么。索性就把高级的题库整理出来了。也算有头有尾。高级的题库更新之后,专业性更强了,不是真正从事这一行的,很难做出来。本人就是个小菜鸡&#…...
敲详细的springboot中使用RabbitMQ的源码解析
这里介绍的源码主要是涉及springboot框架下的rabbitmq客户端代码(具体在springframework.amqp.rabbit包下,区分一下不由springboot直接接管的spring-rabbit的内容),springboot基于RabbitMQ的Java客户端建立了简便易用的框架。 sp…...
《Nginx核心技术》第04章:生成缩略图
作者:冰河 星球:http://m6z.cn/6aeFbs 博客:https://binghe.gitcode.host 文章汇总:https://binghe.gitcode.host/md/all/all.html 星球项目地址:https://binghe.gitcode.host/md/zsxq/introduce.html 沉淀,…...
python基于微信小程序的方言文化传播平台的设计与开发
目录需求分析与规划技术选型与架构设计核心功能实现数据处理与优化测试与部署运营与迭代项目技术支持源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作需求分析与规划 明确平台的核心功能需求,包括方言内容展示、语音录制与分享、…...
OpCore-Simplify终极指南:零代码自动化黑苹果EFI配置实战
OpCore-Simplify终极指南:零代码自动化黑苹果EFI配置实战 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 在macOS生态之外构建黑苹果系统&…...
Spring Boot 与 Serverless 集成最佳实践
Spring Boot 与 Serverless 集成最佳实践 引言 大家好,今天想和大家聊聊 Spring Boot 与 Serverless 的集成。Serverless 是一种云原生的计算模型,它允许开发者专注于代码开发,而不需要管理服务器基础设施。在 Spring Boot 应用中,…...
保姆级教程:在OrangePi 5 Plus上从SSD启动Ubuntu 22.04,并配置ROS2 Humble环境
OrangePi 5 Plus开发板全栈配置指南:从SSD启动到ROS2 Humble环境搭建 拿到一块OrangePi 5 Plus开发板时,如何快速搭建一个稳定高效的开发环境?本文将手把手带你完成从系统烧录到ROS2环境配置的全过程,特别针对ARM64架构的优化方案…...
JeecgBoot低代码开发平台终极实战指南:从零开始构建企业级应用
JeecgBoot低代码开发平台终极实战指南:从零开始构建企业级应用 【免费下载链接】jeecg-boot jeecgboot/jeecg-boot 是一个基于 Spring Boot 的 Java 框架,用于快速开发企业级应用。适合在 Java 应用开发中使用,提高开发效率和代码质量。特点是…...
腾讯混元翻译模型实战:跨境电商多语言商品描述生成案例
腾讯混元翻译模型实战:跨境电商多语言商品描述生成案例 1. 项目背景与价值 跨境电商企业面临一个共同挑战:如何高效地将商品信息翻译成多种语言。传统人工翻译成本高、周期长,而通用翻译工具又难以满足电商场景的专业需求。 腾讯混元翻译模…...
OpenClaw+Qwen3.5-4B-Claude:个人知识库自动更新系统
OpenClawQwen3.5-4B-Claude:个人知识库自动更新系统 1. 为什么需要自动化知识管理 作为一个技术从业者,我每天都会接触到大量信息——技术博客、论文摘要、行业动态、代码库更新等等。过去三年里,我尝试过各种笔记工具和知识管理方法&#…...
从YOLOv5到YOLOv8:停车位检测模型演进与实战性能对比
1. YOLO系列模型的技术演进路径 YOLO(You Only Look Once)系列模型作为目标检测领域的标杆算法,从2015年诞生至今已经经历了多次重大迭代。每次版本更新都带来了显著的性能提升和架构创新,这使得YOLO系列在实时目标检测任务中始终…...
从镜像到实战:星图OpenClaw+Qwen3-32B完整链路
从镜像到实战:星图OpenClawQwen3-32B完整链路 1. 为什么选择OpenClawQwen3-32B组合 去年冬天,当我第一次尝试用AI自动化处理周报时,发现公有云方案总在数据隐私和功能定制上让我束手束脚。直到遇见星图平台的OpenClaw镜像与Qwen3-32B组合&a…...
Python环境变量冲突避坑指南:解决Fatal Python error: init_sys_streams错误(conda+Pycharm版)
Python环境变量冲突避坑指南:解决Fatal Python error: init_sys_streams错误(condaPycharm版) 当你在PyCharm中运行一个conda虚拟环境下的Python项目时,突然弹出一条令人窒息的错误信息:Fatal Python error: init_sys_…...
