Ver Fonte

资产类型

LIVE_YE há 2 meses atrás
pai
commit
75f334ee3c

+ 62 - 3
ruoyi-modules/ruoyi-wuye/src/main/java/org/dromara/controller/asset/AssetTypeController.java

@@ -1,19 +1,20 @@
 package org.dromara.controller.asset;
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.hutool.core.lang.tree.Tree;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.NotEmpty;
 import jakarta.validation.constraints.NotNull;
 import lombok.RequiredArgsConstructor;
+import org.apache.commons.lang3.ArrayUtils;
 import org.dromara.common.core.domain.R;
+import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.core.validate.AddGroup;
 import org.dromara.common.core.validate.EditGroup;
 import org.dromara.common.excel.utils.ExcelUtil;
 import org.dromara.common.idempotent.annotation.RepeatSubmit;
 import org.dromara.common.log.annotation.Log;
 import org.dromara.common.log.enums.BusinessType;
-import org.dromara.common.mybatis.core.page.PageQuery;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.web.core.BaseController;
 import org.dromara.domain.asset.bo.AssetTypeBo;
 import org.dromara.domain.asset.vo.AssetTypeVo;
@@ -23,6 +24,8 @@ import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
 
+import static org.dromara.common.core.constant.Constants.ONE;
+
 /**
  * 资产类型
  *
@@ -40,12 +43,34 @@ public class AssetTypeController extends BaseController {
     /**
      * 查询资产类型列表
      */
-    @SaCheckPermission("wuYe:assetType:list")
+    /*@SaCheckPermission("wuYe:assetType:list")
     @GetMapping("/list")
     public TableDataInfo<AssetTypeVo> list(AssetTypeBo bo, PageQuery pageQuery) {
         return assetTypeService.queryPageList(bo, pageQuery);
+    }*/
+
+    /**
+     * 查询资产类型列表(不分页)
+     */
+    @SaCheckPermission("wuYe:assetType:list")
+    @GetMapping("/list")
+    public List<AssetTypeVo> list(AssetTypeBo bo) {
+        return assetTypeService.queryList(bo);
+    }
+
+    /**
+     * 查询部门列表(排除节点)
+     */
+    @SaCheckPermission("wuYe:assetType:list")
+    @GetMapping("/list/exclude/{assetId}")
+    public R<List<AssetTypeVo>> excludeChild(@PathVariable Long assetId)
+    {
+        List<AssetTypeVo> assetTypes = assetTypeService.queryList(new AssetTypeBo());
+        assetTypes.removeIf(d -> d.getAssetId().intValue() == assetId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), assetId + ""));
+        return R.ok(assetTypes);
     }
 
+
     /**
      * 导出资产类型列表
      */
@@ -77,6 +102,10 @@ public class AssetTypeController extends BaseController {
     @RepeatSubmit()
     @PostMapping()
     public R<Void> add(@Validated(AddGroup.class) @RequestBody AssetTypeBo bo) {
+        if (!assetTypeService.checkAssetTypeNameUnique(bo))
+        {
+            return R.fail("新增资产'" + bo.getAssetName() + "'失败,资产名称已存在");
+        }
         return toAjax(assetTypeService.insertByBo(bo));
     }
 
@@ -88,6 +117,19 @@ public class AssetTypeController extends BaseController {
     @RepeatSubmit()
     @PostMapping("/put")
     public R<Void> edit(@Validated(EditGroup.class) @RequestBody AssetTypeBo bo) {
+        Long assetId = bo.getAssetId();
+        if (!assetTypeService.checkAssetTypeNameUnique(bo))
+        {
+            return R.fail("新增资产'" + bo.getAssetName() + "'失败,资产名称已存在");
+        }
+        else if (bo.getParentId().equals(assetId))
+        {
+            return R.fail("修改资产'" + bo.getAssetName() + "'失败,上级资产不能是自己");
+        }
+        else if (StringUtils.equals(ONE, bo.getStatus()) && assetTypeService.selectNormalChildrenAssetById(assetId) > 0)
+        {
+            return R.fail("该部门包含未停用的子部门!");
+        }
         return toAjax(assetTypeService.updateByBo(bo));
     }
 
@@ -101,6 +143,23 @@ public class AssetTypeController extends BaseController {
     @GetMapping("/delete/{assetIds}")
     public R<Void> remove(@NotEmpty(message = "主键不能为空")
                           @PathVariable Long[] assetIds) {
+        for (Long assetId : assetIds) {
+            if (assetTypeService.hasChildByAssetId(assetId))
+            {
+                return R.warn("存在下级资产,不允许删除");
+            }
+        }
         return toAjax(assetTypeService.deleteWithValidByIds(List.of(assetIds), true));
     }
+
+    /**
+     * 获取资产分类树列表
+     */
+    @SaCheckPermission("wuYe:assetType:deptTree")
+    @GetMapping("/deptTree")
+    public R<List<Tree<Long>>> deptTree(AssetTypeBo bo)
+    {
+        return assetTypeService.selectAssetTypeTreeList(bo);
+    }
+
 }

+ 8 - 0
ruoyi-modules/ruoyi-wuye/src/main/java/org/dromara/domain/asset/AssetType.java

@@ -6,6 +6,8 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 
 import java.io.Serial;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * 资产类型对象 asset_type
@@ -59,4 +61,10 @@ public class AssetType extends TenantEntity {
     private String delFlag;
 
 
+    /** 父资产名称 */
+    private String parentName;
+    /** 子资产 */
+    private List<AssetType> children = new ArrayList<AssetType>();
+
+
 }

+ 12 - 0
ruoyi-modules/ruoyi-wuye/src/main/java/org/dromara/domain/asset/bo/AssetTypeBo.java

@@ -8,6 +8,9 @@ import org.dromara.common.core.validate.EditGroup;
 import org.dromara.common.mybatis.core.domain.BaseEntity;
 import org.dromara.domain.asset.AssetType;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * 资产类型业务对象 asset_type
  *
@@ -51,4 +54,13 @@ public class AssetTypeBo extends BaseEntity {
     private String status;
 
 
+    /** 删除标志(N代表存在 Y代表删除) */
+    private String delFlag;
+
+    /** 父资产名称 */
+    private String parentName;
+    /** 子资产 */
+    private List<AssetType> children = new ArrayList<AssetType>();
+
+
 }

+ 11 - 1
ruoyi-modules/ruoyi-wuye/src/main/java/org/dromara/domain/asset/vo/AssetTypeVo.java

@@ -11,7 +11,8 @@ import org.dromara.domain.asset.AssetType;
 
 import java.io.Serial;
 import java.io.Serializable;
-
+import java.util.ArrayList;
+import java.util.List;
 
 
 /**
@@ -66,4 +67,13 @@ public class AssetTypeVo implements Serializable {
     private String status;
 
 
+    /** 删除标志(N代表存在 Y代表删除) */
+    private String delFlag;
+
+    /** 父资产名称 */
+    private String parentName;
+    /** 子资产 */
+    private List<AssetType> children = new ArrayList<AssetType>();
+
+
 }

+ 14 - 0
ruoyi-modules/ruoyi-wuye/src/main/java/org/dromara/mapper/AssetTypeMapper.java

@@ -1,10 +1,13 @@
 package org.dromara.mapper;
 
 
+import org.apache.ibatis.annotations.Param;
 import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
 import org.dromara.domain.asset.AssetType;
 import org.dromara.domain.asset.vo.AssetTypeVo;
 
+import java.util.List;
+
 /**
  * 资产类型Mapper接口
  *
@@ -13,4 +16,15 @@ import org.dromara.domain.asset.vo.AssetTypeVo;
  */
 public interface AssetTypeMapper extends BaseMapperPlus<AssetType, AssetTypeVo> {
 
+    AssetTypeVo checkAssetNameUnique(@Param("assetName")String assetName, @Param("parentId")Long parentId);
+
+    int selectNormalChildrenAssetById(@Param("assetId")Long assetId);
+
+    int hasChildByAssetId(@Param("assetId")Long assetId);
+
+    AssetTypeVo selectAssetTypeByAssetId(@Param("assetId")Long parentId);
+
+    List<AssetTypeVo> selectChildrenAssetTypeById(@Param("assetId")Long assetId);
+
+    void updateAssetTypeChildren(@Param("assetTypes") List<AssetTypeVo> assetTypes);
 }

+ 10 - 0
ruoyi-modules/ruoyi-wuye/src/main/java/org/dromara/service/IAssetTypeService.java

@@ -1,6 +1,8 @@
 package org.dromara.service;
 
 
+import cn.hutool.core.lang.tree.Tree;
+import org.dromara.common.core.domain.R;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.domain.asset.bo.AssetTypeBo;
@@ -66,4 +68,12 @@ public interface IAssetTypeService {
      * @return 是否删除成功
      */
     Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    R<List<Tree<Long>>> selectAssetTypeTreeList(AssetTypeBo bo);
+
+    boolean checkAssetTypeNameUnique(AssetTypeBo bo);
+
+    int selectNormalChildrenAssetById(Long assetId);
+
+    boolean hasChildByAssetId(Long assetId);
 }

+ 118 - 2
ruoyi-modules/ruoyi-wuye/src/main/java/org/dromara/service/impl/AssetTypeServiceImpl.java

@@ -1,11 +1,16 @@
 package org.dromara.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 com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import lombok.RequiredArgsConstructor;
-import org.dromara.common.core.utils.MapstructUtils;
-import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.core.constant.SystemConstants;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.*;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.domain.asset.AssetType;
@@ -19,6 +24,8 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
+import static org.dromara.common.core.constant.Constants.SUCCESS;
+
 /**
  * 资产类型Service业务层处理
  *
@@ -88,6 +95,23 @@ public class AssetTypeServiceImpl implements IAssetTypeService {
      */
     @Override
     public Boolean insertByBo(AssetTypeBo bo) {
+        bo.setCreateTime(DateUtils.getNowDate());
+        AssetTypeVo info = baseMapper.selectAssetTypeByAssetId(bo.getParentId());
+        int i = 0;
+        if (info != null) {
+            // 如果父节点不为正常状态,则不允许新增子节点
+            // 如果父节点不为正常状态,则不允许新增子节点
+            if (!SUCCESS.equals(info.getStatus())) {
+                throw new ServiceException("部门停用,不允许新增");
+            }
+            bo.setAncestors(info.getAncestors() + "," + bo.getParentId());
+            bo.setCreateTime(DateUtils.getNowDate());
+        } else {
+            bo.setParentId(0L);
+            bo.setAncestors("0");
+            bo.setCreateTime(DateUtils.getNowDate());
+        }
+
         AssetType add = MapstructUtils.convert(bo, AssetType.class);
         validEntityBeforeSave(add);
         boolean flag = baseMapper.insert(add) > 0;
@@ -105,11 +129,37 @@ public class AssetTypeServiceImpl implements IAssetTypeService {
      */
     @Override
     public Boolean updateByBo(AssetTypeBo bo) {
+        AssetTypeVo newParentAssetType = baseMapper.selectAssetTypeByAssetId(bo.getParentId());
+        AssetTypeVo oldParentAssetType = baseMapper.selectAssetTypeByAssetId(bo.getAssetId());
+        if (StringUtils.isNotNull(newParentAssetType) && StringUtils.isNotNull(oldParentAssetType)) {
+            String newAncestors = newParentAssetType.getAncestors() + "," + newParentAssetType.getAncestors();
+            String oldAncestors = oldParentAssetType.getAncestors();
+            bo.setAncestors(newAncestors);
+            updateAssetTypeChildren(bo.getAssetId(), newAncestors, oldAncestors);
+        }
+        bo.setUpdateTime(DateUtils.getNowDate());
         AssetType update = MapstructUtils.convert(bo, AssetType.class);
         validEntityBeforeSave(update);
         return baseMapper.updateById(update) > 0;
     }
 
+    /**
+     * 修改子元素关系
+     *
+     * @param assetId      被修改的资产ID
+     * @param newAncestors 新的父ID集合
+     * @param oldAncestors 旧的父ID集合
+     */
+    public void updateAssetTypeChildren(Long assetId, String newAncestors, String oldAncestors) {
+        List<AssetTypeVo> children = baseMapper.selectChildrenAssetTypeById(assetId);
+        for (AssetTypeVo child : children) {
+            child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
+        }
+        if (children.size() > 0) {
+            baseMapper.updateAssetTypeChildren(children);
+        }
+    }
+
     /**
      * 保存前的数据校验
      */
@@ -131,4 +181,70 @@ public class AssetTypeServiceImpl implements IAssetTypeService {
         }
         return baseMapper.deleteByIds(ids) > 0;
     }
+
+    @Override
+    public R<List<Tree<Long>>> selectAssetTypeTreeList(AssetTypeBo bo) {
+        LambdaQueryWrapper<AssetType> lqw = buildQueryWrapper(bo);
+        List<AssetTypeVo> assetTypes = baseMapper.selectVoList(lqw);
+        List<Tree<Long>> assetTypeTree = buildDeptTreeSelect(assetTypes);
+        return R.ok(assetTypeTree);
+    }
+
+    /**
+     * 检验资产名称的唯一性
+     *
+     * @param bo
+     * @return
+     */
+    @Override
+    public boolean checkAssetTypeNameUnique(AssetTypeBo bo) {
+
+        Long assetId = StringUtils.isNull(bo.getAssetId()) ? -1L : bo.getAssetId();
+        AssetTypeVo info = baseMapper.checkAssetNameUnique(bo.getAssetName(), bo.getParentId());
+        if (StringUtils.isNotNull(info) && info.getAssetId().longValue() != assetId.longValue()) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int selectNormalChildrenAssetById(Long assetId) {
+        return baseMapper.selectNormalChildrenAssetById(assetId);
+    }
+
+    /**
+     * 是否存在子节点
+     *
+     * @param assetId 资产ID
+     * @return 结果
+     */
+    @Override
+    public boolean hasChildByAssetId(Long assetId) {
+        int result = baseMapper.hasChildByAssetId(assetId);
+        return result > 0;
+    }
+
+    private List<Tree<Long>> buildDeptTreeSelect(List<AssetTypeVo> assetTypes) {
+        if (CollUtil.isEmpty(assetTypes)) {
+            return CollUtil.newArrayList();
+        }
+        // 获取当前列表中每一个节点的parentId,然后在列表中查找是否有id与其parentId对应,若无对应,则表明此时节点列表中,该节点在当前列表中属于顶级节点
+        List<Tree<Long>> treeList = CollUtil.newArrayList();
+        for (AssetTypeVo d : assetTypes) {
+            Long parentId = d.getParentId();
+            AssetTypeVo assetTypeVo = StreamUtils.findFirst(assetTypes, it -> it.getAssetId().longValue() == parentId);
+            if (ObjectUtil.isNull(assetTypeVo)) {
+                List<Tree<Long>> trees = TreeBuildUtils.build(assetTypes, parentId, (assetType, tree) ->
+                    tree.setId(assetType.getAssetId())
+                        .setParentId(assetType.getParentId())
+                        .setName(assetType.getAssetName())
+                        .setWeight(assetType.getOrderNum())
+                        .putExtra("disabled", SystemConstants.DISABLE.equals(assetType.getStatus())));
+                Tree<Long> tree = StreamUtils.findFirst(trees, it -> it.getId().longValue() == d.getAssetId());
+                treeList.add(tree);
+            }
+        }
+        return treeList;
+    }
+
 }

+ 45 - 0
ruoyi-modules/ruoyi-wuye/src/main/resources/mapper/wuYe/AssetTypeMapper.xml

@@ -4,4 +4,49 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="org.dromara.mapper.AssetTypeMapper">
 
+
+    <resultMap type="org.dromara.domain.asset.vo.AssetTypeVo" id="AssetTypeResult">
+        <result property="assetId"    column="asset_id"    />
+        <result property="parentId"    column="parent_id"    />
+        <result property="ancestors"    column="ancestors"    />
+        <result property="assetName"    column="asset_name"    />
+        <result property="orderNum"    column="order_num"    />
+        <result property="status"    column="status"    />
+    </resultMap>
+
+    <sql id="selectAssetTypeVo">
+        select asset_id, parent_id, ancestors, asset_name, order_num, status, del_flag, create_by, create_time, update_by, update_time from asset_type
+    </sql>
+    <update id="updateAssetTypeChildren" parameterType="java.util.List">
+        update asset_type set ancestors =
+        <foreach collection="assetTypes" item="item" index="index"
+                 separator=" " open="case asset_id" close="end">
+            when #{item.assetId} then #{item.ancestors}
+        </foreach>
+        where asset_id in
+        <foreach collection="assetTypes" item="item" index="index"
+                 separator="," open="(" close=")">
+            #{item.item.assetId}
+        </foreach>
+    </update>
+
+    <select id="checkAssetNameUnique" resultMap="AssetTypeResult">
+        <include refid="selectAssetTypeVo"/>
+        where asset_name=#{assetName} and parent_id = #{parentId} and del_flag = '0' limit 1
+    </select>
+    <select id="selectNormalChildrenAssetById" resultType="java.lang.Integer" parameterType="java.lang.Long">
+        select count(*) from asset_type where status = 0 and del_flag = '0' and find_in_set(#{assetId}, ancestors)
+    </select>
+    <select id="hasChildByAssetId" resultType="java.lang.Integer" parameterType="java.lang.Long">
+        select count(1) from asset_type
+        where del_flag = '0' and parent_id = #{assetId} limit 1
+    </select>
+    <select id="selectAssetTypeByAssetId" parameterType="java.lang.Long" resultMap="AssetTypeResult">
+        <include refid="selectAssetTypeVo"/>
+        where asset_id = #{assetId}
+    </select>
+    <select id="selectChildrenAssetTypeById" resultMap="AssetTypeResult" parameterType="java.lang.Long">
+        select * from asset_type where find_in_set(#{assetId}, ancestors)
+    </select>
+
 </mapper>