mirror of
https://github.com/acepanel/panel.git
synced 2026-02-07 10:37:14 +08:00
166 lines
4.2 KiB
Vue
166 lines
4.2 KiB
Vue
<script setup lang="ts">
|
||
import { FitAddon } from '@xterm/addon-fit'
|
||
import { Terminal } from '@xterm/xterm'
|
||
import '@xterm/xterm/css/xterm.css'
|
||
import CryptoJS from 'crypto-js'
|
||
import { useI18n } from 'vue-i18n'
|
||
|
||
import ssh from '@/api/panel/ssh'
|
||
|
||
const { t } = useI18n()
|
||
|
||
const msgData = '1'
|
||
const msgResize = '2'
|
||
|
||
const model = ref({
|
||
host: '',
|
||
port: 22,
|
||
user: '',
|
||
password: ''
|
||
})
|
||
|
||
const handleSave = () => {
|
||
ssh
|
||
.saveInfo(model.value.host, model.value.port, model.value.user, model.value.password)
|
||
.then(() => {
|
||
window.$message.success(t('sshIndex.alerts.save'))
|
||
})
|
||
}
|
||
|
||
const getInfo = () => {
|
||
ssh.info().then((res) => {
|
||
model.value.host = res.data.host
|
||
model.value.port = res.data.port
|
||
model.value.user = res.data.user
|
||
model.value.password = res.data.password
|
||
})
|
||
}
|
||
|
||
const openSession = () => {
|
||
const term = new Terminal({
|
||
fontSize: 15,
|
||
cursorBlink: true, // 光标闪烁
|
||
theme: {
|
||
foreground: '#ECECEC', // 字体
|
||
background: '#000000', //背景色
|
||
cursor: 'help' // 设置光标
|
||
}
|
||
})
|
||
|
||
const fitAddon = new FitAddon()
|
||
term.loadAddon(fitAddon)
|
||
|
||
const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws'
|
||
const ws = new WebSocket(`${protocol}://${window.location.host}/api/panel/ssh/session`)
|
||
ws.binaryType = 'arraybuffer'
|
||
|
||
const enc = new TextDecoder('utf-8')
|
||
ws.onmessage = (event) => {
|
||
term.write(enc.decode(event.data))
|
||
}
|
||
|
||
ws.onopen = () => {
|
||
term.open(document.getElementById('terminal') as HTMLElement)
|
||
fitAddon.fit()
|
||
term.write('\r\n欢迎来到耗子面板SSH,连接成功。')
|
||
term.write('\r\nWelcome to HaoZiPanel SSH. Connection success.\r\n')
|
||
term.focus()
|
||
}
|
||
|
||
ws.onclose = () => {
|
||
term.write('\r\nSSH连接已关闭,请刷新页面。')
|
||
term.write('\r\nSSH connection closed. Please refresh the page.\r\n')
|
||
}
|
||
|
||
ws.onerror = (event) => {
|
||
term.write('\r\nSSH连接发生错误,请刷新页面。')
|
||
term.write('\r\nSSH connection error. Please refresh the page.\r\n')
|
||
console.error(event)
|
||
ws.close()
|
||
}
|
||
|
||
term.onData((data) => {
|
||
ws.send(msgData + CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(data)))
|
||
})
|
||
|
||
term.onResize(({ cols, rows }) => {
|
||
if (ws.readyState === 1) {
|
||
ws.send(
|
||
msgResize +
|
||
CryptoJS.enc.Base64.stringify(
|
||
CryptoJS.enc.Utf8.parse(
|
||
JSON.stringify({
|
||
columns: cols,
|
||
rows: rows
|
||
})
|
||
)
|
||
)
|
||
)
|
||
}
|
||
})
|
||
|
||
window.addEventListener(
|
||
'resize',
|
||
() => {
|
||
fitAddon.fit()
|
||
},
|
||
false
|
||
)
|
||
}
|
||
|
||
onMounted(() => {
|
||
getInfo()
|
||
openSession()
|
||
})
|
||
</script>
|
||
|
||
<template>
|
||
<common-page show-footer>
|
||
<n-space vertical>
|
||
<n-form inline>
|
||
<n-form-item :label="$t('sshIndex.save.fields.host.label')">
|
||
<n-input
|
||
v-model:value="model.host"
|
||
:placeholder="$t('sshIndex.save.fields.host.placeholder')"
|
||
clearable
|
||
size="small"
|
||
/>
|
||
</n-form-item>
|
||
<n-form-item :label="$t('sshIndex.save.fields.port.label')">
|
||
<n-input-number
|
||
v-model:value="model.port"
|
||
:placeholder="$t('sshIndex.save.fields.port.placeholder')"
|
||
clearable
|
||
size="small"
|
||
/>
|
||
</n-form-item>
|
||
<n-form-item :label="$t('sshIndex.save.fields.username.label')">
|
||
<n-input
|
||
v-model:value="model.user"
|
||
:placeholder="$t('sshIndex.save.fields.username.placeholder')"
|
||
clearable
|
||
size="small"
|
||
/>
|
||
</n-form-item>
|
||
<n-form-item :label="$t('sshIndex.save.fields.password.label')">
|
||
<n-input
|
||
v-model:value="model.password"
|
||
:placeholder="$t('sshIndex.save.fields.password.placeholder')"
|
||
clearable
|
||
size="small"
|
||
/>
|
||
</n-form-item>
|
||
<n-form-item>
|
||
<n-button type="primary" size="small" @click="handleSave">
|
||
{{ $t('sshIndex.save.actions.submit') }}
|
||
</n-button>
|
||
</n-form-item>
|
||
</n-form>
|
||
<div
|
||
id="terminal"
|
||
style="width: 100%; height: 70vh; background-color: #000000; margin-top: 20px"
|
||
></div>
|
||
</n-space>
|
||
</common-page>
|
||
</template>
|