递归遍历树结构,前端传入一整颗树,后端处理这个树,包括生成树的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 沉淀,…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...

热烈祝贺埃文科技正式加入可信数据空间发展联盟
2025年4月29日,在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上,可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞,强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...
加密通信 + 行为分析:运营商行业安全防御体系重构
在数字经济蓬勃发展的时代,运营商作为信息通信网络的核心枢纽,承载着海量用户数据与关键业务传输,其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级,传统安全防护体系逐渐暴露出局限性&a…...

2025-05-08-deepseek本地化部署
title: 2025-05-08-deepseek 本地化部署 tags: 深度学习 程序开发 2025-05-08-deepseek 本地化部署 参考博客 本地部署 DeepSeek:小白也能轻松搞定! 如何给本地部署的 DeepSeek 投喂数据,让他更懂你 [实验目的]:理解系统架构与原…...