NEZ-2495 feat:terminal支持查看历史记录页面开发
This commit is contained in:
@@ -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
@@ -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": "定位",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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')
|
||||
},
|
||||
|
||||
@@ -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')
|
||||
},
|
||||
|
||||
@@ -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')
|
||||
// 获取可选语言
|
||||
|
||||
Reference in New Issue
Block a user