2
0
mirror of https://github.com/acepanel/panel.git synced 2026-02-07 10:37:14 +08:00
Files
panel/web/src/views/ssh/IndexView.vue

166 lines
4.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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>