diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/annotation/OperatorLog.java b/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/annotation/OperatorLog.java
index feea2bbe..0f463a45 100644
--- a/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/annotation/OperatorLog.java
+++ b/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/annotation/OperatorLog.java
@@ -30,7 +30,7 @@ public @interface OperatorLog {
* - {@link org.springframework.web.bind.annotation.PathVariable}
*
* 使用 @IgnoreParameter 可以忽略参数记录 {@link IgnoreParameter}
- * 如果只需要忽略某个字段可以使用 @Desensitize(toEmpty = true) 标注
+ * 如果只需要忽略某个字段可以使用 {@code @Desensitize(toEmpty = true)} 标注
*/
boolean parameter() default true;
diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/core/generator/CodeGenerators.java b/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/core/generator/CodeGenerators.java
index 9487af06..90d58988 100644
--- a/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/core/generator/CodeGenerators.java
+++ b/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/core/generator/CodeGenerators.java
@@ -45,23 +45,16 @@ public class CodeGenerators {
// .color("blue", "gray", "red", "green", "white")
// .valueUseFields()
// .build(),
- Template.create("code_snippet", "代码片段", "snippet")
+ Template.create("command_template", "命令模板", "command")
.disableUnitTest()
- .cache("code:snippet:{}", "代码片段")
+ .cache("command:template:list", "命令模板列表")
.expire(1, TimeUnit.DAYS)
.vue("asset", "snippet")
- .enableCardView()
.enableDrawerForm()
- .dict("codeSnippetType", "type")
- .comment("代码片段类型")
- .fields("COMMAND", "TEMPLATE")
- .labels("命令", "模板")
- .extra("icon", "icon-code-block", "icon-code")
- .valueUseFields()
- .dict("codeSnippetRender", "prepare_render")
+ .dict("commandTemplateRender", "prepare_render")
.comment("是否使用脚本渲染")
- .fields("UN_RENDER", "RENDER")
- .labels("不渲染", "渲染")
+ .fields("UNUSED", "USED")
+ .labels("不使用", "使用")
.values(0, 1)
.build(),
};
diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/AssetAuthorizedDataServiceController.http b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/AssetAuthorizedDataServiceController.http
index a5661043..577956c2 100644
--- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/AssetAuthorizedDataServiceController.http
+++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/AssetAuthorizedDataServiceController.http
@@ -1,5 +1,5 @@
-### 查询当前用户已授权的主机分组及主机
-GET {{baseUrl}}/asset/authorized-data/current-host-group
+### 查询当前用户已授权的主机
+GET {{baseUrl}}/asset/authorized-data/current-host
Authorization: {{token}}
### 查询当前用户已授权的主机秘钥
diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/AssetAuthorizedDataServiceController.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/AssetAuthorizedDataServiceController.java
index 635ba537..ee6c3f56 100644
--- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/AssetAuthorizedDataServiceController.java
+++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/AssetAuthorizedDataServiceController.java
@@ -4,7 +4,7 @@ import com.orion.ops.framework.log.core.annotation.IgnoreLog;
import com.orion.ops.framework.log.core.enums.IgnoreLogMode;
import com.orion.ops.framework.security.core.utils.SecurityUtils;
import com.orion.ops.framework.web.core.annotation.RestWrapper;
-import com.orion.ops.module.asset.entity.vo.AuthorizedHostGroupWrapperVO;
+import com.orion.ops.module.asset.entity.vo.AuthorizedHostWrapperVO;
import com.orion.ops.module.asset.entity.vo.HostIdentityVO;
import com.orion.ops.module.asset.entity.vo.HostKeyVO;
import com.orion.ops.module.asset.service.AssetAuthorizedDataService;
@@ -38,9 +38,9 @@ public class AssetAuthorizedDataServiceController {
private AssetAuthorizedDataService assetAuthorizedDataService;
@IgnoreLog(IgnoreLogMode.RET)
- @GetMapping("/current-host-group")
- @Operation(summary = "查询当前用户已授权的主机分组及主机")
- public AuthorizedHostGroupWrapperVO getCurrentAuthorizedHostGroup() {
+ @GetMapping("/current-host")
+ @Operation(summary = "查询当前用户已授权的主机")
+ public AuthorizedHostWrapperVO getCurrentAuthorizedHostGroup() {
return assetAuthorizedDataService.getUserAuthorizedHostGroup(SecurityUtils.getLoginUserId());
}
diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/AuthorizedHostGroupWrapperVO.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/AuthorizedHostWrapperVO.java
similarity index 77%
rename from orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/AuthorizedHostGroupWrapperVO.java
rename to orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/AuthorizedHostWrapperVO.java
index 125da1e9..0162f8fb 100644
--- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/AuthorizedHostGroupWrapperVO.java
+++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/AuthorizedHostWrapperVO.java
@@ -7,6 +7,8 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
/**
* 已授权的主机分组 视图响应对象
@@ -20,7 +22,7 @@ import java.util.List;
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "AuthorizedHostGroupWrapperVO", description = "已授权的主机分组 视图响应对象")
-public class AuthorizedHostGroupWrapperVO {
+public class AuthorizedHostWrapperVO {
@Schema(description = "授权的主机分组")
private List groupTree;
@@ -28,4 +30,7 @@ public class AuthorizedHostGroupWrapperVO {
@Schema(description = "授权的主机列表")
private List hostList;
+ @Schema(description = "分组树节点映射 'groupId':hostIdList")
+ private Map> treeNodes;
+
}
diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/HostGroupTreeVO.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/HostGroupTreeVO.java
index 4efee71b..001abaa9 100644
--- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/HostGroupTreeVO.java
+++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/HostGroupTreeVO.java
@@ -44,7 +44,4 @@ public class HostGroupTreeVO implements TreeNode, Serializable
@Schema(description = "子节点")
private List children;
- @Schema(description = "分组内主机")
- private List hostList;
-
}
diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/AssetAuthorizedDataService.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/AssetAuthorizedDataService.java
index b713f12d..d81490f2 100644
--- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/AssetAuthorizedDataService.java
+++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/AssetAuthorizedDataService.java
@@ -1,7 +1,7 @@
package com.orion.ops.module.asset.service;
import com.orion.ops.module.asset.entity.request.asset.AssetAuthorizedDataQueryRequest;
-import com.orion.ops.module.asset.entity.vo.AuthorizedHostGroupWrapperVO;
+import com.orion.ops.module.asset.entity.vo.AuthorizedHostWrapperVO;
import com.orion.ops.module.asset.entity.vo.HostIdentityVO;
import com.orion.ops.module.asset.entity.vo.HostKeyVO;
import com.orion.ops.module.infra.enums.DataPermissionTypeEnum;
@@ -27,12 +27,12 @@ public interface AssetAuthorizedDataService {
List getAuthorizedDataRelId(DataPermissionTypeEnum type, AssetAuthorizedDataQueryRequest request);
/**
- * 查询用户已授权的主机分组和主机
+ * 查询用户已授权的主机主机
*
* @param userId userId
* @return group
*/
- AuthorizedHostGroupWrapperVO getUserAuthorizedHostGroup(Long userId);
+ AuthorizedHostWrapperVO getUserAuthorizedHostGroup(Long userId);
/**
* 查询用户已授权的主机秘钥
diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/AssetAuthorizedDataServiceImpl.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/AssetAuthorizedDataServiceImpl.java
index 1a450c85..20074d0f 100644
--- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/AssetAuthorizedDataServiceImpl.java
+++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/AssetAuthorizedDataServiceImpl.java
@@ -74,7 +74,7 @@ public class AssetAuthorizedDataServiceImpl implements AssetAuthorizedDataServic
}
@Override
- public AuthorizedHostGroupWrapperVO getUserAuthorizedHostGroup(Long userId) {
+ public AuthorizedHostWrapperVO getUserAuthorizedHostGroup(Long userId) {
if (systemUserApi.isAdminUser(userId)) {
// 管理员查询所有
return this.buildUserAuthorizedHostGroup(null);
@@ -83,7 +83,7 @@ public class AssetAuthorizedDataServiceImpl implements AssetAuthorizedDataServic
List authorizedIdList = dataPermissionApi.getUserAuthorizedRelIdList(DataPermissionTypeEnum.HOST_GROUP, userId);
if (authorizedIdList.isEmpty()) {
// 无数据
- return AuthorizedHostGroupWrapperVO.builder()
+ return AuthorizedHostWrapperVO.builder()
.groupTree(Lists.empty())
.hostList(Lists.empty())
.build();
@@ -142,60 +142,103 @@ public class AssetAuthorizedDataServiceImpl implements AssetAuthorizedDataServic
* @param authorizedGroupIdList authorizedGroupIdList
* @return tree
*/
- private AuthorizedHostGroupWrapperVO buildUserAuthorizedHostGroup(List authorizedGroupIdList) {
+ private AuthorizedHostWrapperVO buildUserAuthorizedHostGroup(List authorizedGroupIdList) {
final boolean allData = Lists.isEmpty(authorizedGroupIdList);
- AuthorizedHostGroupWrapperVO wrapper = new AuthorizedHostGroupWrapperVO();
- // 查询主机列表
- List hosts = hostService.getHostListByCache();
- Map hostMap = hosts.stream()
- .collect(Collectors.toMap(HostVO::getId, Function.identity(), Functions.right()));
- // 查询分组引用
- Map> groupRel = dataGroupRelApi.getGroupRelList(DataGroupTypeEnum.HOST);
+ AuthorizedHostWrapperVO wrapper = new AuthorizedHostWrapperVO();
+ // TODO async get 最近连接
+ // TODO async get 我的收藏
// 查询分组
List dataGroup = dataGroupApi.getDataGroupList(DataGroupTypeEnum.HOST);
- // 过滤分组
+ // 查询分组引用
+ Map> dataGroupRel = dataGroupRelApi.getGroupRelList(DataGroupTypeEnum.HOST);
+ // 过滤已经授权的分组
if (!allData) {
// 构建已授权的分组
List relNodes = new ArrayList<>();
TreeUtils.getAllNodes(dataGroup, authorizedGroupIdList, relNodes);
dataGroup = new ArrayList<>(new HashSet<>(relNodes));
}
- // 设置组内数据
+ // 设置主机分组树
+ wrapper.setGroupTree(this.getAuthorizedHostGroupTree(dataGroup));
+ // 设置主机分组下的主机
+ wrapper.setTreeNodes(this.getAuthorizedHostGroupNodes(allData, dataGroup, dataGroupRel, authorizedGroupIdList));
+ // 设置已授权的所有主机
+ wrapper.setHostList(this.getAuthorizedHostList(allData, dataGroup, dataGroupRel, authorizedGroupIdList));
+ // TODO set 最近连接
+ // TODO set 我的收藏
+
+ return wrapper;
+ }
+
+ /**
+ * 构建主机分组树
+ *
+ * @param dataGroup dataGroup
+ * @return tree
+ */
+ private List getAuthorizedHostGroupTree(List dataGroup) {
List groupList = HostGroupConvert.MAPPER.toList(dataGroup);
- groupList.stream()
- // 因为可能父菜单没有授权 这里需要判断组
- .filter(s -> allData || authorizedGroupIdList.contains(s.getId()))
- .forEach(s -> {
- List groupHosts = Lists.stream(groupRel.get(s.getId()))
- .map(hostMap::get)
- .filter(Objects::nonNull)
- .collect(Collectors.toList());
- s.setHostList(groupHosts);
- });
- // 构建主机树
HostGroupTreeVO rootNode = HostGroupTreeVO.builder()
.id(Const.ROOT_PARENT_ID)
.sort(Const.DEFAULT_SORT)
.build();
TreeUtils.buildGroupTree(rootNode, groupList);
- wrapper.setGroupTree(rootNode.getChildren());
- // 设置授权的主机
+ return rootNode.getChildren();
+ }
+
+ /**
+ * 获取主机分组树 主机节点映射
+ *
+ * @param allData allData
+ * @param dataGroup dataGroup
+ * @param dataGroupRel dataGroupRel
+ * @param authorizedGroupIdList authorizedGroupIdList
+ * @return hostGroupId:hostIdList
+ */
+ private Map> getAuthorizedHostGroupNodes(boolean allData,
+ List dataGroup,
+ Map> dataGroupRel,
+ List authorizedGroupIdList) {
+ Map> result = new HashMap<>();
+ dataGroup.stream()
+ .map(DataGroupDTO::getId)
+ // 因为可能父菜单没有授权 这里需要判断分组权限
+ .filter(id -> allData || authorizedGroupIdList.contains(id))
+ .forEach(s -> result.put(String.valueOf(s), dataGroupRel.get(s)));
+ return result;
+ }
+
+ /**
+ * 查询已授权的所有主机
+ *
+ * @param allData allData
+ * @param dataGroup dataGroup
+ * @param dataGroupRel dataGroupRel
+ * @param authorizedGroupIdList authorizedGroupIdList
+ * @return hosts
+ */
+ private List getAuthorizedHostList(boolean allData,
+ List dataGroup,
+ Map> dataGroupRel,
+ List authorizedGroupIdList) {
+ // 查询主机列表
+ List hosts = hostService.getHostListByCache();
+ // 全部数据直接返回
if (allData) {
- // 设置全部数据
- wrapper.setHostList(hosts);
- } else {
- // 仅设置已授权的数据
- List groupHosts = groupList.stream()
- .filter(s -> authorizedGroupIdList.contains(s.getId()))
- .map(s -> groupRel.get(s.getId()))
- .filter(Lists::isNoneEmpty)
- .flatMap(Collection::stream)
- .map(hostMap::get)
- .filter(Objects::nonNull)
- .collect(Collectors.toList());
- wrapper.setHostList(groupHosts);
+ return hosts;
}
- return wrapper;
+ Map hostMap = hosts.stream()
+ .collect(Collectors.toMap(HostVO::getId, Function.identity(), Functions.right()));
+ // 仅设置已授权的数据
+ return dataGroup.stream()
+ .map(DataGroupDTO::getId)
+ .filter(authorizedGroupIdList::contains)
+ .map(dataGroupRel::get)
+ .filter(Lists::isNoneEmpty)
+ .flatMap(Collection::stream)
+ .map(hostMap::get)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
}
}
diff --git a/orion-ops-ui/src/api/asset/asset-authorized-data.ts b/orion-ops-ui/src/api/asset/asset-authorized-data.ts
index 7d7ef0f2..6b96bdc5 100644
--- a/orion-ops-ui/src/api/asset/asset-authorized-data.ts
+++ b/orion-ops-ui/src/api/asset/asset-authorized-data.ts
@@ -5,18 +5,19 @@ import type { HostIdentityQueryResponse } from './host-identity';
import axios from 'axios';
/**
- * 已授权的主机分组 查询响应
+ * 已授权的主机 查询响应
*/
-export interface AuthorizedHostGroupQueryResponse {
+export interface AuthorizedHostQueryResponse {
groupTree: Array;
hostList: Array;
+ treeNodes: Record>;
}
/**
- * 查询当前用户已授权的主机分组
+ * 查询当前用户已授权的主机
*/
-export function getCurrentAuthorizedHostGroup() {
- return axios.get('/asset/authorized-data/current-host-group');
+export function getCurrentAuthorizedHost() {
+ return axios.get('/asset/authorized-data/current-host');
}
/**
diff --git a/orion-ops-ui/src/api/asset/host-group.ts b/orion-ops-ui/src/api/asset/host-group.ts
index d2ad3e50..075a18d3 100644
--- a/orion-ops-ui/src/api/asset/host-group.ts
+++ b/orion-ops-ui/src/api/asset/host-group.ts
@@ -1,4 +1,3 @@
-import type { HostQueryResponse } from './host';
import axios from 'axios';
/**
@@ -34,7 +33,6 @@ export interface HostGroupQueryResponse {
parentId: number;
title: string;
children: Array;
- hostList: Array;
}
/**
diff --git a/orion-ops-ui/src/api/meta/tag.ts b/orion-ops-ui/src/api/meta/tag.ts
index 4fa5623e..2ace1b2f 100644
--- a/orion-ops-ui/src/api/meta/tag.ts
+++ b/orion-ops-ui/src/api/meta/tag.ts
@@ -1,6 +1,6 @@
import axios from 'axios';
-export type TagType = 'HOST'
+export type TagType = 'HOST' | string
/**
* tag 创建对象
@@ -29,5 +29,5 @@ export function createTag(request: TagCreateRequest) {
* 查询标签
*/
export function getTagList(type: TagType) {
- return axios.get('/infra/tag/list', { params: { type } });
+ return axios.get>('/infra/tag/list', { params: { type } });
}
diff --git a/orion-ops-ui/src/components/asset/host-group/host-group-tree-selector.vue b/orion-ops-ui/src/components/asset/host-group/host-group-tree-selector.vue
index 62ad26f5..3b48995d 100644
--- a/orion-ops-ui/src/components/asset/host-group/host-group-tree-selector.vue
+++ b/orion-ops-ui/src/components/asset/host-group/host-group-tree-selector.vue
@@ -44,15 +44,10 @@
const treeData = ref>([]);
// 初始化选项
- onBeforeMount(async () => {
- if (cacheStore.hostGroups.length) {
- treeData.value = cacheStore.hostGroups;
- } else {
- // 加载数据
- const { data } = await getHostGroupTree();
- treeData.value = data;
- cacheStore.set('hostGroups', data);
- }
+ onBeforeMount(() => {
+ cacheStore.loadHostGroups().then(s => {
+ treeData.value = s;
+ });
});
diff --git a/orion-ops-ui/src/components/asset/host-group/host-group-tree.vue b/orion-ops-ui/src/components/asset/host-group/host-group-tree.vue
index 6b93e464..bca9d667 100644
--- a/orion-ops-ui/src/components/asset/host-group/host-group-tree.vue
+++ b/orion-ops-ui/src/components/asset/host-group/host-group-tree.vue
@@ -5,7 +5,7 @@
ref="tree"
class="tree-container"
:blockNode="true"
- :draggable="draggable"
+ :draggable="editable"
:data="treeData"
:checkable="checkable"
v-model:checked-keys="checkedKeys"
@@ -20,7 +20,6 @@
v-model="currName"
style="width: 138px;"
placeholder="名称"
- autofocus
:max-length="32"
:disabled="node.loading"
@blur="() => saveNode(node.key)"
@@ -77,7 +76,7 @@
暂无数据
- 点击上方 '' 添加一个分组吧~
+ 点击上方 '' 添加一个分组吧~
@@ -99,7 +98,7 @@
const props = defineProps({
loading: Boolean,
- draggable: {
+ editable: {
type: Boolean,
default: true
},
@@ -313,20 +312,13 @@
// 加载数据
const fetchTreeData = async (force = false) => {
- if (cacheStore.hostGroups.length && !force) {
- // 缓存有数据并且非强制加载 直接从缓存中加载
- treeData.value = cacheStore.hostGroups;
- } else {
- // 无数据/强制加载
- try {
- emits('loading', true);
- const { data } = await getHostGroupTree();
- treeData.value = data;
- cacheStore.hostGroups = data;
- } catch (e) {
- } finally {
- emits('loading', false);
- }
+ try {
+ const groups = await cacheStore.loadHostGroups(force);
+ emits('loading', true);
+ treeData.value = groups;
+ } catch (e) {
+ } finally {
+ emits('loading', false);
}
// 未选择则选择首个
if (!tree.value?.getSelectedNodes()?.length && treeData.value.length) {
diff --git a/orion-ops-ui/src/components/asset/host-identity/host-identity-selector.vue b/orion-ops-ui/src/components/asset/host-identity/host-identity-selector.vue
index bf0ce623..e1dd2832 100644
--- a/orion-ops-ui/src/components/asset/host-identity/host-identity-selector.vue
+++ b/orion-ops-ui/src/components/asset/host-identity/host-identity-selector.vue
@@ -40,11 +40,13 @@
// 初始化选项
onBeforeMount(() => {
- optionData.value = cacheStore.hostIdentities.map(s => {
- return {
- label: `${s.name} (${s.username})`,
- value: s.id,
- };
+ cacheStore.loadHostIdentities().then(hostIdentities => {
+ optionData.value = hostIdentities.map(s => {
+ return {
+ label: `${s.name} (${s.username})`,
+ value: s.id,
+ };
+ });
});
});
diff --git a/orion-ops-ui/src/components/asset/host-key/host-key-selector.vue b/orion-ops-ui/src/components/asset/host-key/host-key-selector.vue
index 75cb5c04..3d6ac95d 100644
--- a/orion-ops-ui/src/components/asset/host-key/host-key-selector.vue
+++ b/orion-ops-ui/src/components/asset/host-key/host-key-selector.vue
@@ -40,11 +40,13 @@
// 初始化选项
onBeforeMount(() => {
- optionData.value = cacheStore.hostKeys.map(s => {
- return {
- label: s.name,
- value: s.id,
- };
+ cacheStore.loadHostKeys().then(hostKeys => {
+ optionData.value = hostKeys.map(s => {
+ return {
+ label: s.name,
+ value: s.id,
+ };
+ });
});
});
diff --git a/orion-ops-ui/src/components/meta/tag/tag-multi-selector.vue b/orion-ops-ui/src/components/meta/tag/tag-multi-selector.vue
index 54e7b6e5..160435e4 100644
--- a/orion-ops-ui/src/components/meta/tag/tag-multi-selector.vue
+++ b/orion-ops-ui/src/components/meta/tag/tag-multi-selector.vue
@@ -2,6 +2,7 @@
{ emits('onLimited', limit, `最多选择${limit}个tag`) }"
@@ -24,6 +25,7 @@
import { useCacheStore } from '@/store';
import { Message } from '@arco-design/web-vue';
import { createTag } from '@/api/meta/tag';
+ import useLoading from '@/hooks/loading';
const props = defineProps({
modelValue: Array as PropType>,
@@ -31,11 +33,11 @@
limit: Number,
type: String,
allowCreate: Boolean,
- tagType: String,
});
const emits = defineEmits(['update:modelValue', 'onLimited']);
+ const { loading, setLoading } = useLoading();
const cacheStore = useCacheStore();
const value = computed>({
@@ -51,12 +53,13 @@
// 初始化选项
onBeforeMount(() => {
- const tagCache = cacheStore[props.tagType as string] as Array;
- optionData.value = tagCache.map(s => {
- return {
- label: s.name,
- value: s.id,
- };
+ cacheStore.loadTags(props.type as string).then((tags) => {
+ optionData.value = tags.map(s => {
+ return {
+ label: s.name,
+ value: s.id,
+ };
+ });
});
});
@@ -78,12 +81,16 @@
tags.splice(i, 1);
return;
}
+ // 不存在则创建 tag
+ setLoading(true);
try {
// 创建 tag
tags[i] = await doCreateTag(tag);
} catch (e) {
// 失败删除
tags.splice(i, 1);
+ } finally {
+ setLoading(false);
}
}
};
@@ -95,8 +102,8 @@
type: props.type
} as unknown as TagCreateRequest);
// 插入缓存
- const tagCache = cacheStore[props.tagType as string] as Array;
- tagCache.push({ id, name });
+ const tagCache = await cacheStore.loadTags(props.type as string);
+ tagCache && tagCache.push({ id, name });
// 插入 options
optionData.value.push({
label: name,
diff --git a/orion-ops-ui/src/components/system/dict-key/dict-key-selector.vue b/orion-ops-ui/src/components/system/dict-key/dict-key-selector.vue
index b2a50010..0abea687 100644
--- a/orion-ops-ui/src/components/system/dict-key/dict-key-selector.vue
+++ b/orion-ops-ui/src/components/system/dict-key/dict-key-selector.vue
@@ -41,18 +41,18 @@
},
set(e) {
if (typeof e === 'string') {
- // 创建的值
- emits('update:modelValue', undefined);
+ // 创建的值 这里必须为 null, 否则 table 的重置不生效
+ emits('update:modelValue', null);
emits('change', {
- id: undefined,
+ id: null,
keyName: e
});
} else {
// 已有的值
emits('update:modelValue', e);
- const find = cacheStore.dictKeys.find(s => s.id === e);
+ const find = optionData.value.find(s => s.value === e);
if (find) {
- emits('change', find);
+ emits('change', find.origin);
}
}
}
@@ -61,11 +61,14 @@
// 初始化选项
onBeforeMount(() => {
- optionData.value = cacheStore.dictKeys.map(s => {
- return {
- label: `${s.keyName} - ${s.description || ''}`,
- value: s.id,
- };
+ cacheStore.loadDictKeys().then(dictKeys => {
+ optionData.value = dictKeys.map(s => {
+ return {
+ label: `${s.keyName} - ${s.description || ''}`,
+ value: s.id,
+ origin: s
+ };
+ });
});
});
diff --git a/orion-ops-ui/src/components/system/menu/grant/menu-grant-table.vue b/orion-ops-ui/src/components/system/menu/grant/menu-grant-table.vue
index f5222315..d0596bcf 100644
--- a/orion-ops-ui/src/components/system/menu/grant/menu-grant-table.vue
+++ b/orion-ops-ui/src/components/system/menu/grant/menu-grant-table.vue
@@ -67,7 +67,9 @@
unTriggerChange.value = true;
checkedKeys.value = keys;
if (!menuData.value.length) {
- menuData.value = [...cacheStore.menus];
+ cacheStore.loadMenus().then(menus => {
+ menuData.value = [...menus];
+ });
}
};
diff --git a/orion-ops-ui/src/views/system/menu/components/menu-tree-selector.vue b/orion-ops-ui/src/components/system/menu/selector/menu-tree-selector.vue
similarity index 72%
rename from orion-ops-ui/src/views/system/menu/components/menu-tree-selector.vue
rename to orion-ops-ui/src/components/system/menu/selector/menu-tree-selector.vue
index 2c99d540..dc200da8 100644
--- a/orion-ops-ui/src/views/system/menu/components/menu-tree-selector.vue
+++ b/orion-ops-ui/src/components/system/menu/selector/menu-tree-selector.vue
@@ -1,9 +1,9 @@
@@ -16,8 +16,9 @@
diff --git a/orion-ops-ui/src/store/modules/cache/index.ts b/orion-ops-ui/src/store/modules/cache/index.ts
index 5fda7f5b..840bf218 100644
--- a/orion-ops-ui/src/store/modules/cache/index.ts
+++ b/orion-ops-ui/src/store/modules/cache/index.ts
@@ -1,24 +1,23 @@
import type { CacheState } from './types';
import type { AxiosResponse } from 'axios';
+import type { TagType } from '@/api/meta/tag';
+import { getTagList } from '@/api/meta/tag';
import { defineStore } from 'pinia';
import { getUserList } from '@/api/user/user';
import { getRoleList } from '@/api/user/role';
+import { getDictKeyList } from '@/api/system/dict-key';
+import { getHostKeyList } from '@/api/asset/host-key';
+import { getHostIdentityList } from '@/api/asset/host-identity';
+import { getHostList } from '@/api/asset/host';
+import { getHostGroupTree } from '@/api/asset/host-group';
+import { getMenuList } from '@/api/system/menu';
export type CacheType = 'users' | 'menus' | 'roles'
- | 'host' | 'hostGroups' | 'hostTags' | 'hostKeys' | 'hostIdentities'
+ | 'host' | 'hostGroups' | 'hostKeys' | 'hostIdentities'
| 'dictKeys' | string
export default defineStore('cache', {
- state: (): CacheState => ({
- menus: [],
- roles: [],
- hosts: [],
- hostGroups: [],
- hostTags: [],
- hostKeys: [],
- hostIdentities: [],
- dictKeys: [],
- }),
+ state: (): CacheState => ({}),
getters: {},
@@ -41,9 +40,9 @@ export default defineStore('cache', {
},
// 加载数据
- async load(name: CacheType, loader: () => Promise>, onErrorValue = []) {
+ async load(name: CacheType, loader: () => Promise>, force = false, onErrorValue = []) {
// 尝试直接从缓存中获取数据
- if (this[name]) {
+ if (this[name] && !force) {
return this[name] as T;
}
// 加载数据
@@ -57,13 +56,48 @@ export default defineStore('cache', {
},
// 获取用户列表
- async loadUsers() {
- return await this.load('users', getUserList);
+ async loadUsers(force = false) {
+ return await this.load('users', getUserList, force);
},
// 获取角色列表
- async loadRoles() {
- return await this.load('roles', getRoleList);
+ async loadRoles(force = false) {
+ return await this.load('roles', getRoleList, force);
+ },
+
+ // 获取菜单列表
+ async loadMenus(force = false) {
+ return await this.load('menus', () => getMenuList({}), force);
+ },
+
+ // 获取主机分组列表
+ async loadHostGroups(force = false) {
+ return await this.load('hostGroups', getHostGroupTree, force);
+ },
+
+ // 获取主机列表
+ async loadHosts(force = false) {
+ return await this.load('hosts', getHostList, force);
+ },
+
+ // 获取主机秘钥列表
+ async loadHostKeys(force = false) {
+ return await this.load('hostKeys', getHostKeyList, force);
+ },
+
+ // 获取主机身份列表
+ async loadHostIdentities(force = false) {
+ return await this.load('hostIdentities', getHostIdentityList, force);
+ },
+
+ // 获取字典配置项列表
+ async loadDictKeys(force = false) {
+ return await this.load('dictKeys', getDictKeyList, force);
+ },
+
+ // 加载 tags
+ async loadTags(type: TagType, force = false) {
+ return await this.load(`${type}_Tags`, () => getTagList(type), force);
},
}
diff --git a/orion-ops-ui/src/store/modules/cache/types.ts b/orion-ops-ui/src/store/modules/cache/types.ts
index 3a53c16c..3c4d8c22 100644
--- a/orion-ops-ui/src/store/modules/cache/types.ts
+++ b/orion-ops-ui/src/store/modules/cache/types.ts
@@ -1,7 +1,6 @@
import type { UserQueryResponse } from '@/api/user/user';
import type { MenuQueryResponse } from '@/api/system/menu';
import type { RoleQueryResponse } from '@/api/user/role';
-import type { TagQueryResponse } from '@/api/meta/tag';
import type { HostQueryResponse } from '@/api/asset/host';
import type { HostGroupQueryResponse } from '@/api/asset/host-group';
import type { HostKeyQueryResponse } from '@/api/asset/host-key';
@@ -12,7 +11,6 @@ export interface CacheState {
users?: UserQueryResponse[];
menus?: MenuQueryResponse[];
roles?: RoleQueryResponse[];
- hostTags?: TagQueryResponse[];
hosts?: HostQueryResponse[];
hostGroups?: HostGroupQueryResponse[];
hostKeys?: HostKeyQueryResponse[];
diff --git a/orion-ops-ui/src/types/form.ts b/orion-ops-ui/src/types/form.ts
index 336256de..04b3293e 100644
--- a/orion-ops-ui/src/types/form.ts
+++ b/orion-ops-ui/src/types/form.ts
@@ -2,3 +2,8 @@
export const labelFilter = (searchValue: string, option: { label: string; }) => {
return option.label.toLowerCase().indexOf(searchValue.toLowerCase()) > -1;
};
+
+// 通过 title 进行过滤
+export const titleFilter = (searchValue: string, option: { title: string; }) => {
+ return option.title.toLowerCase().indexOf(searchValue.toLowerCase()) > -1;
+};
diff --git a/orion-ops-ui/src/views/asset/grant/components/host-group-role-grant.vue b/orion-ops-ui/src/views/asset/grant/components/host-group-role-grant.vue
index 78269ca1..28a20c5b 100644
--- a/orion-ops-ui/src/views/asset/grant/components/host-group-role-grant.vue
+++ b/orion-ops-ui/src/views/asset/grant/components/host-group-role-grant.vue
@@ -31,7 +31,7 @@
selectedGroup = e"
diff --git a/orion-ops-ui/src/views/asset/grant/components/host-group-user-grant.vue b/orion-ops-ui/src/views/asset/grant/components/host-group-user-grant.vue
index 06d23ce6..2c4daa33 100644
--- a/orion-ops-ui/src/views/asset/grant/components/host-group-user-grant.vue
+++ b/orion-ops-ui/src/views/asset/grant/components/host-group-user-grant.vue
@@ -30,7 +30,7 @@
selectedGroup = e"
diff --git a/orion-ops-ui/src/views/asset/grant/components/host-list.vue b/orion-ops-ui/src/views/asset/grant/components/host-list.vue
index 5e7759d6..328f83fe 100644
--- a/orion-ops-ui/src/views/asset/grant/components/host-list.vue
+++ b/orion-ops-ui/src/views/asset/grant/components/host-list.vue
@@ -36,10 +36,8 @@
import type { PropType } from 'vue';
import useLoading from '@/hooks/loading';
import { useCacheStore } from '@/store';
- import { onBeforeMount, ref, watch } from 'vue';
+ import { ref, watch } from 'vue';
import { getHostGroupRelList } from '@/api/asset/host-group';
- import { getHostList } from '@/api/asset/host';
- import { Message } from '@arco-design/web-vue';
const props = defineProps({
group: {
@@ -64,7 +62,8 @@
try {
setLoading(true);
const { data } = await getHostGroupRelList(groupId as number);
- selectedGroupHosts.value = data.map(s => cacheStore.hosts.find(h => h.id === s) as HostQueryResponse)
+ const hosts = await cacheStore.loadHosts();
+ selectedGroupHosts.value = data.map(s => hosts.find(h => h.id === s) as HostQueryResponse)
.filter(Boolean);
} catch (e) {
} finally {
@@ -72,24 +71,6 @@
}
});
- // 加载主机列表
- const loadHostList = async () => {
- try {
- const { data } = await getHostList();
- // 设置到缓存
- cacheStore.set('hosts', data);
- } catch (e) {
- Message.error('主机列表加载失败');
- }
- };
-
- onBeforeMount(async () => {
- if (!cacheStore.hosts.length) {
- // 加载用户列表
- await loadHostList();
- }
- });
-