1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-01-19 08:19:15 +08:00

feat: 增加终端自定义配置 (#6208)

This commit is contained in:
ssongliu 2024-08-22 18:46:54 +08:00 committed by GitHub
parent 12b7f806f9
commit cfe4fa7a92
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 533 additions and 28 deletions

View File

@ -29,6 +29,21 @@ func (b *BaseApi) GetSettingInfo(c *gin.Context) {
helper.SuccessWithData(c, setting)
}
// @Tags System Setting
// @Summary Load system terminal setting info
// @Description 加载系统终端配置信息
// @Success 200 {object} dto.TerminalInfo
// @Security ApiKeyAuth
// @Router /core/settings/terminal/search [post]
func (b *BaseApi) GetTerminalSettingInfo(c *gin.Context) {
setting, err := settingService.GetTerminalInfo()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, setting)
}
// @Tags System Setting
// @Summary Load system available status
// @Description 获取系统可用状态
@ -61,6 +76,28 @@ func (b *BaseApi) UpdateSetting(c *gin.Context) {
helper.SuccessWithData(c, nil)
}
// @Tags System Setting
// @Summary Update system terminal setting
// @Description 更新系统终端配置
// @Accept json
// @Param request body dto.TerminalInfo true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /core/settings/terminal/update [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改系统终端配置","formatEN":"update system terminal setting"}
func (b *BaseApi) UpdateTerminalSetting(c *gin.Context) {
var req dto.TerminalInfo
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := settingService.UpdateTerminal(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags System Setting
// @Summary Update proxy setting
// @Description 服务器代理配置

View File

@ -196,3 +196,13 @@ type XpackHideMenu struct {
Path string `json:"path,omitempty"`
Children []XpackHideMenu `json:"children,omitempty"`
}
type TerminalInfo struct {
LineHeight string `json:"lineHeight"`
LetterSpacing string `json:"letterSpacing"`
FontSize string `json:"fontSize"`
CursorBlink string `json:"cursorBlink"`
CursorStyle string `json:"cursorStyle"`
Scrollback string `json:"scrollback"`
ScrollSensitivity string `json:"scrollSensitivity"`
}

View File

@ -36,6 +36,9 @@ type ISettingService interface {
UpdateSSL(c *gin.Context, req dto.SSLUpdate) error
LoadFromCert() (*dto.SSLInfo, error)
HandlePasswordExpired(c *gin.Context, old, new string) error
GetTerminalInfo() (*dto.TerminalInfo, error)
UpdateTerminal(req dto.TerminalInfo) error
}
func NewISettingService() ISettingService {
@ -338,6 +341,50 @@ func (u *SettingService) HandlePasswordExpired(c *gin.Context, old, new string)
return constant.ErrInitialPassword
}
func (u *SettingService) GetTerminalInfo() (*dto.TerminalInfo, error) {
setting, err := settingRepo.List()
if err != nil {
return nil, constant.ErrRecordNotFound
}
settingMap := make(map[string]string)
for _, set := range setting {
settingMap[set.Key] = set.Value
}
var info dto.TerminalInfo
arr, err := json.Marshal(settingMap)
if err != nil {
return nil, err
}
if err := json.Unmarshal(arr, &info); err != nil {
return nil, err
}
return &info, err
}
func (u *SettingService) UpdateTerminal(req dto.TerminalInfo) error {
if err := settingRepo.Update("LineHeight", req.LineHeight); err != nil {
return err
}
if err := settingRepo.Update("LetterSpacing", req.LetterSpacing); err != nil {
return err
}
if err := settingRepo.Update("FontSize", req.FontSize); err != nil {
return err
}
if err := settingRepo.Update("CursorBlink", req.CursorBlink); err != nil {
return err
}
if err := settingRepo.Update("CursorStyle", req.CursorStyle); err != nil {
return err
}
if err := settingRepo.Update("Scrollback", req.Scrollback); err != nil {
return err
}
if err := settingRepo.Update("ScrollSensitivity", req.ScrollSensitivity); err != nil {
return err
}
return nil
}
func (u *SettingService) UpdatePassword(c *gin.Context, old, new string) error {
if err := u.HandlePasswordExpired(c, old, new); err != nil {
return err

View File

@ -14,6 +14,7 @@ func Init() {
migrations.InitOneDrive,
migrations.InitMasterAddr,
migrations.InitHost,
migrations.InitTerminalSetting,
})
if err := m.Migrate(); err != nil {
global.LOG.Error(err)

View File

@ -205,3 +205,31 @@ var InitMasterAddr = &gormigrate.Migration{
return nil
},
}
var InitTerminalSetting = &gormigrate.Migration{
ID: "20240814-init-terminal-setting",
Migrate: func(tx *gorm.DB) error {
if err := tx.Create(&model.Setting{Key: "LineHeight", Value: "1.2"}).Error; err != nil {
return err
}
if err := tx.Create(&model.Setting{Key: "LetterSpacing", Value: "0"}).Error; err != nil {
return err
}
if err := tx.Create(&model.Setting{Key: "FontSize", Value: "12"}).Error; err != nil {
return err
}
if err := tx.Create(&model.Setting{Key: "CursorBlink", Value: "enable"}).Error; err != nil {
return err
}
if err := tx.Create(&model.Setting{Key: "CursorStyle", Value: "block"}).Error; err != nil {
return err
}
if err := tx.Create(&model.Setting{Key: "Scrollback", Value: "1000"}).Error; err != nil {
return err
}
if err := tx.Create(&model.Setting{Key: "ScrollSensitivity", Value: "6"}).Error; err != nil {
return err
}
return nil
},
}

View File

@ -12,9 +12,11 @@ func (s *SettingRouter) InitRouter(Router *gin.RouterGroup) {
baseApi := v2.ApiGroupApp.BaseApi
{
settingRouter.POST("/search", baseApi.GetSettingInfo)
settingRouter.POST("/terminal/search", baseApi.GetTerminalSettingInfo)
settingRouter.POST("/expired/handle", baseApi.HandlePasswordExpired)
settingRouter.GET("/search/available", baseApi.GetSystemAvailable)
settingRouter.POST("/update", baseApi.UpdateSetting)
settingRouter.POST("/terminal/update", baseApi.UpdateTerminalSetting)
settingRouter.GET("/interface", baseApi.LoadInterfaceAddr)
settingRouter.POST("/menu/update", baseApi.UpdateMenu)
settingRouter.POST("/proxy/update", baseApi.UpdateProxy)

View File

@ -59,6 +59,15 @@ export namespace Setting {
proxyPasswd: string;
proxyPasswdKeep: string;
}
export interface TerminalInfo {
lineHeight: string;
letterSpacing: string;
fontSize: string;
cursorBlink: string;
cursorStyle: string;
scrollback: string;
scrollSensitivity: string;
}
export interface SettingUpdate {
key: string;
value: string;

View File

@ -33,6 +33,12 @@ export const loadDaemonJsonPath = () => {
export const getSettingInfo = () => {
return http.post<Setting.SettingInfo>(`/core/settings/search`);
};
export const getTerminalInfo = () => {
return http.post<Setting.TerminalInfo>(`/core/settings/terminal/search`);
};
export const UpdateTerminalInfo = (param: Setting.TerminalInfo) => {
return http.post(`/core/settings/terminal/update`, param);
};
export const getSystemAvailable = () => {
return http.get(`/settings/search/available`);
};

View File

@ -1,5 +1,5 @@
<template>
<div ref="terminalElement" @wheel="onTermWheel"></div>
<div ref="terminalElement"></div>
</template>
<script lang="ts" setup>
@ -8,6 +8,7 @@ import { Terminal } from '@xterm/xterm';
import '@xterm/xterm/css/xterm.css';
import { FitAddon } from '@xterm/addon-fit';
import { Base64 } from 'js-base64';
import { TerminalStore } from '@/store';
const terminalElement = ref<HTMLDivElement | null>(null);
const fitAddon = new FitAddon();
@ -29,6 +30,33 @@ const readyWatcher = watch(
},
);
const terminalStore = TerminalStore();
const lineHeight = computed(() => terminalStore.lineHeight);
const fontSize = computed(() => terminalStore.fontSize);
const letterSpacing = computed(() => terminalStore.letterSpacing);
watch([lineHeight, fontSize, letterSpacing], ([newLineHeight, newFontSize, newLetterSpacing]) => {
term.value.options.lineHeight = newLineHeight;
term.value.options.letterSpacing = newLetterSpacing;
term.value.options.fontSize = newFontSize;
changeTerminalSize();
});
const cursorStyle = computed(() => terminalStore.cursorStyle);
watch(cursorStyle, (newCursorStyle) => {
term.value.options.cursorStyle = newCursorStyle;
});
const cursorBlink = computed(() => terminalStore.cursorBlink);
watch(cursorBlink, (newCursorBlink) => {
term.value.options.cursorBlink = newCursorBlink === 'enable';
});
const scrollback = computed(() => terminalStore.scrollback);
watch(scrollback, (newScrollback) => {
term.value.options.scrollback = newScrollback;
});
const scrollSensitivity = computed(() => terminalStore.scrollSensitivity);
watch(scrollSensitivity, (newScrollSensitivity) => {
term.value.options.scrollSensitivity = newScrollSensitivity;
});
interface WsProps {
endpoint: string;
args: string;
@ -58,7 +86,6 @@ const newTerm = () => {
cursorStyle: 'underline',
scrollback: 1000,
scrollSensitivity: 15,
tabStopWidth: 4,
});
};
@ -117,25 +144,6 @@ function changeTerminalSize() {
}
}
/**
* Support for Ctrl+MouseWheel to scaling fonts
* @param event WheelEvent
*/
const onTermWheel = (event: WheelEvent) => {
if (event.ctrlKey) {
event.preventDefault();
if (event.deltaY > 0) {
// web font-size mini 12px
if (term.value.options.fontSize > 12) {
term.value.options.fontSize = term.value.options.fontSize - 1;
}
} else {
term.value.options.fontSize = term.value.options.fontSize + 1;
}
changeTerminalSize();
}
};
// terminal end
// websocket start
@ -201,7 +209,7 @@ const errorRealTerminal = (ex: any) => {
const closeRealTerminal = (ev: CloseEvent) => {
if (heartbeatTimer.value) {
clearInterval(heartbeatTimer.value);
clearInterval(Number(heartbeatTimer.value));
}
term.value.write('The connection has been disconnected.');
term.value.write(ev.reason);

View File

@ -24,6 +24,7 @@ const message = {
confirm: 'Confirm',
cancel: 'Cancel',
reset: 'Reset',
setDefault: 'Restore Default',
restart: 'Restart',
conn: 'Connect',
disconn: 'Disconnect',
@ -319,7 +320,7 @@ const message = {
security: 'Security',
files: 'File',
monitor: 'Monitor',
terminal: 'Terminal',
terminal: 'Web Terminal',
settings: 'Setting',
toolbox: 'Toolbox',
logs: 'Log',
@ -994,6 +995,17 @@ const message = {
key: 'Private key',
keyPassword: 'Private key password',
emptyTerminal: 'No terminal is currently connected',
lineHeight: 'Line Height',
letterSpacing: 'Letter Spacing',
fontSize: 'Font Size',
cursorBlink: 'Cursor Blink',
cursorStyle: 'Cursor Style',
cursorUnderline: 'Underline',
cursorBlock: 'Block',
cursorBar: 'Bar',
scrollback: 'Scrollback',
scrollSensitivity: 'Scroll Sensitivity',
saveHelper: 'Are you sure you want to save the current terminal configuration?',
},
toolbox: {
swap: {

View File

@ -23,6 +23,7 @@ const message = {
confirm: '確認',
cancel: '取消',
reset: '重置',
setDefault: '恢復預設',
restart: '重啟',
conn: '連接',
disconn: '斷開',
@ -313,7 +314,7 @@ const message = {
host: '主機',
files: '文件',
monitor: '監控',
terminal: '終端',
terminal: 'Web終端',
settings: '面板設置',
toolbox: '工具箱',
logs: '日誌審計',
@ -947,6 +948,17 @@ const message = {
key: '私鑰',
keyPassword: '私鑰密碼',
emptyTerminal: '暫無終端連接',
lineHeight: '字體行高',
letterSpacing: '字體間距',
fontSize: '字體大小',
cursorBlink: '光標閃爍',
cursorStyle: '光標樣式',
cursorUnderline: '下劃線',
cursorBlock: '塊狀',
cursorBar: '條形',
scrollback: '滾動行數',
scrollSensitivity: '滾動速度',
saveHelper: '是否確認保存當前終端配置',
},
toolbox: {
swap: {

View File

@ -23,6 +23,7 @@ const message = {
confirm: '确认',
cancel: '取消',
reset: '重置',
setDefault: '恢复默认',
restart: '重启',
conn: '连接',
disconn: '断开',
@ -948,6 +949,17 @@ const message = {
key: '私钥',
keyPassword: '私钥密码',
emptyTerminal: '暂无终端连接',
lineHeight: '字体行高',
letterSpacing: '字体间距',
fontSize: '字体大小',
cursorBlink: '光标闪烁',
cursorStyle: '光标样式',
cursorUnderline: '下划线',
cursorBlock: '块状',
cursorBar: '条形',
scrollback: '滚动行数',
scrollSensitivity: '滚动速度',
saveHelper: '是否确认保存当前终端配置',
},
toolbox: {
swap: {
@ -1121,7 +1133,7 @@ const message = {
role: '权限',
info: '属性',
linkFile: '软连接文件',
terminal: '终端',
terminal: 'Web终端',
shareList: '分享列表',
zip: '压缩',
group: '用户组',

View File

@ -3,10 +3,11 @@ import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
import GlobalStore from './modules/global';
import MenuStore from './modules/menu';
import TabsStore from './modules/tabs';
import TerminalStore from './modules/terminal';
const pinia = createPinia();
pinia.use(piniaPluginPersistedstate);
export { GlobalStore, MenuStore, TabsStore };
export { GlobalStore, MenuStore, TabsStore, TerminalStore };
export default pinia;

View File

@ -46,3 +46,13 @@ export interface MenuState {
menuList: RouteRecordRaw[];
withoutAnimation: boolean;
}
export interface TerminalState {
lineHeight: number;
letterSpacing: number;
fontSize: number;
cursorBlink: string;
cursorStyle: string;
scrollback: number;
scrollSensitivity: number;
}

View File

@ -0,0 +1,42 @@
import { defineStore } from 'pinia';
import piniaPersistConfig from '@/config/pinia-persist';
import { TerminalState } from '../interface';
export const TerminalStore = defineStore({
id: 'TerminalState',
state: (): TerminalState => ({
lineHeight: 1.2,
letterSpacing: 1.2,
fontSize: 12,
cursorBlink: 'enable',
cursorStyle: 'underline',
scrollback: 1000,
scrollSensitivity: 10,
}),
actions: {
setLineHeight(lineHeight: number) {
this.lineHeight = lineHeight;
},
setLetterSpacing(letterSpacing: number) {
this.letterSpacing = letterSpacing;
},
setFontSize(fontSize: number) {
this.fontSize = fontSize;
},
setCursorBlink(cursorBlink: string) {
this.cursorBlink = cursorBlink;
},
setCursorStyle(cursorStyle: string) {
this.cursorStyle = cursorStyle;
},
setScrollback(scrollback: number) {
this.scrollback = scrollback;
},
setScrollSensitivity(scrollSensitivity: number) {
this.scrollSensitivity = scrollSensitivity;
},
},
persist: piniaPersistConfig('TerminalState'),
});
export default TerminalStore;

View File

@ -96,7 +96,7 @@
<script setup lang="ts">
import { dateFormat } from '@/utils/util';
import { onMounted, ref } from 'vue';
import { searchBackup, deleteBackup, refreshOneDrive } from '@/api/modules/setting';
import { searchBackup, deleteBackup, refreshOneDrive } from '@/api/modules/backup';
import Operate from '@/views/setting/backup-account/operate/index.vue';
import { Backup } from '@/api/interface/backup';
import i18n from '@/lang';

View File

@ -291,7 +291,7 @@ import { Rules } from '@/global/form-rules';
import i18n from '@/lang';
import { ElForm } from 'element-plus';
import { Backup } from '@/api/interface/backup';
import { addBackup, editBackup, getOneDriveInfo, listBucket } from '@/api/modules/setting';
import { addBackup, editBackup, getOneDriveInfo, listBucket } from '@/api/modules/backup';
import { cities } from './../helper';
import { deepCopy, spliceHttp, splitHttp } from '@/utils/util';
import { MsgSuccess } from '@/utils/message';

View File

@ -11,6 +11,9 @@
<el-radio-button class="router_card_button" size="large" value="command">
{{ $t('terminal.quickCommand') }}
</el-radio-button>
<el-radio-button class="router_card_button" size="large" value="setting">
{{ $t('container.setting') }}
</el-radio-button>
</el-radio-group>
</el-card>
@ -23,6 +26,9 @@
<div v-if="activeNames === 'command'">
<CommandTab ref="commandTabRef" />
</div>
<div v-if="activeNames === 'setting'">
<SettingTab ref="settingTabRef" />
</div>
</div>
</template>
@ -30,12 +36,17 @@
import HostTab from '@/views/terminal/host/index.vue';
import CommandTab from '@/views/terminal/command/index.vue';
import TerminalTab from '@/views/terminal/terminal/index.vue';
import SettingTab from '@/views/terminal/setting/index.vue';
import { onMounted, onUnmounted, ref } from 'vue';
import { getTerminalInfo } from '@/api/modules/setting';
import { TerminalStore } from '@/store';
const terminalStore = TerminalStore();
const activeNames = ref<string>('terminal');
const hostTabRef = ref();
const commandTabRef = ref();
const terminalTabRef = ref();
const settingTabRef = ref();
const handleChange = (tab: any) => {
if (tab === 'host') {
@ -47,9 +58,25 @@ const handleChange = (tab: any) => {
if (tab === 'terminal') {
terminalTabRef.value!.acceptParams();
}
if (tab === 'setting') {
settingTabRef.value!.acceptParams();
}
};
const loadTerminalSetting = async () => {
await getTerminalInfo().then((res) => {
terminalStore.setLineHeight(Number(res.data.lineHeight));
terminalStore.setLetterSpacing(Number(res.data.letterSpacing));
terminalStore.setFontSize(Number(res.data.fontSize));
terminalStore.setCursorBlink(res.data.cursorBlink);
terminalStore.setCursorStyle(res.data.cursorStyle);
terminalStore.setScrollback(Number(res.data.scrollback));
terminalStore.setScrollSensitivity(Number(res.data.scrollSensitivity));
});
};
onMounted(() => {
loadTerminalSetting();
handleChange('terminal');
});
onUnmounted(() => {

View File

@ -0,0 +1,241 @@
<template>
<div v-loading="loading">
<LayoutContent :title="$t('container.setting')" :divider="true">
<template #main>
<el-form :model="form" label-position="left" label-width="150px">
<el-row>
<el-col :span="1"><br /></el-col>
<el-col :xs="24" :sm="20" :md="15" :lg="12" :xl="12">
<el-form-item :label="$t('terminal.lineHeight')">
<el-input-number
class="formInput"
:min="1"
:max="2.0"
:precision="1"
:step="0.1"
v-model="form.lineHeight"
@change="changeItem()"
/>
</el-form-item>
<el-form-item :label="$t('terminal.letterSpacing')">
<el-input-number
class="formInput"
:min="0"
:max="3.5"
:precision="1"
:step="0.5"
v-model="form.letterSpacing"
@change="changeItem()"
/>
</el-form-item>
<el-form-item :label="$t('terminal.fontSize')">
<el-input-number
class="formInput"
:step="1"
:min="12"
:max="20"
v-model="form.fontSize"
@change="changeItem()"
/>
</el-form-item>
<el-form-item>
<div class="terminal" ref="terminalElement"></div>
</el-form-item>
<el-form-item :label="$t('terminal.cursorBlink')">
<el-switch
v-model="form.cursorBlink"
active-value="enable"
inactive-value="disable"
@change="changeItem()"
/>
</el-form-item>
<el-form-item :label="$t('terminal.cursorStyle')">
<el-select class="formInput" v-model="form.cursorStyle" @change="changeItem()">
<el-option value="block" :label="$t('terminal.cursorBlock')" />
<el-option value="underline" :label="$t('terminal.cursorUnderline')" />
<el-option value="bar" :label="$t('terminal.cursorBar')" />
</el-select>
</el-form-item>
<el-form-item :label="$t('terminal.scrollback')">
<el-input-number
class="formInput"
:step="50"
:min="0"
:max="10000"
v-model="form.scrollback"
@change="changeItem()"
/>
</el-form-item>
<el-form-item :label="$t('terminal.scrollSensitivity')">
<el-input-number
class="formInput"
:step="1"
:min="0"
:max="16"
v-model="form.scrollSensitivity"
@change="changeItem()"
/>
</el-form-item>
<el-form-item>
<el-button @click="onSetDefault()" plain>
{{ $t('commons.button.setDefault') }}
</el-button>
<el-button @click="search(true)" plain>{{ $t('commons.button.reset') }}</el-button>
<el-button @click="onSave" type="primary">{{ $t('commons.button.save') }}</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
</LayoutContent>
</div>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue';
import { ElForm } from 'element-plus';
import { getTerminalInfo, UpdateTerminalInfo } from '@/api/modules/setting';
import { Terminal } from '@xterm/xterm';
import '@xterm/xterm/css/xterm.css';
import { FitAddon } from '@xterm/addon-fit';
import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message';
import { TerminalStore } from '@/store';
const loading = ref(false);
const terminalStore = TerminalStore();
const terminalElement = ref<HTMLDivElement | null>(null);
const fitAddon = new FitAddon();
const term = ref();
const form = reactive({
lineHeight: 1.2,
letterSpacing: 1.2,
fontSize: 12,
cursorBlink: 'enable',
cursorStyle: 'underline',
scrollback: 1000,
scrollSensitivity: 10,
});
const acceptParams = () => {
search();
iniTerm();
};
const search = async (withReset?: boolean) => {
loading.value = true;
await getTerminalInfo()
.then((res) => {
loading.value = false;
form.lineHeight = Number(res.data.lineHeight);
form.letterSpacing = Number(res.data.letterSpacing);
form.fontSize = Number(res.data.fontSize);
form.cursorBlink = res.data.cursorBlink;
form.cursorStyle = res.data.cursorStyle;
form.scrollback = Number(res.data.scrollback);
form.scrollSensitivity = Number(res.data.scrollSensitivity);
if (withReset) {
changeItem();
}
})
.catch(() => {
loading.value = false;
});
};
const iniTerm = () => {
term.value = new Terminal({
lineHeight: 1.2,
fontSize: 12,
fontFamily: "Monaco, Menlo, Consolas, 'Courier New', monospace",
theme: {
background: '#000000',
},
cursorBlink: true,
cursorStyle: 'block',
scrollback: 1000,
scrollSensitivity: 15,
});
term.value.open(terminalElement.value);
term.value.loadAddon(fitAddon);
term.value.write('the first line \r\nthe second line');
fitAddon.fit();
};
const changeItem = () => {
term.value.options.lineHeight = form.lineHeight;
term.value.options.letterSpacing = form.letterSpacing;
term.value.options.fontSize = form.fontSize;
term.value.options.cursorBlink = form.cursorBlink === 'enable';
term.value.options.cursorStyle = form.cursorStyle;
term.value.options.scrollback = form.scrollback;
term.value.options.scrollSensitivity = form.scrollSensitivity;
fitAddon.fit();
};
const onSetDefault = () => {
form.lineHeight = 1.2;
form.letterSpacing = 0;
form.fontSize = 12;
form.cursorBlink = 'enable';
form.cursorStyle = 'block';
form.scrollback = 1000;
form.scrollSensitivity = 6;
changeItem();
};
const onSave = () => {
ElMessageBox.confirm(i18n.global.t('terminal.saveHelper'), i18n.global.t('container.setting'), {
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),
type: 'info',
}).then(async () => {
loading.value = true;
let param = {
lineHeight: form.lineHeight + '',
letterSpacing: form.letterSpacing + '',
fontSize: form.fontSize + '',
cursorBlink: form.cursorBlink,
cursorStyle: form.cursorStyle,
scrollback: form.scrollback + '',
scrollSensitivity: form.scrollSensitivity + '',
};
await UpdateTerminalInfo(param)
.then(() => {
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
loading.value = false;
terminalStore.setLineHeight(form.lineHeight);
terminalStore.setLetterSpacing(form.letterSpacing);
terminalStore.setFontSize(form.fontSize);
terminalStore.setCursorBlink(form.cursorBlink);
terminalStore.setCursorStyle(form.cursorStyle);
terminalStore.setScrollback(form.scrollback);
terminalStore.setScrollSensitivity(form.scrollSensitivity);
})
.catch(() => {
loading.value = false;
});
});
};
defineExpose({
acceptParams,
});
</script>
<style lang="css" scoped>
.formInput {
width: 100%;
}
.terminal {
width: 100%;
height: 100px;
}
</style>