递归遍历树结构,前端传入一整颗树,后端处理这个树,包括生成树的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 沉淀,…...
【接口协议】FPGA 驱动 VGA 显示实验(一)原理部分
目录 VGA介绍 VGA 接口管脚 VGA 色彩原理 VGA 工作原理 VGA 时序 VGA介绍 VGA(Video Graphics Array)视频图形阵列是 IBM 于 1987 年提出的一个使用模拟信号的电脑显示标准。VGA 接口即电脑采用 VGA 标准输出数据的专用接口。VGA 接口共有 15 针&am…...
lychee-rerank-mm开源部署:GitHub仓库结构说明+自定义模型替换路径
lychee-rerank-mm开源部署:GitHub仓库结构说明自定义模型替换路径 1. 项目概述 lychee-rerank-mm是一个基于Qwen2.5-VL多模态大模型架构的专业重排序系统,专门为RTX 4090显卡优化设计。这个项目实现了文本描述与批量图片的智能相关性分析和自动排序功能…...
锁相放大器的作用
锁相放大器是一种可以从干扰极大的环境中分离出特定载波频率信号的放大器。锁相放大器是由普林斯顿大学的物理学家罗伯特H迪克发明的。 锁相放大器技术于20 世纪30 年代问世,并于20 世纪中期进入商业化应用阶段。锁相放大器是一种对交变信号进行相敏检波的放大器。它利用和被测…...
C++11包装器实战:从回调函数到命令模式的优雅实现
1. C11包装器的前世今生 记得我第一次接触C函数回调是在大学时期做一个简单的命令行工具。当时用C语言写了个函数指针数组,光是类型声明就写了三行代码,队友看到后直呼"这写的什么鬼东西"。后来接触到C仿函数,虽然解决了类型问题&a…...
立创EDA梵高星空灯光画改造:LED点阵驱动与PCB打板工艺详解
立创EDA梵高星空灯光画改造:LED点阵驱动与PCB打板工艺详解 最近看到不少朋友对那种会发光的装饰画很感兴趣,想把喜欢的画作变成一件独特的电子艺术品。正好,我之前用立创EDA设计并制作了一幅梵高《星空》的灯光画,效果非常棒。今天…...
【Linux】Deepin系统下配置abraunegg/onedrive实现文件自动同步的完整指南
1. 为什么选择abraunegg/onedrive 作为一个长期使用Deepin系统的老用户,我深知在Linux环境下同步文件的痛点。微软官方没有提供Linux版的OneDrive客户端,这让很多从Windows转过来的用户非常不适应。经过多次尝试,我发现abraunegg/onedrive这个…...
立创EDA开源项目:基于RDA5807的徽章式FM收音机硬件设计详解
立创EDA开源项目:基于RDA5807的徽章式FM收音机硬件设计详解 最近在立创开源硬件平台看到一个挺有意思的项目——一个可以别在身上的徽章式FM收音机。它把收音机芯片、充电管理、电池和外壳都集成到了一块小小的板子上,设计思路很巧妙,特别适合…...
双馈发电机控制必看:动态模型中的磁链方程详解与仿真验证
双馈发电机磁链方程工程解析:从动态建模到实时仿真的高阶实践 风电行业的快速发展对双馈感应发电机(DFIG)的动态控制精度提出了更高要求。作为核心环节的磁链方程,其物理本质与工程实现之间的鸿沟常常成为控制策略失效的关键症结。…...
机器视觉入门基础相关概念二 ——从坐标变换到相机内参
1. 从2D坐标变换说起:平移、旋转与缩放 当你第一次接触机器视觉时,可能会被各种坐标系和变换搞得晕头转向。别担心,我们从一个更熟悉的场景开始——2D平面上的图形变换。想象你正在用手机修图软件调整一张照片:拖动图片是平移&…...
Nginx 性能调优与深度监控实战全解析
前言在全球互联网流量持续激增的背景下,Nginx 作为高性能的反向代理、负载均衡器和 HTTP 服务器,已成为企业级 Web 架构中的核心组件。其性能表现直接决定了用户访问体验和业务服务的连续性,一旦 Nginx 出现性能瓶颈或故障,将直接…...
