⚡ 优化资产授权交互逻辑.
This commit is contained in:
@@ -5,8 +5,7 @@
|
|||||||
:loading="loading"
|
:loading="loading"
|
||||||
placeholder="请选择主机分组"
|
placeholder="请选择主机分组"
|
||||||
:allow-clear="true"
|
:allow-clear="true"
|
||||||
:allow-search="true">
|
:allow-search="true" />
|
||||||
</a-tree-select>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|||||||
@@ -2,15 +2,17 @@
|
|||||||
<a-scrollbar>
|
<a-scrollbar>
|
||||||
<!-- 分组树 -->
|
<!-- 分组树 -->
|
||||||
<a-tree v-if="treeData.length"
|
<a-tree v-if="treeData.length"
|
||||||
|
v-model:checked-keys="checkedKeys"
|
||||||
ref="tree"
|
ref="tree"
|
||||||
class="tree-container block-tree"
|
class="tree-container block-tree"
|
||||||
v-model:checked-keys="checkedKeys"
|
:class="[ editable ? 'editable-tree' : '' ]"
|
||||||
:blockNode="true"
|
:blockNode="true"
|
||||||
:draggable="editable"
|
|
||||||
:data="treeData"
|
:data="treeData"
|
||||||
|
:draggable="editable"
|
||||||
:checkable="checkable"
|
:checkable="checkable"
|
||||||
:check-strictly="true"
|
:check-strictly="true"
|
||||||
@drop="moveGroup">
|
@drop="moveGroup"
|
||||||
|
@select="(s) => emits('onSelected', s)">
|
||||||
<!-- 标题 -->
|
<!-- 标题 -->
|
||||||
<template #title="node">
|
<template #title="node">
|
||||||
<!-- 修改名称输入框 -->
|
<!-- 修改名称输入框 -->
|
||||||
@@ -97,13 +99,16 @@
|
|||||||
import { isString } from '@/utils/is';
|
import { isString } from '@/utils/is';
|
||||||
import { useCacheStore } from '@/store';
|
import { useCacheStore } from '@/store';
|
||||||
|
|
||||||
const props = defineProps<Partial<{
|
const props = withDefaults(defineProps<Partial<{
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
editable: boolean;
|
editable: boolean;
|
||||||
checkable: boolean;
|
checkable: boolean;
|
||||||
checkedKeys: Array<number>;
|
checkedKeys: Array<number>;
|
||||||
}>>();
|
}>>(), {
|
||||||
const emits = defineEmits(['setLoading', 'selectedNode', 'update:checkedKeys']);
|
editable: false,
|
||||||
|
checkable: false,
|
||||||
|
});
|
||||||
|
const emits = defineEmits(['setLoading', 'onSelected', 'selectedNode', 'update:checkedKeys']);
|
||||||
|
|
||||||
const cacheStore = useCacheStore();
|
const cacheStore = useCacheStore();
|
||||||
|
|
||||||
@@ -331,19 +336,9 @@
|
|||||||
width: max-content;
|
width: max-content;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
|
||||||
|
|
||||||
.empty-container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
height: 100%;
|
|
||||||
padding-top: 25px;
|
|
||||||
color: var(--color-text-3);
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.arco-tree-node-title) {
|
:deep(.arco-tree-node-title) {
|
||||||
padding: 0 80px 0 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.node-title-wrapper {
|
.node-title-wrapper {
|
||||||
@@ -358,5 +353,21 @@
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: rgb(var(--primary-6));
|
color: rgb(var(--primary-6));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable-tree {
|
||||||
|
:deep(.arco-tree-node-title) {
|
||||||
|
padding: 0 80px 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
padding-top: 25px;
|
||||||
|
color: var(--color-text-3);
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
import useLoading from '@/hooks/loading';
|
import useLoading from '@/hooks/loading';
|
||||||
|
|
||||||
const props = defineProps<Partial<{
|
const props = defineProps<Partial<{
|
||||||
modelValue: number
|
modelValue: number;
|
||||||
}>>();
|
}>>();
|
||||||
|
|
||||||
const emits = defineEmits(['update:modelValue']);
|
const emits = defineEmits(['update:modelValue']);
|
||||||
|
|||||||
@@ -39,7 +39,8 @@
|
|||||||
allowCreate: boolean;
|
allowCreate: boolean;
|
||||||
tagColor: Array<string>;
|
tagColor: Array<string>;
|
||||||
}>>(), {
|
}>>(), {
|
||||||
tagColor: () => []
|
allowCreate: false,
|
||||||
|
tagColor: () => [],
|
||||||
});
|
});
|
||||||
|
|
||||||
const emits = defineEmits(['update:modelValue', 'onLimited']);
|
const emits = defineEmits(['update:modelValue', 'onLimited']);
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="editorContainer"
|
<div ref="editorContainer"
|
||||||
class="editor-wrapper"
|
class="editor-wrapper"
|
||||||
:class="[
|
:class="[ !!containerClass ? containerClass : '' ]"
|
||||||
!!containerClass ? containerClass : ''
|
:style="{ ...containerStyle }" />
|
||||||
]"
|
|
||||||
:style="{
|
|
||||||
...containerStyle
|
|
||||||
}" />
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|||||||
@@ -27,15 +27,30 @@
|
|||||||
</template>
|
</template>
|
||||||
</span>
|
</span>
|
||||||
</a-alert>
|
</a-alert>
|
||||||
|
<!-- 操作按钮 -->
|
||||||
|
<a-space>
|
||||||
|
<!-- 全选 -->
|
||||||
|
<a-button @click="emits('selectAll')">
|
||||||
|
全选
|
||||||
|
<template #icon>
|
||||||
|
<icon-select-all />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
<!-- 反选 -->
|
||||||
|
<a-button @click="emits('reverse')">
|
||||||
|
反选
|
||||||
|
<template #icon>
|
||||||
|
<icon-list />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
<!-- 授权 -->
|
<!-- 授权 -->
|
||||||
<a-button class="grant-button"
|
<a-button type="primary" @click="doGrant">
|
||||||
type="primary"
|
|
||||||
@click="doGrant">
|
|
||||||
授权
|
授权
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<icon-safe />
|
<icon-safe />
|
||||||
</template>
|
</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
|
</a-space>
|
||||||
</div>
|
</div>
|
||||||
<!-- 主体部分 -->
|
<!-- 主体部分 -->
|
||||||
<div class="data-main">
|
<div class="data-main">
|
||||||
@@ -63,7 +78,7 @@
|
|||||||
type: string;
|
type: string;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
}>();
|
}>();
|
||||||
const emits = defineEmits(['fetch', 'grant']);
|
const emits = defineEmits(['fetch', 'grant', 'selectAll', 'reverse']);
|
||||||
|
|
||||||
const subjectId = ref();
|
const subjectId = ref();
|
||||||
const currentSubject = ref();
|
const currentSubject = ref();
|
||||||
@@ -115,16 +130,13 @@
|
|||||||
|
|
||||||
.alert-wrapper {
|
.alert-wrapper {
|
||||||
padding: 4px 16px;
|
padding: 4px 16px;
|
||||||
|
margin-right: 12px;
|
||||||
|
|
||||||
.alert-message {
|
.alert-message {
|
||||||
display: block;
|
display: block;
|
||||||
height: 22px;
|
height: 22px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.grant-button {
|
|
||||||
margin-left: 16px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.data-main {
|
.data-main {
|
||||||
|
|||||||
@@ -2,15 +2,19 @@
|
|||||||
<grant-layout :type="type"
|
<grant-layout :type="type"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
@fetch="fetchAuthorizedData"
|
@fetch="fetchAuthorizedData"
|
||||||
@grant="doGrant">
|
@grant="doGrant"
|
||||||
|
@select-all="selectAll"
|
||||||
|
@reverse="reverseSelect">
|
||||||
<!-- 分组 -->
|
<!-- 分组 -->
|
||||||
<host-group-tree v-model:checked-keys="checkedGroups"
|
<host-group-tree v-model:checked-keys="checkedGroups"
|
||||||
|
ref="tree"
|
||||||
outer-class="group-main-tree"
|
outer-class="group-main-tree"
|
||||||
:checkable="true"
|
:checkable="true"
|
||||||
:editable="false"
|
:editable="false"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
@set-loading="setLoading"
|
@set-loading="setLoading"
|
||||||
@selected-node="(e) => selectedGroup = e" />
|
@selected-node="(e) => selectedGroup = e"
|
||||||
|
@on-selected="clickGroup" />
|
||||||
<!-- 主机列表 -->
|
<!-- 主机列表 -->
|
||||||
<host-list class="group-main-hosts sticky-list" :group="selectedGroup" />
|
<host-list class="group-main-hosts sticky-list" :group="selectedGroup" />
|
||||||
</grant-layout>
|
</grant-layout>
|
||||||
@@ -28,6 +32,8 @@
|
|||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import useLoading from '@/hooks/loading';
|
import useLoading from '@/hooks/loading';
|
||||||
import { getAuthorizedHostGroup, grantHostGroup } from '@/api/asset/asset-data-grant';
|
import { getAuthorizedHostGroup, grantHostGroup } from '@/api/asset/asset-data-grant';
|
||||||
|
import { useCacheStore } from '@/store';
|
||||||
|
import { flatNodeKeys } from '@/utils/tree';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
import HostGroupTree from '@/components/asset/host-group/tree/index.vue';
|
import HostGroupTree from '@/components/asset/host-group/tree/index.vue';
|
||||||
import HostList from './host-list.vue';
|
import HostList from './host-list.vue';
|
||||||
@@ -37,12 +43,27 @@
|
|||||||
type: string;
|
type: string;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const cacheStore = useCacheStore();
|
||||||
const { loading, setLoading } = useLoading();
|
const { loading, setLoading } = useLoading();
|
||||||
|
|
||||||
|
const tree = ref();
|
||||||
const authorizedGroups = ref<Array<number>>([]);
|
const authorizedGroups = ref<Array<number>>([]);
|
||||||
const checkedGroups = ref<Array<number>>([]);
|
const checkedGroups = ref<Array<number>>([]);
|
||||||
const selectedGroup = ref<TreeNodeData>({});
|
const selectedGroup = ref<TreeNodeData>({});
|
||||||
|
|
||||||
|
// 点击分组
|
||||||
|
const clickGroup = (groups: Array<number>) => {
|
||||||
|
if (groups && groups.length) {
|
||||||
|
const group = groups[0];
|
||||||
|
const index = checkedGroups.value.findIndex((s) => s === group);
|
||||||
|
if (index === -1) {
|
||||||
|
checkedGroups.value.push(group);
|
||||||
|
} else {
|
||||||
|
checkedGroups.value.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 获取授权列表
|
// 获取授权列表
|
||||||
const fetchAuthorizedData = async (request: AssetAuthorizedDataQueryRequest) => {
|
const fetchAuthorizedData = async (request: AssetAuthorizedDataQueryRequest) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
@@ -74,6 +95,24 @@
|
|||||||
await fetchAuthorizedData(request);
|
await fetchAuthorizedData(request);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 全选
|
||||||
|
const selectAll = async () => {
|
||||||
|
// 从缓存中查询全部分组
|
||||||
|
const groups = await cacheStore.loadHostGroups();
|
||||||
|
const groupKeys: number[] = [];
|
||||||
|
flatNodeKeys(groups, groupKeys);
|
||||||
|
checkedGroups.value = groupKeys;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 反选
|
||||||
|
const reverseSelect = async () => {
|
||||||
|
// 从缓存中查询全部分组
|
||||||
|
const groups = await cacheStore.loadHostGroups();
|
||||||
|
const groupKeys: number[] = [];
|
||||||
|
flatNodeKeys(groups, groupKeys);
|
||||||
|
checkedGroups.value = groupKeys.filter(s => !checkedGroups.value.includes(s));
|
||||||
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
<grant-layout :type="type"
|
<grant-layout :type="type"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
@fetch="fetchAuthorizedData"
|
@fetch="fetchAuthorizedData"
|
||||||
@grant="doGrant">
|
@grant="doGrant"
|
||||||
|
@select-all="selectAll"
|
||||||
|
@reverse="reverseSelect">
|
||||||
<!-- 主机身份表格 -->
|
<!-- 主机身份表格 -->
|
||||||
<a-table row-key="id"
|
<a-table row-key="id"
|
||||||
class="host-identity-main-table"
|
class="host-identity-main-table"
|
||||||
@@ -102,6 +104,17 @@
|
|||||||
await fetchAuthorizedData(request);
|
await fetchAuthorizedData(request);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 全选
|
||||||
|
const selectAll = () => {
|
||||||
|
selectedKeys.value = hostIdentities.value.map(s => s.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 反选
|
||||||
|
const reverseSelect = () => {
|
||||||
|
selectedKeys.value = hostIdentities.value.map(s => s.id)
|
||||||
|
.filter(s => !selectedKeys.value.includes(s));
|
||||||
|
};
|
||||||
|
|
||||||
// 点击行
|
// 点击行
|
||||||
const clickRow = ({ id }: TableData) => {
|
const clickRow = ({ id }: TableData) => {
|
||||||
const index = selectedKeys.value.indexOf(id);
|
const index = selectedKeys.value.indexOf(id);
|
||||||
@@ -112,7 +125,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 初始化数据
|
// 初始化身份数据
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
@@ -124,7 +137,7 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 初始化数据
|
// 初始化秘钥数据
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// 加载主机秘钥
|
// 加载主机秘钥
|
||||||
hostKeys.value = await cacheStore.loadHostKeys();
|
hostKeys.value = await cacheStore.loadHostKeys();
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
<grant-layout :type="type"
|
<grant-layout :type="type"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
@fetch="fetchAuthorizedData"
|
@fetch="fetchAuthorizedData"
|
||||||
@grant="doGrant">
|
@grant="doGrant"
|
||||||
|
@select-all="selectAll"
|
||||||
|
@reverse="reverseSelect">
|
||||||
<!-- 主机秘钥表格 -->
|
<!-- 主机秘钥表格 -->
|
||||||
<a-table row-key="id"
|
<a-table row-key="id"
|
||||||
class="host-key-main-table"
|
class="host-key-main-table"
|
||||||
@@ -78,6 +80,17 @@
|
|||||||
await fetchAuthorizedData(request);
|
await fetchAuthorizedData(request);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 全选
|
||||||
|
const selectAll = () => {
|
||||||
|
selectedKeys.value = hostKeys.value.map(s => s.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 反选
|
||||||
|
const reverseSelect = () => {
|
||||||
|
selectedKeys.value = hostKeys.value.map(s => s.id)
|
||||||
|
.filter(s => !selectedKeys.value.includes(s));
|
||||||
|
};
|
||||||
|
|
||||||
// 点击行
|
// 点击行
|
||||||
const clickRow = ({ id }: TableData) => {
|
const clickRow = ({ id }: TableData) => {
|
||||||
const index = selectedKeys.value.indexOf(id);
|
const index = selectedKeys.value.indexOf(id);
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
<host-group-tree outer-class="tree-card-main"
|
<host-group-tree outer-class="tree-card-main"
|
||||||
ref="tree"
|
ref="tree"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
|
:editable="true"
|
||||||
@set-loading="setLoading"
|
@set-loading="setLoading"
|
||||||
@selected-node="selectGroup" />
|
@selected-node="selectGroup" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -74,7 +74,6 @@
|
|||||||
<!-- 主机标签 -->
|
<!-- 主机标签 -->
|
||||||
<a-form-item field="tags" label="主机标签">
|
<a-form-item field="tags" label="主机标签">
|
||||||
<tag-multi-selector v-model="formModel.tags"
|
<tag-multi-selector v-model="formModel.tags"
|
||||||
:allowCreate="false"
|
|
||||||
:limit="0"
|
:limit="0"
|
||||||
type="HOST"
|
type="HOST"
|
||||||
:tagColor="tagColor"
|
:tagColor="tagColor"
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
<a-form-item field="tags" label="主机标签">
|
<a-form-item field="tags" label="主机标签">
|
||||||
<tag-multi-selector v-model="formModel.tags"
|
<tag-multi-selector v-model="formModel.tags"
|
||||||
ref="tagSelector"
|
ref="tagSelector"
|
||||||
:allowCreate="false"
|
|
||||||
:limit="0"
|
:limit="0"
|
||||||
type="HOST"
|
type="HOST"
|
||||||
:tagColor="tagColor"
|
:tagColor="tagColor"
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
import CommandSnippetListItem from './command-snippet-list-item.vue';
|
import CommandSnippetListItem from './command-snippet-list-item.vue';
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
snippet: CommandSnippetWrapperResponse
|
snippet: CommandSnippetWrapperResponse;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
// 计算总量
|
// 计算总量
|
||||||
|
|||||||
@@ -121,7 +121,7 @@
|
|||||||
import { openUpdateSnippetKey, removeSnippetKey } from '../types/const';
|
import { openUpdateSnippetKey, removeSnippetKey } from '../types/const';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
item: CommandSnippetQueryResponse
|
item: CommandSnippetQueryResponse;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { getAndCheckCurrentSshSession } = useTerminalStore();
|
const { getAndCheckCurrentSshSession } = useTerminalStore();
|
||||||
|
|||||||
@@ -28,9 +28,9 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import type { HostQueryResponse } from '@/api/asset/host';
|
||||||
|
import type { HostGroupQueryResponse } from '@/api/asset/host-group';
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import { HostQueryResponse } from '@/api/asset/host';
|
|
||||||
import { HostGroupQueryResponse } from '@/api/asset/host-group';
|
|
||||||
import HostListView from './host-list-view.vue';
|
import HostListView from './host-list-view.vue';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
|||||||
@@ -23,18 +23,18 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import type { AuthorizedHostQueryResponse } from '@/api/asset/asset-authorized-data';
|
||||||
|
import type { HostQueryResponse } from '@/api/asset/host';
|
||||||
import { computed, onMounted, provide, ref, watch } from 'vue';
|
import { computed, onMounted, provide, ref, watch } from 'vue';
|
||||||
import { NewConnectionType, openSettingModalKey } from '../../types/terminal.const';
|
import { NewConnectionType, openSettingModalKey } from '../../types/terminal.const';
|
||||||
import { AuthorizedHostQueryResponse } from '@/api/asset/asset-authorized-data';
|
|
||||||
import { HostQueryResponse } from '@/api/asset/host';
|
|
||||||
import HostGroupView from './host-group-view.vue';
|
import HostGroupView from './host-group-view.vue';
|
||||||
import HostListView from './host-list-view.vue';
|
import HostListView from './host-list-view.vue';
|
||||||
import HostSettingModal from '../setting/extra/host-setting-modal.vue';
|
import HostSettingModal from '../setting/extra/host-setting-modal.vue';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
hosts: AuthorizedHostQueryResponse,
|
hosts: AuthorizedHostQueryResponse;
|
||||||
filterValue: string,
|
filterValue: string;
|
||||||
newConnectionType: string
|
newConnectionType: string;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const hostList = ref<Array<HostQueryResponse>>([]);
|
const hostList = ref<Array<HostQueryResponse>>([]);
|
||||||
|
|||||||
@@ -3,8 +3,7 @@
|
|||||||
ref="formRef"
|
ref="formRef"
|
||||||
label-align="right"
|
label-align="right"
|
||||||
:label-col-props="{ span: 6 }"
|
:label-col-props="{ span: 6 }"
|
||||||
:wrapper-col-props="{ span: 18 }"
|
:wrapper-col-props="{ span: 18 }">
|
||||||
:rules="{}">
|
|
||||||
<!-- 验证方式 -->
|
<!-- 验证方式 -->
|
||||||
<a-form-item field="authType" label="验证方式">
|
<a-form-item field="authType" label="验证方式">
|
||||||
<a-radio-group type="button"
|
<a-radio-group type="button"
|
||||||
|
|||||||
@@ -80,7 +80,7 @@
|
|||||||
defineProps<{
|
defineProps<{
|
||||||
title: string;
|
title: string;
|
||||||
type: number;
|
type: number;
|
||||||
items: Array<TerminalShortcutKeyEditable>
|
items: Array<TerminalShortcutKeyEditable>;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emits = defineEmits(['setEditable', 'clearEditable', 'updateEnabled']);
|
const emits = defineEmits(['setEditable', 'clearEditable', 'updateEnabled']);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="terminal-example" ref="terminal"></div>
|
<div class="terminal-example" ref="terminal"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
import { onMounted, onUnmounted, ref } from 'vue';
|
import { onMounted, onUnmounted, ref } from 'vue';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
schema: TerminalThemeSchema | Record<string, any>
|
schema: TerminalThemeSchema | Record<string, any>;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const terminal = ref();
|
const terminal = ref();
|
||||||
|
|||||||
@@ -79,7 +79,7 @@
|
|||||||
import SftpUploadModal from './sftp-upload-modal.vue';
|
import SftpUploadModal from './sftp-upload-modal.vue';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
tab: TerminalTabItem
|
tab: TerminalTabItem;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { preference, sessionManager, transferManager } = useTerminalStore();
|
const { preference, sessionManager, transferManager } = useTerminalStore();
|
||||||
|
|||||||
@@ -79,7 +79,7 @@
|
|||||||
import XtermSearchModal from '@/components/xtrem/search-modal/index.vue';
|
import XtermSearchModal from '@/components/xtrem/search-modal/index.vue';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
tab: TerminalTabItem
|
tab: TerminalTabItem;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { getDictValue } = useDictStore();
|
const { getDictValue } = useDictStore();
|
||||||
|
|||||||
@@ -60,8 +60,8 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { UserQueryResponse, LoginHistoryQueryResponse } from '@/api/user/user';
|
import type { UserQueryResponse, LoginHistoryQueryResponse } from '@/api/user/user';
|
||||||
import useLoading from '@/hooks/loading';
|
|
||||||
import { ref, onBeforeMount } from 'vue';
|
import { ref, onBeforeMount } from 'vue';
|
||||||
|
import useLoading from '@/hooks/loading';
|
||||||
import { ResultStatus } from '../types/const';
|
import { ResultStatus } from '../types/const';
|
||||||
import { getCurrentLoginHistory } from '@/api/user/mine';
|
import { getCurrentLoginHistory } from '@/api/user/mine';
|
||||||
import { getLoginHistory } from '@/api/user/user';
|
import { getLoginHistory } from '@/api/user/user';
|
||||||
|
|||||||
@@ -49,8 +49,8 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { UserUpdateRequest, UserQueryResponse } from '@/api/user/user';
|
import type { UserUpdateRequest, UserQueryResponse } from '@/api/user/user';
|
||||||
import useLoading from '@/hooks/loading';
|
|
||||||
import { ref, onMounted } from 'vue';
|
import { ref, onMounted } from 'vue';
|
||||||
|
import useLoading from '@/hooks/loading';
|
||||||
import formRules from '../../user/types/form.rules';
|
import formRules from '../../user/types/form.rules';
|
||||||
import { useUserStore } from '@/store';
|
import { useUserStore } from '@/store';
|
||||||
import { getCurrentUser, updateCurrentUser } from '@/api/user/mine';
|
import { getCurrentUser, updateCurrentUser } from '@/api/user/mine';
|
||||||
|
|||||||
@@ -68,14 +68,14 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { UserQueryResponse } from '@/api/user/user';
|
import type { UserQueryResponse } from '@/api/user/user';
|
||||||
import type { UserSessionQueryResponse } from '@/api/user/user';
|
import type { UserSessionQueryResponse } from '@/api/user/user';
|
||||||
import useLoading from '@/hooks/loading';
|
|
||||||
import { ref, onBeforeMount } from 'vue';
|
import { ref, onBeforeMount } from 'vue';
|
||||||
|
import { getUserSessionList, offlineUserSession } from '@/api/user/user';
|
||||||
import { getCurrentUserSessionList, offlineCurrentUserSession } from '@/api/user/mine';
|
import { getCurrentUserSessionList, offlineCurrentUserSession } from '@/api/user/mine';
|
||||||
import { dateFormat } from '@/utils';
|
import { dateFormat } from '@/utils';
|
||||||
import { isMobile } from '@/utils/is';
|
import { isMobile } from '@/utils/is';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import useLoading from '@/hooks/loading';
|
||||||
import usePermission from '@/hooks/permission';
|
import usePermission from '@/hooks/permission';
|
||||||
import { getUserSessionList, offlineUserSession } from '@/api/user/user';
|
import { Message } from '@arco-design/web-vue';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
user?: UserQueryResponse;
|
user?: UserQueryResponse;
|
||||||
|
|||||||
Reference in New Issue
Block a user