NEZ-2495 feat:terminal支持查看历史记录页面开发

This commit is contained in:
zyh
2023-01-05 17:32:53 +08:00
parent 1a68e4ef52
commit bbb04a0777
14 changed files with 221 additions and 47 deletions

View File

@@ -135,14 +135,103 @@
font-size: 6px;
}
.shell-input{
position: relative;
input {
background: #1E1E1E !important;
border: none;
color: white;
padding-right: 53px;
}
input::input-placeholder{
color: #7C7C7C;
}
.el-input__suffix{
right: 20px;
.el-input__suffix-inner{
height: 100%;
display: flex;
align-items: center;
font-size: 18px;
}
i{
color: $--color-text-regular;
cursor: pointer;
}
i.active{
color: $--color-primary;
}
}
}
.web-terminal-history{
position: absolute;
bottom: 32px;
z-index: 9;
width: 100%;
background: #1E1E1E;
border-bottom: 1px solid rgba(0,0,0,0.50);
.terminal-history-header{
box-sizing: border-box;
padding: 0 20px;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
color: #B7B7B7;
height: 36px;
border-bottom: 1px solid #2F2F2F;
i{
font-size: 14px;
cursor: pointer;
}
}
.terminal-history-list-wrap{
padding: 10px 0;
box-sizing: border-box;
.terminal-history-list{
max-height: 160px;
overflow-y: auto;
line-height:normal;
&::-webkit-scrollbar-thumb{
background-color:#404040;
border:2px solid #222329;
}
.terminal-history-item{
padding: 0px 20px;
height: 20px;
box-sizing: border-box;
display: flex;
align-items: center;
cursor: pointer;
&:hover{
background: #18171D;
}
.terminal-history-num{
width: 28px;
font-size: 14px;
color: #B7B7B7;
font-weight: 400;
flex-shrink: 0;
margin-right: 8px;
}
.terminal-history-text{
font-size: 14px;
color: #FFFFFF;
font-weight: 400;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-break: break-all;
}
}
}
}
.terminal-history-empty{
line-height: 50px;
color: #B7B7B7;
font-size: 14px;
text-align: center;
}
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -5,6 +5,20 @@
"css_prefix_text": "nz-icon-",
"description": "",
"glyphs": [
{
"icon_id": "16639137",
"name": "history",
"font_class": "history",
"unicode": "e663",
"unicode_decimal": 58979
},
{
"icon_id": "33610702",
"name": "关闭2",
"font_class": "guanbi2",
"unicode": "e7be",
"unicode_decimal": 59326
},
{
"icon_id": "32096202",
"name": "定位",

File diff suppressed because one or more lines are too long

View File

@@ -133,9 +133,11 @@ export default {
this.host = res.data.host
this.create()
} else {
this.terminal.uuid = res.data.uuid
this.terminal.userName = res.data.authUsername + '@' + res.data.host
this.host = res.data.host
if (res.data) {
this.terminal.uuid = res.data.uuid
this.terminal.userName = res.data.authUsername + '@' + res.data.host
this.host = res.data.host
}
params.name = this.terminal.name
this.$emit('loginFail', params)
this.$message.error(res.msg)
@@ -311,7 +313,12 @@ export default {
this.terminalSocket.send(message)
this.terminalSocket.send('\n')
this.term.scrollToBottom()
this.historyChange(message)
}
},
// 新增历史记录
historyChange (message) {
this.$emit('historyChange', message)
}
},
mounted () {
@@ -324,6 +331,3 @@ export default {
}
}
</script>
<style scoped lang="scss">
</style>

View File

@@ -11,7 +11,29 @@
</div>
<fileListState v-clickoutside="hideFileState" ref="fileListState"/>
<webSSHNew ref="websshNew" />
<el-input :placeholder="placeholder" size="small" class="shell-input" v-model="message" @keyup.enter.native="sendMessage" @focus="placeholderChange('focus')" @blur="placeholderChange('blur')"/>
<div class="shell-input">
<el-input ref="shellInput" :placeholder="placeholder" size="small" v-model="message" @keyup.enter.native="sendMessage" @focus="placeholderChange('focus')" @blur="placeholderChange('blur')">
<i slot="suffix" class="nz-icon nz-icon-history" :class="{'active':visible}" :title="$t('terminal.history')" @click="toggleHistory"></i>
</el-input>
<transition name="el-zoom-in-bottom">
<div class="web-terminal-history" v-show="visible">
<div class="terminal-history-header">
<span>{{$t('terminal.history')}}</span>
<i class="nz-icon nz-icon-close" @click="visible=false"></i>
</div>
<div class="terminal-history-list-wrap" v-if="historyArr.length">
<!-- 历史命令记录 -->
<ul class="terminal-history-list">
<li class="terminal-history-item" v-for="(item,index) in historyArr" :key="index" @click="historyClick(item)">
<span class="terminal-history-num">{{index+1}}</span>
<span class="terminal-history-text">{{item}}</span>
</li>
</ul>
</div>
<div v-else class="terminal-history-empty">{{$t('terminal.noHistoricalRecord')}}</div>
</div>
</transition>
</div>
</div>
</template>
@@ -19,6 +41,7 @@
import webSSHNew from '@/components/cli/webSSHNew'
import fileListState from './fileListState'
import imageUrl from '@/assets/img/logo1-2.png'
import bus from '@/libs/bus'
export default {
name: 'terminal',
components: {
@@ -32,7 +55,10 @@ export default {
fileListStateType: '',
message: '',
name: '',
placeholder: this.$t('terminal.placeholder')
placeholder: this.$t('terminal.placeholder'),
visible: false,
// 历史命令记录
historyArr: []
}
},
computed: {
@@ -49,6 +75,7 @@ export default {
}
})
this.logo = localStorage.getItem('nz-sys-logo')
this.getHistory()
},
mounted () {
const self = this
@@ -70,7 +97,7 @@ export default {
self.$refs.websshNew.addConsole(asset.id, asset.manageIp, '', '', 'asset')
})
} catch (e) {
console.log(e)
// console.log(e)
}
}
})
@@ -87,7 +114,7 @@ export default {
placeholderChange (type) {
if (type == 'focus') {
this.placeholder = ''
}else {
} else {
this.placeholder = this.$t('terminal.placeholder')
}
},
@@ -96,14 +123,33 @@ export default {
setTimeout(() => {
this.message = ''
})
}
},
beforeDestroy () {
},
// 获取历史输入命令
getHistory () {
const length = localStorage.getItem('nz-history-size') || 100
const historyArr = JSON.parse(localStorage.getItem('nz-history-terminal') || '[]')
historyArr.splice(length)
this.historyArr = historyArr
},
// 切换历史记录显示隐藏
toggleHistory () {
this.visible = !this.visible
},
// 点击历史记录
historyClick (value) {
this.visible = false
this.message = value
this.$nextTick(() => {
this.$refs.shellInput.focus()
})
},
// 新增历史记录
historyChange: bus.debounce(function (message) {
const historyArr = JSON.parse(localStorage.getItem('nz-history-terminal') || '[]')
historyArr.unshift(message)
localStorage.setItem('nz-history-terminal', JSON.stringify(historyArr))
this.getHistory()
}, 100)
}
}
</script>
<style scoped lang="scss">
</style>

View File

@@ -1,15 +1,18 @@
<template>
<div class="ani-webSHH-height web-terminal-new" id="web-terminal-new">
<el-tabs :before-leave="beforeLeave"
@tab-click="handleClick"
@tab-remove="removeTab"
type="border-card"
v-model="editableTabsValue" >
<el-tab-pane :key="item.name"
:label="item.title"
:name="item.name"
closable
v-for="(item, index) in editableTabs"
<el-tabs
:before-leave="beforeLeave"
@tab-click="handleClick"
@tab-remove="removeTab"
type="border-card"
v-model="editableTabsValue"
>
<el-tab-pane
:key="item.name"
:label="item.title"
:name="item.name"
closable
v-for="(item, index) in editableTabs"
>
<!-- tab显示的内容 1 grey,2 green, 3 red-->
<span slot="label" class="el-tabs__item-label">
@@ -64,6 +67,7 @@
@loginFail="loginFail"
@closeConsole="removeTab"
@refreshConsoleTitle="refreshTabTitle"
@historyChange="(message)=>{$parent.historyChange(message)}"
></terminal>
</el-tab-pane>
@@ -77,13 +81,13 @@
>
<div>
<div class="popover-webshell-item" @click="assetShowChange"><i class="nz-icon nz-icon-menu-assets" />{{$t('webshell.selAsset')}}</div>
<div class="popover-webshell-item" @click="customShow=true"><i class="nz-icon nz-icon-edit" />{{$t('webshell.custom')}}</div>
<div class="popover-webshell-item" @click="customShow=true"><i class="nz-icon nz-icon-edit" />{{$t('webshell.custom')}}</div>
</div>
<span slot="reference" style="padding:8px;font-size:20px;font-weight:bold;">+</span>
</el-popover>
</el-tab-pane>
</el-tabs>
<!--弹窗-->
<!--弹窗-->
<el-dialog :modal-append-to-body='false' :show-close="true" :visible.sync="assetShow" @close="closeAssetCustom" class="nz-dialog" width="620px">
<div slot="title">{{$t('webshell.connect')}}</div>
<div >
@@ -121,7 +125,7 @@
</el-form>
</div>
</el-dialog>
<el-dialog :modal-append-to-body='false' :show-close="true" :visible.sync="customShow" @close="closeAssetCustom" class="nz-dialog" width="620px"destroy-on-close >
<el-dialog :modal-append-to-body='false' :show-close="true" :visible.sync="customShow" @close="closeAssetCustom" class="nz-dialog" width="620px" destroy-on-close>
<div slot="title">{{$t('webshell.connect')}}</div>
<div >
<el-form label-width="120px" size="small" :model="customConnect" label-position = "top" :rules=" customConnect.authProtocol ===2 ? rulesCustom2: rulesCustom" ref="customConnect" v-my-loading="assetLoading" class="custom">
@@ -151,10 +155,10 @@
>
<el-input v-model="customConnect.authPriKey" size="small" autocomplete="new-password"/>
</el-form-item>
<el-form-item :label='$t("login.pin")' prop="authPin"
:rules="[
{ required: customConnect.authType ===1, message:$t('validate.required'), trigger: 'change'},
]">
<el-form-item
:label='$t("login.pin")' prop="authPin"
:rules="[{ required: customConnect.authType ===1, message:$t('validate.required'), trigger: 'change'},]"
>
<el-input v-model="customConnect.authPin" size="small" type="password" autocomplete="new-password"/>
</el-form-item>
<el-form-item

View File

@@ -227,12 +227,12 @@ export default {
})
},
methods: {
// 使用防抖是因为,防止标签输入框失去焦点校验和开始任务校验重复(连续两次message提示)
// 防止标签输入框失去焦点校验和开始任务校验重复(连续两次message提示)
validateHost: bus.debounce(function () {
this.$message.error(this.$t('validate.host'))
},
50),
// 使用防抖是因为,防止标签输入框失去焦点校验和开始任务校验重复(连续两次message提示)
// 防止标签输入框失去焦点校验和开始任务校验重复(连续两次message提示)
validateDuplicate: bus.debounce(function () {
this.$message.error(this.$t('ping.duplicate') + ' IP')
},

View File

@@ -218,12 +218,12 @@ export default {
})
},
methods: {
// 使用防抖是因为,防止标签输入框失去焦点校验和开始任务校验重复(连续两次message提示)
// 防止标签输入框失去焦点校验和开始任务校验重复(连续两次message提示)
validateHost: bus.debounce(function () {
this.$message.error(this.$t('validate.host'))
},
50),
// 使用防抖是因为,防止标签输入框失去焦点校验和开始任务校验重复(连续两次message提示)
// 防止标签输入框失去焦点校验和开始任务校验重复(连续两次message提示)
validateDuplicate: bus.debounce(function () {
this.$message.error(this.$t('ping.duplicate') + ' IP')
},

View File

@@ -93,13 +93,14 @@ const user = {
localStorage.setItem(`nz-user-${res.data.user.id}-theme`, currentTheme)
const body = document.getElementsByTagName('body')[0]
body.setAttribute('class', `theme-${currentTheme}`)
console.log(res)
localStorage.setItem('timezoneOffset', moment.tz(res.data.timezone || defaultAppearance.timezone).format('Z'))
localStorage.setItem('nz-sys-default-cabinet-usize', res.data.defaultCabinetUsize)
localStorage.setItem('nz-sys-max-terminal-num', res.data.maxTerminalNum)
localStorage.setItem('nz-sys-asset-ping-switch', res.data.assetPingSwitch)
localStorage.setItem('nz-unnsaved-change', res.data.unsavedChange)
localStorage.setItem('nz-mfa-enable', Number(res.data.mfaAuthEnable) ? 1 : 0)
localStorage.setItem('nz-history-size', res.data.history_size ? res.data.history_size : 100)
store.commit('setLanguage', res.data.user.lang || defaultAppearance.language)
store.commit('setTimeFormatMain', localStorage.getItem('nz-default-dateFormat') || 'YYYY-MM-DD HH:mm:ss')
// 获取可选语言