From 7be48c3774afc5f676698dab998d65a936326632 Mon Sep 17 00:00:00 2001 From: lijiahangmax Date: Mon, 18 Dec 2023 00:15:56 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E4=BF=AE=E6=94=B9=20tag=20selector?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/TerminalPreferenceModel.java | 7 +- .../strategy/TerminalPreferenceStrategy.java | 3 +- .../meta/tag/tag-multi-selector.vue | 19 ++++- .../src/store/modules/terminal/index.ts | 81 ++++++++++++++----- .../src/store/modules/terminal/types.ts | 31 +++---- orion-ops-ui/src/utils/index.ts | 9 ++- .../host-list/components/host-card-list.vue | 1 + .../host-list/components/host-form-modal.vue | 2 + .../asset/host-list/components/host-table.vue | 1 + .../components/layout/terminal-header.vue | 4 +- .../layout/terminal-left-sidebar.vue | 7 +- .../new-connection/new-connection-view.vue | 20 ++--- .../view-setting/terminal-display-block.vue | 24 ++---- .../view-setting/terminal-theme-block.vue | 40 +-------- sql/init-3-data.sql | 2 +- sql/常用.sql | 5 ++ 16 files changed, 141 insertions(+), 115 deletions(-) diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/handler/preference/model/TerminalPreferenceModel.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/handler/preference/model/TerminalPreferenceModel.java index b0d1a3dc..c60c254e 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/handler/preference/model/TerminalPreferenceModel.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/handler/preference/model/TerminalPreferenceModel.java @@ -24,8 +24,8 @@ public class TerminalPreferenceModel implements PreferenceModel { @Schema(description = "暗色主题") private String darkTheme; - @Schema(description = "终端主题") - private JSONObject themeSchema; + @Schema(description = "新建连接类型") + private String newConnectionType; @Schema(description = "显示设置") private JSONObject displaySetting; @@ -33,6 +33,9 @@ public class TerminalPreferenceModel implements PreferenceModel { @Schema(description = "背景设置") private JSONObject backgroundSetting; + @Schema(description = "终端主题") + private JSONObject themeSchema; + @Data @Builder @NoArgsConstructor diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/handler/preference/strategy/TerminalPreferenceStrategy.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/handler/preference/strategy/TerminalPreferenceStrategy.java index bbd3875a..44036d37 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/handler/preference/strategy/TerminalPreferenceStrategy.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/handler/preference/strategy/TerminalPreferenceStrategy.java @@ -18,7 +18,7 @@ public class TerminalPreferenceStrategy implements IPreferenceStrategy + @@ -23,7 +28,7 @@ import type { TagCreateRequest } from '@/api/meta/tag'; import { ref, computed, onBeforeMount } from 'vue'; import { useCacheStore } from '@/store'; - import { Message } from '@arco-design/web-vue'; + import { dataColor } from '@/utils'; import { createTag } from '@/api/meta/tag'; import useLoading from '@/hooks/loading'; @@ -33,6 +38,10 @@ limit: Number, type: String, allowCreate: Boolean, + tagColor: { + type: Array as PropType>, + default: () => [] + }, }); const emits = defineEmits(['update:modelValue', 'onLimited']); @@ -95,7 +104,10 @@ // 插入 options optionData.value.push({ label: name, - value: id + value: id, + tagProps: { + color: dataColor(name, props.tagColor) + } }); return id; }; @@ -109,6 +121,9 @@ return { label: s.name, value: s.id, + tagProps: { + color: dataColor(s.name, props.tagColor) + } }; }); } catch (e) { diff --git a/orion-ops-ui/src/store/modules/terminal/index.ts b/orion-ops-ui/src/store/modules/terminal/index.ts index f7c78597..e2ce6a8b 100644 --- a/orion-ops-ui/src/store/modules/terminal/index.ts +++ b/orion-ops-ui/src/store/modules/terminal/index.ts @@ -2,7 +2,7 @@ import type { TerminalDisplaySetting, TerminalPreference, TerminalState, Termina import { defineStore } from 'pinia'; import { getPreference, updatePreferencePartial } from '@/api/user/preference'; import { Message } from '@arco-design/web-vue'; -import { useDark } from '@vueuse/core'; +import { useDark, useDebounceFn } from '@vueuse/core'; import { DEFAULT_SCHEMA } from '@/views/host-ops/terminal/types/terminal.theme'; // 暗色主题 @@ -24,17 +24,13 @@ export default defineStore('terminal', { }), preference: { darkTheme: 'auto', - themeSchema: {} as TerminalThemeSchema, - displaySetting: {} as TerminalDisplaySetting + newConnectionType: 'group', + displaySetting: {} as TerminalDisplaySetting, + themeSchema: {} as TerminalThemeSchema }, }), actions: { - // 修改暗色主题 - changeDarkTheme(dark: boolean) { - this.isDarkTheme = dark; - }, - // 加载终端偏好 async fetchPreference() { try { @@ -56,18 +52,67 @@ export default defineStore('terminal', { } }, - // 更新终端偏好 - async updatePreference() { - try { - // 修改配置 - await updatePreferencePartial({ - type: 'TERMINAL', - config: this.preference - }); - } catch (e) { - Message.error('同步失败'); + // 修改暗色主题 + changeDarkTheme(darkTheme: string) { + this.preference.darkTheme = darkTheme; + if (darkTheme === DarkTheme.DARK) { + // 暗色 + this.isDarkTheme = true; + } else if (darkTheme === DarkTheme.LIGHT) { + // 亮色 + this.isDarkTheme = false; + } else if (darkTheme === DarkTheme.AUTO) { + // 自动配色 + this.isDarkTheme = this.preference.themeSchema.dark; } + // 同步配置 + this.updateTerminalPreference(); }, + // 修改显示配置 + changeDisplaySetting(displaySetting: TerminalDisplaySetting) { + this.preference.displaySetting = displaySetting; + // 同步配置 + this.updateTerminalPreference(); + }, + + // 选择终端主题 + changeThemeSchema(themeSchema: TerminalThemeSchema) { + this.preference.themeSchema = themeSchema; + // 切换主题配色 + if (this.preference.darkTheme === DarkTheme.AUTO) { + this.isDarkTheme = themeSchema.dark; + } + // 同步配置 + this.updateTerminalPreference(); + }, + + // 切换新建连接类型 + changeNewConnectionType(newConnectionType: string) { + this.preference.newConnectionType = newConnectionType; + // 同步配置 + this.updateTerminalPreference(); + }, + + // 更新终端偏好-防抖 + updateTerminalPreference() { + // 初始化函数 + if (!this.updateTerminalPreferenceFn) { + this.updateTerminalPreferenceFn = useDebounceFn(async () => { + try { + // 修改配置 + await updatePreferencePartial({ + type: 'TERMINAL', + config: this.preference + }); + } catch (e) { + Message.error('同步失败'); + } + }, 1500); + } + // 更新 + this.updateTerminalPreferenceFn(); + } + }, }); diff --git a/orion-ops-ui/src/store/modules/terminal/types.ts b/orion-ops-ui/src/store/modules/terminal/types.ts index 14cef453..60dce0ba 100644 --- a/orion-ops-ui/src/store/modules/terminal/types.ts +++ b/orion-ops-ui/src/store/modules/terminal/types.ts @@ -3,13 +3,27 @@ import type { Ref } from 'vue'; export interface TerminalState { isDarkTheme: Ref; preference: TerminalPreference; + + updateTerminalPreferenceFn?: () => void; } // 终端配置 export interface TerminalPreference { - darkTheme: string, - themeSchema: TerminalThemeSchema, - displaySetting: TerminalDisplaySetting, + darkTheme: string; + newConnectionType: string; + displaySetting: TerminalDisplaySetting; + themeSchema: TerminalThemeSchema; +} + +// 显示设置 +export interface TerminalDisplaySetting { + fontFamily?: string; + fontSize?: number; + lineHeight?: number; + fontWeight?: string | number; + fontWeightBold?: string | number; + cursorStyle?: string; + cursorBlink?: boolean; } // 终端主题 @@ -42,14 +56,3 @@ export interface TerminalThemeSchema { [key: string]: unknown; } - -// 显示设置 -export interface TerminalDisplaySetting { - fontFamily?: string; - fontSize?: number; - lineHeight?: number; - fontWeight?: string | number; - fontWeightBold?: string | number; - cursorStyle?: string; - cursorBlink?: boolean; -} diff --git a/orion-ops-ui/src/utils/index.ts b/orion-ops-ui/src/utils/index.ts index 8c0b48b3..b9299639 100644 --- a/orion-ops-ui/src/utils/index.ts +++ b/orion-ops-ui/src/utils/index.ts @@ -40,7 +40,10 @@ export function md5(plain: string): string { /** * 获取数据颜色 */ -export function dataColor(str: string, colors: string[]): string { +export function dataColor(str: string, colors: string[], defaultColor = ''): string { + if (!colors?.length) { + return defaultColor; + } let total = 0; for (let i = 0; i < str.length; i++) { total += str.charCodeAt(i); @@ -160,7 +163,7 @@ export const resetObject = (obj: any, ignore: string[] = []) => { export const objectTruthKeyCount = (obj: any, ignore: string[] = []) => { return Object.keys(obj) .filter(s => !ignore.includes(s)) - .reduce(function(acc, curr) { + .reduce(function (acc, curr) { const currVal = obj[curr]; return acc + ~~(currVal !== undefined && currVal !== null && currVal?.length !== 0 && currVal !== ''); }, 0); @@ -200,7 +203,7 @@ export function getRoute(url = location.href) { * 获取唯一的 UUID */ export function getUUID() { - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { const r = Math.random() * 16 | 0; const v = c === 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); diff --git a/orion-ops-ui/src/views/asset/host-list/components/host-card-list.vue b/orion-ops-ui/src/views/asset/host-list/components/host-card-list.vue index c09a46a2..4b092d4b 100644 --- a/orion-ops-ui/src/views/asset/host-list/components/host-card-list.vue +++ b/orion-ops-ui/src/views/asset/host-list/components/host-card-list.vue @@ -78,6 +78,7 @@ :allowCreate="false" :limit="0" type="HOST" + :tagColor="tagColor" placeholder="请选择主机标签" /> diff --git a/orion-ops-ui/src/views/asset/host-list/components/host-form-modal.vue b/orion-ops-ui/src/views/asset/host-list/components/host-form-modal.vue index 3c85bca8..47b95fee 100644 --- a/orion-ops-ui/src/views/asset/host-list/components/host-form-modal.vue +++ b/orion-ops-ui/src/views/asset/host-list/components/host-form-modal.vue @@ -43,6 +43,7 @@ :allowCreate="true" :limit="5" type="HOST" + :tagColor="tagColor" placeholder="请选择主机标签" @onLimited="onLimitedTag" /> @@ -68,6 +69,7 @@ import { pick } from 'lodash'; import TagMultiSelector from '@/components/meta/tag/tag-multi-selector.vue'; import HostGroupTreeSelector from '@/components/asset/host-group/host-group-tree-selector.vue'; + import { tagColor } from '@/views/asset/host-list/types/const'; const { visible, setVisible } = useVisible(); const { loading, setLoading } = useLoading(); diff --git a/orion-ops-ui/src/views/asset/host-list/components/host-table.vue b/orion-ops-ui/src/views/asset/host-list/components/host-table.vue index 1363a720..09190159 100644 --- a/orion-ops-ui/src/views/asset/host-list/components/host-table.vue +++ b/orion-ops-ui/src/views/asset/host-list/components/host-table.vue @@ -32,6 +32,7 @@ :allowCreate="false" :limit="0" type="HOST" + :tagColor="tagColor" placeholder="请选择主机标签" /> diff --git a/orion-ops-ui/src/views/host-ops/terminal/components/layout/terminal-header.vue b/orion-ops-ui/src/views/host-ops/terminal/components/layout/terminal-header.vue index b71928ff..5160e61d 100644 --- a/orion-ops-ui/src/views/host-ops/terminal/components/layout/terminal-header.vue +++ b/orion-ops-ui/src/views/host-ops/terminal/components/layout/terminal-header.vue @@ -56,6 +56,7 @@ import { computed } from 'vue'; import IconActions from '../layout/icon-actions.vue'; import { useTerminalStore } from '@/store'; + import { DarkTheme } from '@/store/modules/terminal'; const props = defineProps({ modelValue: { @@ -82,10 +83,9 @@ click: () => emits('share') }, { - // FIXME 持久化 icon: terminalStore.isDarkTheme ? 'icon-sun-fill' : 'icon-moon-fill', content: terminalStore.isDarkTheme ? '点击切换为亮色模式' : '点击切换为暗色模式', - click: () => terminalStore.changeDarkTheme(!terminalStore.isDarkTheme) + click: () => terminalStore.changeDarkTheme(terminalStore.isDarkTheme ? DarkTheme.LIGHT : DarkTheme.DARK) }, { icon: isFullscreen.value ? 'icon-fullscreen-exit' : 'icon-fullscreen', diff --git a/orion-ops-ui/src/views/host-ops/terminal/components/layout/terminal-left-sidebar.vue b/orion-ops-ui/src/views/host-ops/terminal/components/layout/terminal-left-sidebar.vue index 7c8631e1..22f86b18 100644 --- a/orion-ops-ui/src/views/host-ops/terminal/components/layout/terminal-left-sidebar.vue +++ b/orion-ops-ui/src/views/host-ops/terminal/components/layout/terminal-left-sidebar.vue @@ -22,7 +22,7 @@ import { InnerTabs } from '../../types/terminal.const'; import IconActions from './icon-actions.vue'; - const emits = defineEmits(['switchTab', 'copyAddress']); + const emits = defineEmits(['switchTab']); // 顶部操作 const topActions: Array = [ @@ -31,11 +31,6 @@ content: '新建连接', click: () => emits('switchTab', InnerTabs.NEW_CONNECTION) }, - { - icon: 'icon-copy', - content: '复制主机IP', - click: () => emits('copyAddress') - }, ]; // 底部操作 diff --git a/orion-ops-ui/src/views/host-ops/terminal/components/new-connection/new-connection-view.vue b/orion-ops-ui/src/views/host-ops/terminal/components/new-connection/new-connection-view.vue index 6aabf374..29ff7d8f 100644 --- a/orion-ops-ui/src/views/host-ops/terminal/components/new-connection/new-connection-view.vue +++ b/orion-ops-ui/src/views/host-ops/terminal/components/new-connection/new-connection-view.vue @@ -10,7 +10,7 @@ type="button" class="usn" :options="toOptions(NewConnectionTypeKey)" - @change="changeConnectionType" /> + @change="changeNewConnectionType" /> + class="host-view-container" + :hosts="hosts" + :filter-value="filterValue" + :new-connection-type="newConnectionType" /> @@ -80,15 +80,16 @@ import { onBeforeMount, ref } from 'vue'; import { NewConnectionType, NewConnectionTypeKey } from '../../types/terminal.const'; import useLoading from '@/hooks/loading'; - import { useDictStore } from '@/store'; + import { useDictStore, useTerminalStore } from '@/store'; import { dataColor } from '@/utils'; import { tagColor } from '@/views/asset/host-list/types/const'; import HostsView from './hosts-view.vue'; const { loading, setLoading } = useLoading(); const { toOptions } = useDictStore(); + const { preference, changeNewConnectionType } = useTerminalStore(); - const newConnectionType = ref(NewConnectionType.GROUP); + const newConnectionType = ref(preference.newConnectionType || NewConnectionType.GROUP); const filterValue = ref(''); const filterOptions = ref>([]); const hosts = ref({} as AuthorizedHostQueryResponse); @@ -124,11 +125,6 @@ }).forEach(s => filterOptions.value.push(s)); }; - // 修改连接类型 - const changeConnectionType = () => { - // FIXME 持久化类型 - }; - // 初始化 const init = async () => { try { diff --git a/orion-ops-ui/src/views/host-ops/terminal/components/view-setting/terminal-display-block.vue b/orion-ops-ui/src/views/host-ops/terminal/components/view-setting/terminal-display-block.vue index 95156d49..dcbee392 100644 --- a/orion-ops-ui/src/views/host-ops/terminal/components/view-setting/terminal-display-block.vue +++ b/orion-ops-ui/src/views/host-ops/terminal/components/view-setting/terminal-display-block.vue @@ -79,7 +79,7 @@
预览效果
+ :style="{ background: preference.themeSchema?.background }">
@@ -96,22 +96,19 @@