NEZ-3038 feat:升级 xterm。js的版本

This commit is contained in:
zhangyu
2023-08-10 11:10:12 +08:00
parent 7a42de5cf6
commit 45def99505
10 changed files with 111 additions and 84 deletions

View File

@@ -31,6 +31,9 @@
</template>
<script>
import Terminal from '../common/js/Xterm'
import { AttachAddon } from 'xterm-addon-attach'
import { FitAddon } from 'xterm-addon-fit'
import { CanvasAddon } from 'xterm-addon-canvas'
import fileDirectory from './fileDirectory'
export default {
name: 'console',
@@ -58,6 +61,8 @@ export default {
return {
term: null,
terminalSocket: null,
termAttachAddon: null,
termFitAddon: null,
termimalRows: 15,
termimalHeight: 270,
topMenuHeight: 30,
@@ -90,8 +95,8 @@ export default {
}
},
// computed: {
// terminalSetting () {
// return this.provObj.terminalSetting
// userInfo () {
// return this.$store.getters.getUserInfo
// }
// },
watch: {
@@ -101,13 +106,16 @@ export default {
term.write('\r\n ')// term.write('\r\n~$ ');
},
resize (consoleHeigt, consoleWidth) {
this.term.fit()
this.termFitAddon.fit()
this.resizeServiceConsole()
},
resizeServiceConsole () {
const consoleBox = document.getElementById('ternimalContainer' + this.idIndex)
const width = document.body.clientWidth - 10// 可视宽度
const height = parseInt(consoleBox.offsetHeight) - 10
console.log(width, height)
console.log(this.term.cols)
console.log(this.term.rows)
const winStyle = {
width: width,
height: height,
@@ -116,7 +124,8 @@ export default {
}
this.$post('terminal/resize', winStyle).then(response => {
if (response.code === 200) {
this.term.fit()
// this.term.resize()
this.termFitAddon.fit()
} else {
this.$message.error(response.msg)
}
@@ -134,18 +143,30 @@ export default {
rows = parseInt(rows)
const terminalContainer = document.getElementById('terminal' + this.idIndex)
this.term = new Terminal({
allowTransparency: true,
allowProposedApi: true,
overviewRulerWidth: 8,
cursorStyle: 'block', // 光标样式 null | 'block' | 'underline' | 'bar'
disableStdin: false, // 是否应禁用输入
fontSize: 16,
fontSize: 18,
lineHeight: 1.2,
allowTransparency: true,
letterSpacing: 0,
background: 'transparent',
scrollback: this.terminalSetting.scrollbackLines
scrollback: this.terminalSetting.scrollbackLines,
wordSeparator: this.terminalSetting.wordSeparator
})
this.term.open(terminalContainer)
this.term.focus()
this.term.fit()
this.create()
this.termFitAddon = new FitAddon()
this.term.loadAddon(this.termFitAddon)
// const attachAddon = new AttachAddon()
// this.term.loadAddon(attachAddon)
// this.term.loadAddon(fitAddon)
setTimeout(() => {
this.term.open(terminalContainer)
this.term.loadAddon(new CanvasAddon())
this.term.focus()
this.termFitAddon.fit()
this.create()
}, 100)
},
create () {
const that = this
@@ -160,7 +181,10 @@ export default {
let url = ''
this.terminal.height = document.body.clientHeight - 100
this.terminal.width = document.body.clientWidth
this.waterMarkText = this.terminal.userName
const userInfo = localStorage.getItem('nz-userInfo') ? JSON.parse(localStorage.getItem('nz-userInfo')) : ''
if (userInfo) {
this.waterMarkText = `${userInfo.username}(${userInfo.name})`
}
if (this.terminal.type === 'asset') {
url = baseUrl + '/terminal.ws?width=' + this.terminal.width + '&height=' + this.terminal.height + '&cols=' + this.term.cols + '&rows=' + this.term.rows + '&token=' + token + '&assetId=' + this.terminal.assetId + '&accountId=' + this.terminal.accountId + '&uuid=' + this.terminal.uuid
} else if (this.terminal.type === 'custom') {
@@ -172,6 +196,7 @@ export default {
})
}
this.terminalSocket = new WebSocket(url)
this.termAttachAddon = new AttachAddon(this.terminalSocket)
// 连接成功onclose
this.terminalSocket.onopen = () => {
this.terminal.isLogin = true
@@ -179,15 +204,6 @@ export default {
this.isInit = true
this.term.focus()
}
// 登录后,你输入的内容从后台服务返回
this.term.on('data', function (data) {
/*
let code = data.charCodeAt(0);
if(code==13){
}else {
//that.term.write(data);
} */
})
// 个性化配置
this.initTerminalSetting()
// 返回
@@ -238,18 +254,14 @@ export default {
this.terminal.isLogin = false
// 报错sorry的还没来得及看信息就关闭
// this.$emit("closeConsole",this.terminal.name);//
this.term && this.term.setOption('disableStdin', true)
this.term && (this.term.options.disableStdin = true)
}
// 错误
this.terminalSocket.onerror = (e) => {
this.terminal.isLogin = false
}
// // 选中 复制
// this.term.on('selection', function () {})
this.term.attachCustomKeyEventHandler(function (ev) { })
this.term.attach(this.terminalSocket)
this.term.loadAddon(this.termAttachAddon)
this.term._initialized = true
// this.term.fit()// 自适应大小(使终端的尺寸和几何尺寸适合于终端容器的尺寸) 只是width
this.$nextTick(() => { // 解决进入全屏和退出全屏是底部隐藏
@@ -263,13 +275,13 @@ export default {
this.terminalSocket = ''
}
if (this.term) {
this.term.destroy()
this.term.dispose()
}
// 初始化console的高度
this.conFinish = false
},
setFontSize (fontSize) {
this.term && this.term.setOption('fontSize', fontSize)
this.term && (this.term.options.fontSize = fontSize)
const consoleBox = document.getElementById('ternimalContainer' + this.idIndex)
const width = document.body.clientWidth// 可视宽度
let height = parseInt(consoleBox.offsetHeight)
@@ -286,7 +298,7 @@ export default {
this.term.resize(this.term.cols, this.term.rows)
this.$post('terminal/resize', winStyle).then(response => {
if (response.code === 200) {
this.term.fit()
this.termFitAddon.fit()
} else {
this.$message.error(response.msg)
}
@@ -324,9 +336,9 @@ export default {
},
enterStr (message) {
if (this.terminalSocket && this.terminal.isLogin) {
this.term.send(message)
this.terminalSocket.send(message)
setTimeout(() => {
this.term.send('\n')
this.terminalSocket.send('\n')
}, 100)
this.term.scrollToBottom()
this.historyChange(message)
@@ -339,32 +351,29 @@ export default {
initTerminalSetting () { // 个性化配置
// 1 render
this.showWatermark = this.terminalSetting.watermark
console.log(this.terminalSetting.watermark)
this.term.on('selection', (p, a) => {
this.term.onSelectionChange((p, a) => {
if (this.terminalSetting.copyOnSelect) {
this.copySelection()
setTimeout(() => {
this.copySelection()
})
}
})
// this.term.on('click', () => {
// console.log('click')
// console.log(this.term.getSelection())
// })
// this.term.on('dbclick', () => {
// console.log('doubleclick123')
// console.log(this.term.getSelection())
// })
this.term.selectionManager._isCharWordSeparator = (charData) => {
console.log(charData)
if (charData[2] === 0) {
return false
}
return this.wordSeparator.indexOf(charData[1]) >= 0
}
// this.term.selectionManager._isCharWordSeparator = (charData) => {
// if (charData[2] === 0) {
// return false
// }
// return this.wordSeparator.indexOf(charData[1]) >= 0
// }
},
renderTerminalSetting () {
console.log('renderTerminalSetting')
this.showWatermark = this.terminalSetting.watermark
this.wordSeparator = this.terminalSetting.wordSeparator
this.term.setOption('scrollback', this.terminalSetting.scrollbackLines)
this.term.options = {
scrollback: this.terminalSetting.scrollbackLines,
wordSeparator: this.terminalSetting.wordSeparator
}
console.log(this.term)
},
copySelection () {
let str = this.term.getSelection()
@@ -374,14 +383,9 @@ export default {
if (this.terminalSetting.copyTrimEnd) {
str = str.replace(/(\s*$)/g, '')
}
this.$copyText(str)
},
dblclick () {
if (this.term) {
if (this.terminalSetting.copyOnSelect) {
this.copySelection()
}
}
this.$copyText(str).then((res) => {
console.log(res)
})
},
async contextmenu (event) {
event.preventDefault()
@@ -395,14 +399,14 @@ export default {
if (this.terminalSetting.rightClick === 'paste') {
if (!document.execCommand('paste')) {
const text = await navigator.clipboard.readText()
this.term.send(text)
this.term.write(text)
}
}
},
async paste () {
if (!document.execCommand('paste')) {
const text = await navigator.clipboard.readText()
this.term.send(text)
this.term.write(text)
}
},
tiggerMenu (flag, event) {
@@ -435,17 +439,13 @@ export default {
this.beforeCreate()
this.showWatermark = this.terminalSetting.watermark
const dom = document.getElementById('ternimalContainer' + this.idIndex)
dom.addEventListener('dblclick', this.dblclick)
dom.addEventListener('contextmenu', this.contextmenu)
dom.addEventListener('click', this.clickHide)
},
beforeDestroy () {
this.closeSocket()
this.term.off('selection')
this.term.off('data')
const dom = document.getElementById('ternimalContainer' + this.idIndex)
dom && dom.removeEventListener('dblclick', this.dblclick)
dom && dom.removeEventListener('contextmenu', this.contextmenu)
dom && dom.removeEventListener('contextmenu', this.contextmenu)
dom && dom.removeEventListener('click', this.clickHide)
}
}

View File

@@ -262,8 +262,11 @@ export default {
this.$put('/sys/user/preference', { terminal: JSON.stringify(this.newTerminalSetting) }).then(res => {
if (res.code === 200) {
this.terminalSetting = this.$lodash.cloneDeep(this.newTerminalSetting)
this.$refs.websshNew.renderTerminalSetting()
this.personalization = false
this.$nextTick(() => {
this.$refs.websshNew.renderTerminalSetting()
this.personalization = false
})
this.$message.success(this.$t('overall.success'))
} else {
this.$message.error(res.msg || res.error)
}