243 行
5.6 KiB
Vue
243 行
5.6 KiB
Vue
<template>
|
|
<div>
|
|
<span class="regText">
|
|
<span class="regBold">
|
|
{{ l.username }}@{{ l.hostname }}:<span class="pathText">{{ l.path }}</span>
|
|
</span>$
|
|
<span id="box">▮</span>
|
|
<span v-for="(l, i) in line" :key="`l-${i}`">
|
|
<span v-if="l.active">
|
|
<input
|
|
:key="i"
|
|
autofocus
|
|
spellcheck="false"
|
|
type="text"
|
|
class="inputField"
|
|
v-model="l.command"
|
|
@keyup.enter="exec(l.command, i)"
|
|
/>
|
|
</span>
|
|
<span v-else>
|
|
<input
|
|
:key="i"
|
|
disabled
|
|
spellcheck="false"
|
|
type="text"
|
|
class="inputField"
|
|
v-model="l.command"
|
|
@keyup.enter="exec(l.command, i)"
|
|
/>
|
|
</span>
|
|
<br />
|
|
</span>
|
|
<span v-for="(res, d) in result" :key="`res-${d}`">
|
|
<br />
|
|
{{ res.text }}
|
|
<span v-if="res.field">
|
|
<span v-if="res.password">
|
|
<span v-if="res.active">
|
|
<input
|
|
:key="d"
|
|
password="password"
|
|
autofocus
|
|
spellcheck="false"
|
|
type="text"
|
|
class="inputField"
|
|
v-model="res.command"
|
|
@keyup.enter="execContinue(res.command, d)"
|
|
/>
|
|
</span>
|
|
<span v-else>
|
|
<input
|
|
:key="d"
|
|
password="password"
|
|
disabled
|
|
spellcheck="false"
|
|
type="text"
|
|
class="inputField"
|
|
v-model="res.command"
|
|
@keyup.enter="execContinue(res.command, d)"
|
|
/>
|
|
</span>
|
|
</span>
|
|
<span v-else>
|
|
<span v-if="res.active">
|
|
<input
|
|
:key="d"
|
|
spellcheck="false"
|
|
autofocus
|
|
type="text"
|
|
class="inputField"
|
|
v-model="res.command"
|
|
@keyup.enter="execContinue(res.command, d)"
|
|
/>
|
|
</span>
|
|
<span v-else>
|
|
<input
|
|
:key="d"
|
|
disabled
|
|
spellcheck="false"
|
|
type="text"
|
|
class="inputField"
|
|
v-model="res.command"
|
|
@keyup.enter="execContinue(res.command, d)"
|
|
/>
|
|
</span>
|
|
</span>
|
|
<br />
|
|
</span>
|
|
</span>
|
|
</span>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
data: function () {
|
|
return {
|
|
user: 'user',
|
|
host: '076server',
|
|
pwd: '/',
|
|
line: [{
|
|
active: true,
|
|
username: this.user,
|
|
hostname: this.host,
|
|
path: this.pwd,
|
|
command: ''
|
|
}],
|
|
result: [],
|
|
group: []
|
|
}
|
|
},
|
|
created: function () {
|
|
this.line = [];
|
|
this.line.push({
|
|
active: true,
|
|
username: this.user,
|
|
hostname: this.host,
|
|
path: this.pwd,
|
|
command: ''
|
|
});
|
|
},
|
|
methods: {
|
|
exec(text, key) {
|
|
var arg = text.split(' ');
|
|
|
|
this.line[key].active = false;
|
|
if (arg[0] === 'sudo') this.isSudo();
|
|
else this.execContinue(text, key);
|
|
},
|
|
isSudo() {
|
|
this.result.push({
|
|
active: true,
|
|
text: 'パスワード: ',
|
|
field: true,
|
|
password: true,
|
|
command: ''
|
|
});
|
|
},
|
|
execContinue(text, key) {
|
|
var arg = text.split(' ');
|
|
|
|
if (arg[0] === 'ls') this.ls(this.line[key].path);
|
|
else if (arg[0] === 'cd') this.cd(arg[1]);
|
|
else if (arg[0] === 'clear') this.clear();
|
|
else this.result.push({
|
|
active: true,
|
|
text: arg[0] + ': コマンドは見つかれません。',
|
|
field: false,
|
|
password: false,
|
|
command: ''
|
|
});
|
|
|
|
this.line.push({
|
|
active: true,
|
|
username: this.user,
|
|
hostname: this.host,
|
|
path: this.pwd,
|
|
command: ''
|
|
});
|
|
|
|
this.group.push([
|
|
this.line,
|
|
this.result
|
|
]);
|
|
},
|
|
ls(pwd) {
|
|
var neopwd = pwd.replace('/', 'sl');
|
|
axios.get('/api/rpc/bash/ls/' + neopwd).then(res => {
|
|
this.result.push({
|
|
active: true,
|
|
text: res.data,
|
|
field: false,
|
|
password: false,
|
|
command: ''
|
|
})
|
|
})
|
|
},
|
|
cd(pwd) {
|
|
if (pwd === '/fuck' || pwd === 'fuck') {
|
|
this.result.push({
|
|
active: true,
|
|
text: 'bash: cd: ' + pwd + ': このファイルまたはフォルダがありません。',
|
|
field: false,
|
|
password: false,
|
|
command: ''
|
|
});
|
|
return false;
|
|
}
|
|
if (!pwd.startsWith('/')) pwd = '/' + pwd;
|
|
|
|
this.pwd = pwd;
|
|
},
|
|
clear() {
|
|
this.line = [];
|
|
this.result = [];
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
@keyframes blink {
|
|
0% { opacity: 0; }
|
|
50% { opacity: 1; }
|
|
100% { opacity: 0; }
|
|
}
|
|
#box {
|
|
animation: blink 1s infinite;
|
|
}
|
|
.inputField {
|
|
background-color: #000000;
|
|
color: #73D216;
|
|
border-width: 0px;
|
|
font-family: monospace;
|
|
font-size: large;
|
|
width: 500px;
|
|
outline: none;
|
|
}
|
|
.regBold {
|
|
font-weight: bold;
|
|
}
|
|
.regText {
|
|
color: #73D216;
|
|
}
|
|
.pathText {
|
|
color: #5454FF;
|
|
}
|
|
h1, h2 {
|
|
font-weight: normal;
|
|
}
|
|
ul {
|
|
list-style-type: none;
|
|
padding: 0;
|
|
}
|
|
li {
|
|
display: inline-block;
|
|
margin: 0 10px;
|
|
}
|
|
a {
|
|
color: #42b983;
|
|
}
|
|
</style>
|