refactor: 优化查询主机逻辑.
This commit is contained in:
@@ -34,6 +34,6 @@ public class AuthorizedHostWrapperVO {
|
||||
private Map<String, Set<Long>> treeNodes;
|
||||
|
||||
@Schema(description = "最近访问的主机")
|
||||
private List<Long> latestHosts;
|
||||
private Set<Long> latestHosts;
|
||||
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ public class AssetAuthorizedDataServiceImpl implements AssetAuthorizedDataServic
|
||||
favoriteResult.get(),
|
||||
dataAliasResult.get());
|
||||
// 设置最近连接的主机
|
||||
wrapper.setLatestHosts(latestConnectHostIdList.get());
|
||||
wrapper.setLatestHosts(new LinkedHashSet<>(latestConnectHostIdList.get()));
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
</sql>
|
||||
|
||||
<select id="selectLatestConnectHostId" resultType="java.lang.Long">
|
||||
SELECT DISTINCT host_id
|
||||
SELECT host_id
|
||||
FROM host_connect_log
|
||||
WHERE deleted = 0
|
||||
AND type = #{type}
|
||||
|
||||
@@ -11,6 +11,7 @@ export interface AuthorizedHostQueryResponse {
|
||||
groupTree: Array<HostGroupQueryResponse>;
|
||||
hostList: Array<HostQueryResponse>;
|
||||
treeNodes: Record<string, Array<number>>;
|
||||
latestHosts: Array<number>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,6 +7,8 @@ import type {
|
||||
TerminalSessionSetting,
|
||||
TerminalState
|
||||
} from './types';
|
||||
import type { AuthorizedHostQueryResponse } from '@/api/asset/asset-authorized-data';
|
||||
import { getCurrentAuthorizedHost } from '@/api/asset/asset-authorized-data';
|
||||
import type { TerminalTheme } from '@/api/asset/host-terminal';
|
||||
import { getTerminalThemes } from '@/api/asset/host-terminal';
|
||||
import { defineStore } from 'pinia';
|
||||
@@ -44,6 +46,7 @@ export default defineStore('terminal', {
|
||||
pluginsSetting: {} as TerminalPluginsSetting,
|
||||
sessionSetting: {} as TerminalSessionSetting,
|
||||
},
|
||||
hosts: {} as AuthorizedHostQueryResponse,
|
||||
tabManager: new TerminalTabManager(),
|
||||
sessionManager: new TerminalSessionManager()
|
||||
}),
|
||||
@@ -55,7 +58,7 @@ export default defineStore('terminal', {
|
||||
// 加载偏好
|
||||
const { data } = await getPreference<TerminalPreference>('TERMINAL');
|
||||
// theme 不存在则默认加载第一个
|
||||
if (!data.theme) {
|
||||
if (!data.theme?.name) {
|
||||
const { data: themes } = await getTerminalThemes();
|
||||
data.theme = themes[0];
|
||||
// 更新默认主题偏好
|
||||
@@ -91,6 +94,22 @@ export default defineStore('terminal', {
|
||||
}
|
||||
},
|
||||
|
||||
// 加载主机列表
|
||||
async loadHosts() {
|
||||
if (this.hosts.hostList?.length) {
|
||||
return;
|
||||
}
|
||||
const { data } = await getCurrentAuthorizedHost();
|
||||
Object.keys(data).forEach(k => {
|
||||
this.hosts[k as keyof AuthorizedHostQueryResponse] = data[k as keyof AuthorizedHostQueryResponse] as any;
|
||||
});
|
||||
},
|
||||
|
||||
// 添加到最近连接列表
|
||||
addToLatestConnect(hostId: number) {
|
||||
this.hosts.latestHosts = [...new Set([hostId, ...this.hosts.latestHosts])];
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import type { ITerminalSessionManager, ITerminalTabManager } from '@/views/host/terminal/types/terminal.type';
|
||||
import type { TerminalTheme } from '@/api/asset/host-terminal';
|
||||
import type { AuthorizedHostQueryResponse } from '@/api/asset/asset-authorized-data';
|
||||
|
||||
export interface TerminalState {
|
||||
preference: TerminalPreference;
|
||||
hosts: AuthorizedHostQueryResponse;
|
||||
tabManager: ITerminalTabManager;
|
||||
sessionManager: ITerminalSessionManager;
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@
|
||||
emptyValue: string
|
||||
}>();
|
||||
|
||||
const { tabManager } = useTerminalStore();
|
||||
const { tabManager, addToLatestConnect } = useTerminalStore();
|
||||
const { toggle: toggleFavorite, loading: favoriteLoading } = useFavorite('HOST');
|
||||
|
||||
const aliasNameInput = ref();
|
||||
@@ -215,6 +215,8 @@
|
||||
|
||||
// 打开终端
|
||||
const openTerminal = (record: HostQueryResponse) => {
|
||||
// 添加到最近连接
|
||||
addToLatestConnect(record.id);
|
||||
// 获取 seq
|
||||
const tabSeqArr = tabManager.items
|
||||
.map(s => s.seq)
|
||||
|
||||
@@ -44,8 +44,7 @@
|
||||
const props = defineProps<{
|
||||
hosts: AuthorizedHostQueryResponse,
|
||||
filterValue: string,
|
||||
newConnectionType: string,
|
||||
latestHosts: Array<number>
|
||||
newConnectionType: string
|
||||
}>();
|
||||
|
||||
const hostList = ref<Array<HostQueryResponse>>([]);
|
||||
@@ -94,19 +93,26 @@
|
||||
list = list.filter(item => item.favorite);
|
||||
} else if (NewConnectionType.LATEST === props.newConnectionType) {
|
||||
// 过滤-最近连接
|
||||
list = list.filter(s => props.latestHosts.includes(s.id));
|
||||
list = props.hosts.latestHosts
|
||||
.map(s => list.find(item => item.id === s) as HostQueryResponse)
|
||||
.filter(Boolean);
|
||||
}
|
||||
// 排序
|
||||
hostList.value = list?.sort((o1, o2) => {
|
||||
if (o1.favorite || o2.favorite) {
|
||||
if (o1.favorite && o2.favorite) {
|
||||
// 非最近连接排序
|
||||
if (NewConnectionType.LATEST !== props.newConnectionType) {
|
||||
hostList.value = list.sort((o1, o2) => {
|
||||
if (o1.favorite || o2.favorite) {
|
||||
if (o1.favorite && o2.favorite) {
|
||||
return o2.id < o1.id ? 1 : -1;
|
||||
}
|
||||
return o2.favorite ? 1 : -1;
|
||||
} else {
|
||||
return o2.id < o1.id ? 1 : -1;
|
||||
}
|
||||
return o2.favorite ? 1 : -1;
|
||||
} else {
|
||||
return o2.id < o1.id ? 1 : -1;
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// 最近连接不排序
|
||||
hostList.value = list;
|
||||
}
|
||||
};
|
||||
|
||||
// 监听搜索值变化
|
||||
|
||||
@@ -60,8 +60,7 @@
|
||||
class="host-view-container"
|
||||
:hosts="hosts"
|
||||
:filter-value="filterValue"
|
||||
:new-connection-type="newConnectionType"
|
||||
:latest-hosts="latestHosts" />
|
||||
:new-connection-type="newConnectionType" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -76,27 +75,22 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { SelectOptionData } from '@arco-design/web-vue';
|
||||
import type { AuthorizedHostQueryResponse } from '@/api/asset/asset-authorized-data';
|
||||
import { getCurrentAuthorizedHost } from '@/api/asset/asset-authorized-data';
|
||||
import { onBeforeMount, ref } from 'vue';
|
||||
import { NewConnectionType, newConnectionTypeKey } from '../../types/terminal.const';
|
||||
import useLoading from '@/hooks/loading';
|
||||
import { useAppStore, useDictStore, useTerminalStore } from '@/store';
|
||||
import { useDictStore, useTerminalStore } from '@/store';
|
||||
import { PreferenceItem } from '@/store/modules/terminal';
|
||||
import { dataColor } from '@/utils';
|
||||
import { tagColor } from '@/views/asset/host-list/types/const';
|
||||
import { getLatestConnectHostId } from '@/api/asset/host-connect-log';
|
||||
import HostsView from './hosts-view.vue';
|
||||
|
||||
const { loading, setLoading } = useLoading();
|
||||
const { toRadioOptions } = useDictStore();
|
||||
const { preference, updateTerminalPreference } = useTerminalStore();
|
||||
const { preference, updateTerminalPreference, hosts, loadHosts } = useTerminalStore();
|
||||
|
||||
const newConnectionType = ref(preference.newConnectionType || NewConnectionType.GROUP);
|
||||
const filterValue = ref('');
|
||||
const filterOptions = ref<Array<SelectOptionData>>([]);
|
||||
const hosts = ref<AuthorizedHostQueryResponse>({} as AuthorizedHostQueryResponse);
|
||||
const latestHosts = ref<Array<number>>([]);
|
||||
|
||||
// 过滤输入
|
||||
const searchFilter = (searchValue: string, option: SelectOptionData) => {
|
||||
@@ -112,7 +106,7 @@
|
||||
// 初始化过滤器项
|
||||
const initFilterOptions = () => {
|
||||
// 添加 tags
|
||||
const tagNames = hosts.value.hostList?.map(s => s.tags)
|
||||
const tagNames = hosts.hostList?.map(s => s.tags)
|
||||
.filter(s => s?.length)
|
||||
.flat(1)
|
||||
.sort((o1, o2) => o1.id - o2.id)
|
||||
@@ -121,7 +115,7 @@
|
||||
return { label: value, value: `@${value}`, isTag: true };
|
||||
}).forEach(s => filterOptions.value.push(s));
|
||||
// 添加主机信息
|
||||
const hostMeta = hosts.value.hostList?.map(s => {
|
||||
const hostMeta = hosts.hostList?.map(s => {
|
||||
return [s.name, s.code, s.address, s.alias];
|
||||
}).filter(Boolean).flat(1);
|
||||
[...new Set(hostMeta)].map(value => {
|
||||
@@ -134,8 +128,7 @@
|
||||
try {
|
||||
setLoading(true);
|
||||
// 加载主机信息
|
||||
const { data } = await getCurrentAuthorizedHost();
|
||||
hosts.value = data;
|
||||
await loadHosts();
|
||||
// 初始化过滤项
|
||||
initFilterOptions();
|
||||
} finally {
|
||||
@@ -143,24 +136,9 @@
|
||||
}
|
||||
};
|
||||
|
||||
// 加载最近连接主机
|
||||
const loadLatestConnectHost = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
// 加载最近连接主机
|
||||
const { data } = await getLatestConnectHostId('SSH', useAppStore().defaultTablePageSize);
|
||||
latestHosts.value = data;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 加载主机信息
|
||||
onBeforeMount(initHosts);
|
||||
|
||||
// 加载最近连接主机
|
||||
onBeforeMount(loadLatestConnectHost);
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
@@ -82,7 +82,8 @@
|
||||
const terminalRef = ref();
|
||||
const session = ref<ITerminalSession>();
|
||||
|
||||
// FIXME
|
||||
// TODO
|
||||
// index 页面
|
||||
// 搜索 search color 配置
|
||||
// 右键菜单补充 启用右键菜单 enableRightClickMenu 粘贴逻辑
|
||||
// 快捷键补充 粘贴逻辑
|
||||
|
||||
Reference in New Issue
Block a user