From f1208474f771a1c233d7425c8ed13fbaa0d521ac Mon Sep 17 00:00:00 2001
From: baoshiwei <baoshiwei@shlanbao.cn>
Date: 星期三, 12 三月 2025 09:35:13 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/5.X' into 5.X

---
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwCategoryServiceImpl.java |  269 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 269 insertions(+), 0 deletions(-)

diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwCategoryServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwCategoryServiceImpl.java
new file mode 100644
index 0000000..db1b7b7
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwCategoryServiceImpl.java
@@ -0,0 +1,269 @@
+package org.dromara.workflow.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.lang.tree.Tree;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.constant.SystemConstants;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.*;
+import org.dromara.common.mybatis.helper.DataBaseHelper;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.warm.flow.core.service.DefService;
+import org.dromara.warm.flow.orm.entity.FlowDefinition;
+import org.dromara.workflow.common.ConditionalOnEnable;
+import org.dromara.workflow.common.constant.FlowConstant;
+import org.dromara.workflow.domain.FlowCategory;
+import org.dromara.workflow.domain.bo.FlowCategoryBo;
+import org.dromara.workflow.domain.vo.FlowCategoryVo;
+import org.dromara.workflow.mapper.FlwCategoryMapper;
+import org.dromara.workflow.service.IFlwCategoryService;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 娴佺▼鍒嗙被Service涓氬姟灞傚鐞�
+ *
+ * @author may
+ */
+@ConditionalOnEnable
+@RequiredArgsConstructor
+@Service
+public class FlwCategoryServiceImpl implements IFlwCategoryService {
+
+    private final DefService defService;
+    private final FlwCategoryMapper baseMapper;
+
+    /**
+     * 鏌ヨ娴佺▼鍒嗙被
+     *
+     * @param categoryId 涓婚敭
+     * @return 娴佺▼鍒嗙被
+     */
+    @Override
+    public FlowCategoryVo queryById(Long categoryId) {
+        FlowCategoryVo category = baseMapper.selectVoById(categoryId);
+        if (ObjectUtil.isNull(category)) {
+            return null;
+        }
+        FlowCategoryVo parentCategory = baseMapper.selectVoOne(new LambdaQueryWrapper<FlowCategory>()
+            .select(FlowCategory::getCategoryName).eq(FlowCategory::getCategoryId, category.getParentId()));
+        category.setParentName(ObjectUtils.notNullGetter(parentCategory, FlowCategoryVo::getCategoryName));
+        return category;
+    }
+
+    /**
+     * 鏍规嵁娴佺▼鍒嗙被ID鏌ヨ娴佺▼鍒嗙被鍚嶇О
+     *
+     * @param categoryId 娴佺▼鍒嗙被ID
+     * @return 娴佺▼鍒嗙被鍚嶇О
+     */
+    @Cacheable(cacheNames = FlowConstant.FLOW_CATEGORY_NAME, key = "#categoryId")
+    @Override
+    public String selectCategoryNameById(Long categoryId) {
+        if (ObjectUtil.isNull(categoryId)) {
+            return null;
+        }
+        FlowCategory category = baseMapper.selectOne(new LambdaQueryWrapper<FlowCategory>()
+            .select(FlowCategory::getCategoryName).eq(FlowCategory::getCategoryId, categoryId));
+        return ObjectUtils.notNullGetter(category, FlowCategory::getCategoryName);
+    }
+
+    /**
+     * 鏌ヨ绗﹀悎鏉′欢鐨勬祦绋嬪垎绫诲垪琛�
+     *
+     * @param bo 鏌ヨ鏉′欢
+     * @return 娴佺▼鍒嗙被鍒楄〃
+     */
+    @Override
+    public List<FlowCategoryVo> queryList(FlowCategoryBo bo) {
+        LambdaQueryWrapper<FlowCategory> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    /**
+     * 鏌ヨ娴佺▼鍒嗙被鏍戠粨鏋勪俊鎭�
+     *
+     * @param category 娴佺▼鍒嗙被淇℃伅
+     * @return 娴佺▼鍒嗙被鏍戜俊鎭泦鍚�
+     */
+    @Override
+    public List<Tree<String>> selectCategoryTreeList(FlowCategoryBo category) {
+        LambdaQueryWrapper<FlowCategory> lqw = buildQueryWrapper(category);
+        List<FlowCategoryVo> categorys = baseMapper.selectVoList(lqw);
+        if (CollUtil.isEmpty(categorys)) {
+            return CollUtil.newArrayList();
+        }
+        // 鑾峰彇褰撳墠鍒楄〃涓瘡涓�涓妭鐐圭殑parentId锛岀劧鍚庡湪鍒楄〃涓煡鎵炬槸鍚︽湁id涓庡叾parentId瀵瑰簲锛岃嫢鏃犲搴旓紝鍒欒〃鏄庢鏃惰妭鐐瑰垪琛ㄤ腑锛岃鑺傜偣鍦ㄥ綋鍓嶅垪琛ㄤ腑灞炰簬椤剁骇鑺傜偣
+        List<Tree<String>> treeList = CollUtil.newArrayList();
+        for (FlowCategoryVo d : categorys) {
+            String parentId = d.getParentId().toString();
+            FlowCategoryVo categoryVo = StreamUtils.findFirst(categorys, it -> it.getCategoryId().toString().equals(parentId));
+            if (ObjectUtil.isNull(categoryVo)) {
+                List<Tree<String>> trees = TreeBuildUtils.build(categorys, parentId, (dept, tree) ->
+                    tree.setId(dept.getCategoryId().toString())
+                        .setParentId(dept.getParentId().toString())
+                        .setName(dept.getCategoryName())
+                        .setWeight(dept.getOrderNum()));
+                Tree<String> tree = StreamUtils.findFirst(trees, it -> it.getId().equals(d.getCategoryId().toString()));
+                treeList.add(tree);
+            }
+        }
+        return treeList;
+    }
+
+    /**
+     * 鏍¢獙娴佺▼鍒嗙被鏄惁鏈夋暟鎹潈闄�
+     *
+     * @param categoryId 娴佺▼鍒嗙被ID
+     */
+    @Override
+    public void checkCategoryDataScope(Long categoryId) {
+        if (ObjectUtil.isNull(categoryId)) {
+            return;
+        }
+        if (LoginHelper.isSuperAdmin()) {
+            return;
+        }
+        if (baseMapper.countCategoryById(categoryId) == 0) {
+            throw new ServiceException("娌℃湁鏉冮檺璁块棶娴佺▼鍒嗙被鏁版嵁锛�");
+        }
+    }
+
+    /**
+     * 鏍¢獙娴佺▼鍒嗙被鍚嶇О鏄惁鍞竴
+     *
+     * @param category 娴佺▼鍒嗙被淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    public boolean checkCategoryNameUnique(FlowCategoryBo category) {
+        boolean exist = baseMapper.exists(new LambdaQueryWrapper<FlowCategory>()
+            .eq(FlowCategory::getCategoryName, category.getCategoryName())
+            .eq(FlowCategory::getParentId, category.getParentId())
+            .ne(ObjectUtil.isNotNull(category.getCategoryId()), FlowCategory::getCategoryId, category.getCategoryId()));
+        return !exist;
+    }
+
+    /**
+     * 鏌ヨ娴佺▼鍒嗙被鏄惁瀛樺湪娴佺▼瀹氫箟
+     *
+     * @param categoryId 娴佺▼鍒嗙被ID
+     * @return 缁撴灉 true 瀛樺湪 false 涓嶅瓨鍦�
+     */
+    @Override
+    public boolean checkCategoryExistDefinition(Long categoryId) {
+        FlowDefinition definition = new FlowDefinition();
+        definition.setCategory(categoryId.toString());
+        return defService.exists(definition);
+    }
+
+    /**
+     * 鏄惁瀛樺湪娴佺▼鍒嗙被瀛愯妭鐐�
+     *
+     * @param categoryId 娴佺▼鍒嗙被ID
+     * @return 缁撴灉
+     */
+    @Override
+    public boolean hasChildByCategoryId(Long categoryId) {
+        return baseMapper.exists(new LambdaQueryWrapper<FlowCategory>()
+            .eq(FlowCategory::getParentId, categoryId));
+    }
+
+    private LambdaQueryWrapper<FlowCategory> buildQueryWrapper(FlowCategoryBo bo) {
+        LambdaQueryWrapper<FlowCategory> lqw = Wrappers.lambdaQuery();
+        lqw.eq(FlowCategory::getDelFlag, SystemConstants.NORMAL);
+        lqw.eq(ObjectUtil.isNotNull(bo.getCategoryId()), FlowCategory::getCategoryId, bo.getCategoryId());
+        lqw.eq(ObjectUtil.isNotNull(bo.getParentId()), FlowCategory::getParentId, bo.getParentId());
+        lqw.like(StringUtils.isNotBlank(bo.getCategoryName()), FlowCategory::getCategoryName, bo.getCategoryName());
+        lqw.orderByAsc(FlowCategory::getAncestors);
+        lqw.orderByAsc(FlowCategory::getParentId);
+        lqw.orderByAsc(FlowCategory::getOrderNum);
+        lqw.orderByAsc(FlowCategory::getCategoryId);
+        return lqw;
+    }
+
+    /**
+     * 鏂板娴佺▼鍒嗙被
+     *
+     * @param bo 娴佺▼鍒嗙被
+     * @return 鏄惁鏂板鎴愬姛
+     */
+    @Override
+    public int insertByBo(FlowCategoryBo bo) {
+        FlowCategory info = baseMapper.selectById(bo.getParentId());
+        FlowCategory category = MapstructUtils.convert(bo, FlowCategory.class);
+        category.setAncestors(info.getAncestors() + StringUtils.SEPARATOR + category.getParentId());
+        return baseMapper.insert(category);
+    }
+
+    /**
+     * 淇敼娴佺▼鍒嗙被
+     *
+     * @param bo 娴佺▼鍒嗙被
+     * @return 鏄惁淇敼鎴愬姛
+     */
+    @CacheEvict(cacheNames = FlowConstant.FLOW_CATEGORY_NAME, key = "#bo.categoryId")
+    @Override
+    public int updateByBo(FlowCategoryBo bo) {
+        FlowCategory category = MapstructUtils.convert(bo, FlowCategory.class);
+        FlowCategory oldCategory = baseMapper.selectById(category.getCategoryId());
+        if (ObjectUtil.isNull(oldCategory)) {
+            throw new ServiceException("娴佺▼鍒嗙被涓嶅瓨鍦紝鏃犳硶淇敼");
+        }
+        if (!oldCategory.getParentId().equals(category.getParentId())) {
+            // 濡傛灉鏄柊鐖舵祦绋嬪垎绫� 鍒欐牎楠屾槸鍚﹀叿鏈夋柊鐖舵祦绋嬪垎绫绘潈闄� 閬垮厤瓒婃潈
+            this.checkCategoryDataScope(category.getParentId());
+            FlowCategory newParentCategory = baseMapper.selectById(category.getParentId());
+            if (ObjectUtil.isNotNull(newParentCategory)) {
+                String newAncestors = newParentCategory.getAncestors() + StringUtils.SEPARATOR + newParentCategory.getCategoryId();
+                String oldAncestors = oldCategory.getAncestors();
+                category.setAncestors(newAncestors);
+                updateCategoryChildren(category.getCategoryId(), newAncestors, oldAncestors);
+            }
+        } else {
+            category.setAncestors(oldCategory.getAncestors());
+        }
+        return baseMapper.updateById(category);
+    }
+
+    /**
+     * 淇敼瀛愬厓绱犲叧绯�
+     *
+     * @param categoryId   琚慨鏀圭殑娴佺▼鍒嗙被ID
+     * @param newAncestors 鏂扮殑鐖禝D闆嗗悎
+     * @param oldAncestors 鏃х殑鐖禝D闆嗗悎
+     */
+    private void updateCategoryChildren(Long categoryId, String newAncestors, String oldAncestors) {
+        List<FlowCategory> children = baseMapper.selectList(new LambdaQueryWrapper<FlowCategory>()
+            .apply(DataBaseHelper.findInSet(categoryId, "ancestors")));
+        List<FlowCategory> list = new ArrayList<>();
+        for (FlowCategory child : children) {
+            FlowCategory category = new FlowCategory();
+            category.setCategoryId(child.getCategoryId());
+            category.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
+            list.add(category);
+        }
+        if (CollUtil.isNotEmpty(list)) {
+            baseMapper.updateBatchById(list);
+        }
+    }
+
+    /**
+     * 鍒犻櫎娴佺▼鍒嗙被淇℃伅
+     *
+     * @param categoryId 涓婚敭
+     * @return 鏄惁鍒犻櫎鎴愬姛
+     */
+    @CacheEvict(cacheNames = FlowConstant.FLOW_CATEGORY_NAME, key = "#categoryId")
+    @Override
+    public int deleteWithValidById(Long categoryId) {
+        return baseMapper.deleteById(categoryId);
+    }
+}

--
Gitblit v1.9.3