4848 :data =" treeData"
4949 :props =" treeProps"
5050 node-key =" id"
51- default-expand-all
51+ : default-expanded-keys = " expandedHistoryKeys "
5252 highlight-current
5353 @node-click =" handleTreeNodeClick"
54+ @node-expand =" handleNodeExpand"
55+ @node-collapse =" handleNodeCollapse"
5456 >
5557 <template #default =" { node , data } " >
5658 <div class =" tree-node" :class =" { 'is-leaf': data.isLeaf }" >
107109 <el-form-item label =" 服务器名称" prop =" name" >
108110 <el-input v-model =" form.name" placeholder =" 请输入服务器名称(可选)" />
109111 </el-form-item >
112+
113+ <el-form-item label =" 所属分组" prop =" group" >
114+ <el-select
115+ v-model =" form.group"
116+ filterable
117+ allow-create
118+ default-first-option
119+ placeholder =" 请输入或选择分组名称(可选)"
120+ style =" width : 100% "
121+ >
122+ <el-option
123+ v-for =" item in availableGroups"
124+ :key =" item"
125+ :label =" item"
126+ :value =" item"
127+ />
128+ </el-select >
129+ </el-form-item >
110130
111131 <el-form-item label =" 主机地址" prop =" host" >
112132 <el-input v-model =" form.host" placeholder =" 请输入IP地址或域名" />
@@ -211,7 +231,6 @@ import { useTerminalStore } from '@/stores/terminal'
211231import { useAuthStore } from ' @/stores/auth'
212232
213233const HISTORY_KEY = ' webssh_quick_connect_history'
214- const MAX_HISTORY = 20
215234
216235const router = useRouter ()
217236const authStore = useAuthStore ()
@@ -227,6 +246,7 @@ const historyList = ref([])
227246
228247const form = reactive ({
229248 name: ' ' ,
249+ group: ' ' ,
230250 host: ' ' ,
231251 port: 22 ,
232252 username: ' ' ,
@@ -272,19 +292,30 @@ const rules = {
272292 ]
273293}
274294
275- // ========== 树形数据 ==========
295+ // ========== 树形数据 & 分组下拉 ==========
296+
297+ // 提取历史记录中出现过的所有分组(去重)
298+ const availableGroups = computed (() => {
299+ const groups = new Set ()
300+ historyList .value .forEach (item => {
301+ if (item .group ) {
302+ groups .add (item .group )
303+ }
304+ })
305+ return Array .from (groups).sort ()
306+ })
276307
277308const treeProps = {
278309 children: ' children' ,
279310 label: ' label'
280311}
281312
282- // 将 historyList 转换为树形结构,按主机地址分组
313+ // 将 historyList 转换为树形结构,按分组名称分组
283314const treeData = computed (() => {
284315 const groups = {}
285316
286317 historyList .value .forEach ((item , index ) => {
287- const groupKey = item .host
318+ const groupKey = item .group || ' 未分组 '
288319 if (! groups[groupKey]) {
289320 groups[groupKey] = {
290321 id: ` group-${ groupKey} ` ,
@@ -313,6 +344,24 @@ const handleTreeNodeClick = (data) => {
313344 }
314345}
315346
347+ // ========== 分组展开状态持久化 (sessionStorage) ==========
348+ const EXPANDED_HISTORY_KEYS_KEY = ' webssh_quick_connect_expanded_keys'
349+ const expandedHistoryKeys = ref (JSON .parse (sessionStorage .getItem (EXPANDED_HISTORY_KEYS_KEY ) || ' []' ))
350+
351+ const handleNodeExpand = (data ) => {
352+ if (! data .isLeaf && ! expandedHistoryKeys .value .includes (data .id )) {
353+ expandedHistoryKeys .value .push (data .id )
354+ sessionStorage .setItem (EXPANDED_HISTORY_KEYS_KEY , JSON .stringify (expandedHistoryKeys .value ))
355+ }
356+ }
357+
358+ const handleNodeCollapse = (data ) => {
359+ if (! data .isLeaf ) {
360+ expandedHistoryKeys .value = expandedHistoryKeys .value .filter (id => id !== data .id )
361+ sessionStorage .setItem (EXPANDED_HISTORY_KEYS_KEY , JSON .stringify (expandedHistoryKeys .value ))
362+ }
363+ }
364+
316365// ========== 历史记录管理 ==========
317366
318367const loadHistory = () => {
@@ -331,6 +380,7 @@ const persistHistory = () => {
331380const saveToHistory = () => {
332381 const record = {
333382 name: form .name || ' ' ,
383+ group: form .group || ' ' ,
334384 host: form .host ,
335385 port: form .port ,
336386 username: form .username ,
@@ -356,15 +406,12 @@ const saveToHistory = () => {
356406
357407 historyList .value .unshift (record)
358408
359- if (historyList .value .length > MAX_HISTORY ) {
360- historyList .value = historyList .value .slice (0 , MAX_HISTORY )
361- }
362-
363409 persistHistory ()
364410}
365411
366412const fillFromHistory = (item ) => {
367413 form .name = item .name || ' '
414+ form .group = item .group || ' '
368415 form .host = item .host
369416 form .port = item .port
370417 form .username = item .username
@@ -464,11 +511,6 @@ const handleImportFile = (event) => {
464511 merged .unshift (item)
465512 })
466513
467- // 限制最大条数
468- if (merged .length > MAX_HISTORY ) {
469- merged = merged .slice (0 , MAX_HISTORY )
470- }
471-
472514 historyList .value = merged
473515 persistHistory ()
474516 ElMessage .success (` 成功导入 ${ addedCount} 条连接记录` )
0 commit comments