mirror of
https://gitee.com/dromara/RuoYi-Vue-Plus.git
synced 2026-09-20 02:08:15 +08:00
服务申请
This commit is contained in:
parent
b3a9ad0af5
commit
fea697a6a9
@ -1,11 +1,15 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import cn.hutool.core.lang.tree.TreeNodeConfig;
|
||||
import cn.hutool.core.lang.tree.TreeUtil;
|
||||
import cn.hutool.core.lang.tree.parser.NodeParser;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 树结构工具类
|
||||
@ -13,18 +17,116 @@ import java.util.List;
|
||||
* @author Wenchao Gong
|
||||
* @date 2021-09-08
|
||||
*/
|
||||
public class TreeUtils {
|
||||
public class TreeUtils
|
||||
{
|
||||
|
||||
public static final TreeNodeConfig DEFAULT_TREE_NODE_CONFIG = new TreeNodeConfig();
|
||||
public static final long DEFAULT_PARENT_ID = 0L;
|
||||
public static final String FIELD_NODE_EXIST = "exist";
|
||||
|
||||
static
|
||||
{
|
||||
static {
|
||||
DEFAULT_TREE_NODE_CONFIG.setNameKey("label");
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置默认 parentId
|
||||
*
|
||||
* @param list
|
||||
* @param nodeParser
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> List<Tree<Long>> build(List<T> list, NodeParser<T, Long> nodeParser)
|
||||
{
|
||||
Long parentId = 0L;
|
||||
return TreeUtil.build(list, parentId, DEFAULT_TREE_NODE_CONFIG, nodeParser);
|
||||
return TreeUtil.build(list, DEFAULT_PARENT_ID, DEFAULT_TREE_NODE_CONFIG, nodeParser);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 树构建
|
||||
*
|
||||
* @param <T> 转换的实体 为数据源里的对象类型
|
||||
* @param <E> ID类型
|
||||
* @param list 源数据集合
|
||||
* @param parentId 最顶层父id值 一般为 0 之类
|
||||
* @param nodeParser 转换器
|
||||
* @param needExistField 是否需要 已存在字段
|
||||
* @return List
|
||||
*/
|
||||
public static <T, E> List<Tree<E>> build(List<T> list, E parentId, NodeParser<T, E> nodeParser,
|
||||
boolean needExistField)
|
||||
{
|
||||
final List<Tree<E>> treeList = CollUtil.newArrayList();
|
||||
final TreeNodeConfig treeNodeConfig = DEFAULT_TREE_NODE_CONFIG;
|
||||
Tree<E> tree;
|
||||
for (T obj : list) {
|
||||
tree = new Tree<>(treeNodeConfig);
|
||||
nodeParser.parse(obj, tree);
|
||||
treeList.add(tree);
|
||||
}
|
||||
|
||||
List<Tree<E>> finalTreeList = CollUtil.newArrayList();
|
||||
for (Tree<E> node : treeList) {
|
||||
if (ObjectUtil.equals(parentId, node.getParentId())) {
|
||||
finalTreeList.add(node);
|
||||
innerBuild(treeList, node, 0, treeNodeConfig.getDeep(), needExistField);
|
||||
}
|
||||
}
|
||||
// 内存每层已经排过了 这是最外层排序
|
||||
finalTreeList = finalTreeList.stream().sorted().collect(Collectors.toList());
|
||||
return finalTreeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归处理
|
||||
*
|
||||
* @param treeNodes 数据集合
|
||||
* @param parentNode 当前节点
|
||||
* @param deep 已递归深度
|
||||
* @param maxDeep 最大递归深度 可能为null即不限制
|
||||
* @param needExistField 是否需要 已存在字段
|
||||
*/
|
||||
private static <T> void innerBuild(List<Tree<T>> treeNodes, Tree<T> parentNode, int deep, Integer maxDeep,
|
||||
boolean needExistField)
|
||||
{
|
||||
if (CollUtil.isEmpty(treeNodes)) {
|
||||
return;
|
||||
}
|
||||
//maxDeep 可能为空
|
||||
if (maxDeep != null && deep >= maxDeep) {
|
||||
return;
|
||||
}
|
||||
// 每层排序 TreeNodeMap 实现了Comparable接口
|
||||
treeNodes = treeNodes.stream().sorted().collect(Collectors.toList());
|
||||
for (Tree<T> childNode : treeNodes) {
|
||||
if (parentNode.getId().equals(childNode.getParentId())) {
|
||||
List<Tree<T>> children = parentNode.getChildren();
|
||||
if (children == null) {
|
||||
children = CollUtil.newArrayList();
|
||||
parentNode.setChildren(children);
|
||||
}
|
||||
children.add(childNode);
|
||||
childNode.setParent(parentNode);
|
||||
if (needExistField) {
|
||||
Object pobj = parentNode.get(FIELD_NODE_EXIST);
|
||||
boolean exist = pobj == null ? true : (boolean) pobj;
|
||||
if (exist && !CollectionUtils.isEmpty(children)) {
|
||||
long count = children.stream().filter(t -> {
|
||||
Object obj = t.get(FIELD_NODE_EXIST);
|
||||
if (obj != null) {
|
||||
return !(boolean) obj;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}).count();
|
||||
if (count > 0) {
|
||||
exist = false;
|
||||
}
|
||||
}
|
||||
parentNode.put(FIELD_NODE_EXIST, exist);
|
||||
}
|
||||
innerBuild(treeNodes, childNode, deep + 1, maxDeep, needExistField);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,21 +3,22 @@ package com.ruoyi.isc.service.impl;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import cn.hutool.core.lang.tree.parser.NodeParser;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.ruoyi.common.constant.UserConstants;
|
||||
import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
|
||||
import com.ruoyi.common.utils.FullPathUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.TreeUtils;
|
||||
import com.ruoyi.isc.domain.IscService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.ruoyi.isc.domain.IscServiceCate;
|
||||
import com.ruoyi.isc.domain.bo.IscServiceCateBo;
|
||||
import com.ruoyi.isc.domain.vo.IscServiceCateVo;
|
||||
import com.ruoyi.isc.domain.IscServiceCate;
|
||||
import com.ruoyi.isc.mapper.IscServiceCateMapper;
|
||||
import com.ruoyi.isc.service.IIscServiceCateService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
@ -35,7 +36,6 @@ public class IscServiceCateServiceImpl extends ServicePlusImpl<IscServiceCateMap
|
||||
public static final String FIELD_NODE_TYPE = "type";
|
||||
public static final int NODE_TYPE_SERVICE = 1;
|
||||
public static final int NODE_TYPE_CATE = 0;
|
||||
public static final String FIELD_NODE_EXIST = "exist";
|
||||
|
||||
@Override
|
||||
public IscServiceCateVo queryById(Long cateId){
|
||||
@ -158,7 +158,7 @@ public class IscServiceCateServiceImpl extends ServicePlusImpl<IscServiceCateMap
|
||||
final Map<String, List<IscService>> cateServiceMap = isServiceTree ? serviceList.stream()
|
||||
.collect(Collectors.groupingBy(IscService::getCateFullPath)) : null;
|
||||
|
||||
return TreeUtils.build(cates, (cate, tree) -> {
|
||||
NodeParser<IscServiceCate, Long> parser = (cate, tree) -> {
|
||||
tree.setId(cate.getCateId());
|
||||
tree.setParentId(cate.getParentId());
|
||||
tree.setName(cate.getCateName());
|
||||
@ -166,8 +166,10 @@ public class IscServiceCateServiceImpl extends ServicePlusImpl<IscServiceCateMap
|
||||
tree.putExtra(FIELD_FULL_PATH, cate.getFullPath());
|
||||
if(isServiceTree) {
|
||||
tree.putExtra(FIELD_NODE_TYPE, NODE_TYPE_CATE);
|
||||
boolean exist = true;
|
||||
List<IscService> services = cateServiceMap.get(cate.getFullPath());
|
||||
if(CollectionUtil.isEmpty(services)) {
|
||||
tree.putExtra(TreeUtils.FIELD_NODE_EXIST, true);
|
||||
return;
|
||||
}
|
||||
for (int index = 0; index < services.size(); index++)
|
||||
@ -182,14 +184,18 @@ public class IscServiceCateServiceImpl extends ServicePlusImpl<IscServiceCateMap
|
||||
child.setId(service.getServiceId());
|
||||
child.setName(service.getServiceName());
|
||||
child.setWeight(index);
|
||||
child.setParent(tree);
|
||||
child.setParentId(tree.getId());
|
||||
child.putExtra(FIELD_NODE_TYPE, NODE_TYPE_SERVICE);
|
||||
child.putExtra(FIELD_NODE_EXIST, exitsIds.contains(service.getServiceId()));
|
||||
boolean contains = exitsIds.contains(service.getServiceId());
|
||||
child.putExtra(TreeUtils.FIELD_NODE_EXIST, contains);
|
||||
children.add(child);
|
||||
if(exist && !contains) {
|
||||
exist = false;
|
||||
}
|
||||
}
|
||||
tree.putExtra(TreeUtils.FIELD_NODE_EXIST, exist);
|
||||
}
|
||||
});
|
||||
};
|
||||
return TreeUtils.build(cates, TreeUtils.DEFAULT_PARENT_ID, parser, isServiceTree);
|
||||
}
|
||||
|
||||
private Map<Long, String> batchCateName(List<IscServiceCate> list) {
|
||||
|
||||
@ -74,7 +74,7 @@
|
||||
|
||||
<el-table v-loading="loading" :data="applicationList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="应用ID" align="center" prop="applicationId" v-if="true" width="50"/>
|
||||
<el-table-column label="应用ID" align="center" prop="applicationId" v-if="true" width="80"/>
|
||||
<el-table-column label="应用名称" align="center" prop="applicationName" >
|
||||
<template slot-scope="scope">
|
||||
<router-link :to="'/isc/app-service/index/' + scope.row.applicationId" class="link-type">
|
||||
|
||||
@ -146,8 +146,10 @@
|
||||
<!-- 添加或修改应用服务对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="服务" prop="serviceId">
|
||||
<treeselect v-model="form.serviceId" :options="appServiceOptions" :show-count="true" :normalizer="normalizer" placeholder="请选择服务" style="width:215px"/>
|
||||
<el-form-item label="服务名称" prop="serviceId">
|
||||
<!-- :disable-branch-nodes="true" 只能选叶子节点 -->
|
||||
<treeselect v-model="form.serviceId" :options="appServiceOptions" :show-count="true" :normalizer="normalizer"
|
||||
:disable-branch-nodes="true" placeholder="请选择服务" style="width:215px"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="启用状态">
|
||||
<el-radio-group v-model="form.enabled">
|
||||
@ -166,17 +168,17 @@
|
||||
placeholder="选择到期时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="天配额" prop="quotaDays">
|
||||
<el-input v-model="form.quotaDays" placeholder="请输入天配额" />
|
||||
<el-form-item label="日配额" prop="quotaDays">
|
||||
<el-input-number v-model="form.quotaDays" step="1000" placeholder="请输入日配额" />
|
||||
</el-form-item>
|
||||
<el-form-item label="小时配额" prop="quotaHours">
|
||||
<el-input v-model="form.quotaHours" placeholder="请输入小时配额" />
|
||||
<el-input-number v-model="form.quotaHours" step="100" placeholder="请输入小时配额" />
|
||||
</el-form-item>
|
||||
<el-form-item label="分钟配额" prop="quotaMinutes">
|
||||
<el-input v-model="form.quotaMinutes" placeholder="请输入分钟配额" />
|
||||
<el-input-number v-model="form.quotaMinutes" step="10" placeholder="请输入分钟配额" />
|
||||
</el-form-item>
|
||||
<el-form-item label="秒配额" prop="quotaSeconds">
|
||||
<el-input v-model="form.quotaSeconds" placeholder="请输入秒配额" />
|
||||
<el-input-number v-model="form.quotaSeconds" placeholder="请输入秒配额" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
@ -231,11 +233,12 @@ export default {
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
applicationId: undefined,
|
||||
enabled: undefined,
|
||||
status: undefined,
|
||||
applicationId: undefined
|
||||
},
|
||||
applicationName: undefined,
|
||||
applicationId: undefined,
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 表单校验
|
||||
@ -243,9 +246,6 @@ export default {
|
||||
serviceId: [
|
||||
{ required: true, message: "服务ID不能为空", trigger: "blur" }
|
||||
],
|
||||
applicationId: [
|
||||
{ required: true, message: "应用ID不能为空", trigger: "blur" }
|
||||
],
|
||||
enabled: [
|
||||
{ required: true, message: "启用状态不能为空", trigger: "blur" }
|
||||
],
|
||||
@ -254,7 +254,7 @@ export default {
|
||||
},
|
||||
created() {
|
||||
const applicationId = this.$route.params && this.$route.params.applicationId;
|
||||
this.form.applicationId = applicationId;
|
||||
this.applicationId = applicationId;
|
||||
this.queryParams.applicationId = applicationId;
|
||||
this.getList(applicationId);
|
||||
this.getDicts("sys_normal_disable").then(response => {
|
||||
@ -293,14 +293,13 @@ export default {
|
||||
},
|
||||
//树节点转换
|
||||
normalizer(node) {
|
||||
const data = {
|
||||
return {
|
||||
id: node.id,
|
||||
label: node.label,
|
||||
children: node.children,
|
||||
disabled: true
|
||||
}
|
||||
console.log(data)
|
||||
return
|
||||
isDisabled: node.exist,
|
||||
type: node.type
|
||||
};
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
@ -316,17 +315,11 @@ export default {
|
||||
enabled: "0",
|
||||
applyType: undefined,
|
||||
status: [],
|
||||
virtualAddr: undefined,
|
||||
endTime: undefined,
|
||||
quotaDays: undefined,
|
||||
quotaHours: undefined,
|
||||
quotaMinutes: undefined,
|
||||
quotaSeconds: undefined,
|
||||
createBy: undefined,
|
||||
createTime: undefined,
|
||||
updateBy: undefined,
|
||||
updateTime: undefined,
|
||||
delFlag: undefined
|
||||
};
|
||||
this.resetForm("form");
|
||||
},
|
||||
|
||||
Loading…
Reference in New Issue
Block a user