✨ feat:更改中心连接模块样式&逻辑;【明天和后端在7环境试一下能不能收到ip和token&拿到的日志文件怎么处理】
This commit is contained in:
parent
03d7b8dcbf
commit
e722bb90a8
@ -1,13 +1,19 @@
|
|||||||
import { Button, Form, Input,FormProps } from '@zhst/meta';
|
import { Button, Form, Input,FormProps } from '@zhst/meta';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import WebTerminal from './components/WebTerminal';
|
import WebTerminal from './components/WebTerminal';
|
||||||
|
import './index.less';
|
||||||
|
|
||||||
interface TerminalProps{
|
interface TerminalProps{
|
||||||
onFinish:FormProps['onFinish']
|
onFinish:FormProps['onFinish'];
|
||||||
|
onExportLog:(filePath:string)=>void;
|
||||||
|
websocketUrl:string; // websocket地址
|
||||||
|
token:string; // 用户token信息
|
||||||
|
ip:string; // ip地址
|
||||||
|
// filePath:string; // 导出日志的文件地址
|
||||||
}
|
}
|
||||||
|
const materialName = 'zhst-material-terminal'
|
||||||
const Terminal: React.FC<TerminalProps> = (props:TerminalProps) => {
|
const Terminal: React.FC<TerminalProps> = (props:TerminalProps) => {
|
||||||
const {onFinish}=props;
|
const {onFinish,websocketUrl='',token='',ip='',onExportLog}=props;
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
const handleCenterConnect = async () => {
|
const handleCenterConnect = async () => {
|
||||||
@ -16,15 +22,8 @@ const Terminal: React.FC<TerminalProps> = (props:TerminalProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{width:'100%',height:'100%',boxSizing:'border-box',padding:'30px',overflow:"hidden"}}>
|
<div className={materialName} style={{}}>
|
||||||
<h1 style={{
|
<h1 >连接中心服务器</h1>
|
||||||
fontWeight: 'bold',
|
|
||||||
fontSize: '16px',
|
|
||||||
textAlign: 'left',
|
|
||||||
lineHeight:'24px',
|
|
||||||
marginBottom: '20px',
|
|
||||||
color: 'rgba(0, 0, 0, 0.88)'
|
|
||||||
}}>连接中心服务器</h1>
|
|
||||||
<Form form={form} requiredMark={false} layout={'inline'} >
|
<Form form={form} requiredMark={false} layout={'inline'} >
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label="输入中心服务器IP"
|
label="输入中心服务器IP"
|
||||||
@ -48,14 +47,17 @@ const Terminal: React.FC<TerminalProps> = (props:TerminalProps) => {
|
|||||||
<Input style={{ width: 320, height: 36 }} allowClear />
|
<Input style={{ width: 320, height: 36 }} allowClear />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item >
|
<Form.Item >
|
||||||
<Button type="primary" onClick={handleCenterConnect}>
|
<Button style={{ width: 100, height: 36,background:'#23ACB2' }} type="primary" onClick={handleCenterConnect}>
|
||||||
连接
|
开始连接
|
||||||
|
</Button>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item >
|
||||||
|
<Button style={{ width: 100, height: 36, }} onClick={onExportLog}>
|
||||||
|
导出日志
|
||||||
</Button>
|
</Button>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
<div style={{marginTop:30,width:'100%',height:'calc(100% - 120px)',boxSizing:'border-box',overflow:'hidden'}}>
|
<WebTerminal websocketUrl={websocketUrl} token={token} ip={ip} />
|
||||||
<WebTerminal />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
// import { getToken } from '@libs/auth';
|
// @ts-nocheck
|
||||||
import React, { Component } from 'react';
|
import React, {Component,useRef,useEffect } from 'react';
|
||||||
import { Terminal } from 'xterm';
|
import { Terminal } from 'xterm';
|
||||||
import { FitAddon } from 'xterm-addon-fit';
|
import { FitAddon } from 'xterm-addon-fit';
|
||||||
|
import WebsocketTerm from './WebsocketTerm';
|
||||||
import 'xterm/css/xterm.css';
|
import 'xterm/css/xterm.css';
|
||||||
|
|
||||||
// TODO:引入xterm 后续需要和后端在建立websocket连接再次调试
|
// TODO:引入xterm 后续需要和后端在建立websocket连接再次调试
|
||||||
@ -9,8 +10,18 @@ export default class WebTerminal extends Component {
|
|||||||
term = null;
|
term = null;
|
||||||
websocket = null;
|
websocket = null;
|
||||||
curr_line = '';
|
curr_line = '';
|
||||||
|
websocketUrl=''; // websocket服务地址
|
||||||
|
token=''; // 用户token信息
|
||||||
|
ip=''; // IP地址
|
||||||
|
constructor(props:any){
|
||||||
|
super(props);
|
||||||
|
this.websocketUrl = props.websocketUrl;
|
||||||
|
this.token=props.token;
|
||||||
|
this.ip=props.ip;
|
||||||
|
}
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
let term = this.term;
|
let term = this.term;
|
||||||
|
// term初始化
|
||||||
this.term = new Terminal({
|
this.term = new Terminal({
|
||||||
fontFamily: 'Menlo, Monaco, "Courier New", monospace',
|
fontFamily: 'Menlo, Monaco, "Courier New", monospace',
|
||||||
fontWeight: 400,
|
fontWeight: 400,
|
||||||
@ -20,24 +31,36 @@ export default class WebTerminal extends Component {
|
|||||||
150) /
|
150) /
|
||||||
14,
|
14,
|
||||||
),
|
),
|
||||||
|
convertEol: true,//控制终端是否自动将 \n 转换为 \r\n。
|
||||||
|
cursorBlink: true,//指定光标是否闪烁
|
||||||
|
scrollback: 50, //终端中的回滚量
|
||||||
|
disableStdin: false, //是否应禁用输入。
|
||||||
|
cursorStyle: "underline", //光标样式
|
||||||
|
windowsMode: true, // 根据窗口换行
|
||||||
|
theme: {
|
||||||
|
foreground: "#ffffff", //字体
|
||||||
|
background: "#1a1a1d", //背景色
|
||||||
|
cursor: "help", //设置光标
|
||||||
|
}
|
||||||
});
|
});
|
||||||
this.term.open(document.getElementById('terminal'));
|
this.term.open(document.getElementById('terminal'));
|
||||||
this.term.focus();
|
this.term.focus(); // 光标聚集
|
||||||
this.term.prompt = (_) => {
|
this.term.prompt = (_) => {
|
||||||
this.term.write('\r\n\x1b[33m$\x1b[0m ');
|
this.term.write('\r\n\x1b[33m$\x1b[0m ');
|
||||||
};
|
};
|
||||||
this.term.prompt();
|
// // 换行并输入起始符
|
||||||
|
// this.term.prompt = (_) => {
|
||||||
|
// this.term.write("\r\n>>> ")
|
||||||
|
// }
|
||||||
|
|
||||||
|
if(this.ip!==''){
|
||||||
|
this.term.write('root@'+this.ip);
|
||||||
|
}
|
||||||
const fitAddon = new FitAddon();
|
const fitAddon = new FitAddon();
|
||||||
this.term.loadAddon(fitAddon);
|
this.term.loadAddon(fitAddon);
|
||||||
fitAddon.fit();
|
fitAddon.fit();
|
||||||
this.term.prompt();
|
this.term.prompt();
|
||||||
// this.term.attachCustomKeyEventHandler((e) => {
|
|
||||||
// console.log({ e });
|
|
||||||
// // e = e.target;
|
|
||||||
// var keyCode = e.keyCode || e.which || e.charCode;
|
|
||||||
// const moveKey = [37, 38, 39, 40].includes(keyCode);
|
|
||||||
// if (moveKey) return false;
|
|
||||||
// });
|
|
||||||
// 添加事件监听器,支持输入方法
|
// 添加事件监听器,支持输入方法
|
||||||
this.term.onKey((e) => {
|
this.term.onKey((e) => {
|
||||||
const printable =
|
const printable =
|
||||||
@ -63,7 +86,6 @@ export default class WebTerminal extends Component {
|
|||||||
this.term.write(e.key);
|
this.term.write(e.key);
|
||||||
}
|
}
|
||||||
this.term.focus();
|
this.term.focus();
|
||||||
console.log(1, 'print', e.key);
|
|
||||||
});
|
});
|
||||||
this.term.onData((key) => {
|
this.term.onData((key) => {
|
||||||
// 粘贴的情况
|
// 粘贴的情况
|
||||||
@ -73,41 +95,69 @@ export default class WebTerminal extends Component {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.initWebsock();
|
this.initWebsock();
|
||||||
|
if(this.websocket){
|
||||||
|
// 只读属性 readyState 表示连接状态,可以是以下值
|
||||||
|
// 0 - 表示连接尚未建立。
|
||||||
|
// 1 - 表示连接已建立,可以进行通信。
|
||||||
|
// 2 - 表示连接正在进行关闭。
|
||||||
|
// 3 - 表示连接已经关闭或者连接不能打开
|
||||||
|
|
||||||
|
// websocket建立连接时发送ip以及token给后端
|
||||||
|
if(this.websocket.readyState ===1){
|
||||||
|
this.Send(this.term,{ip:this.ip,Authorization:this.token})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.term.dispose();
|
this.term.dispose();
|
||||||
|
// WebSocket 方法 关闭连接
|
||||||
this.websocket.close();
|
this.websocket.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
initWebsock = () => {
|
initWebsock = () => {
|
||||||
// let websocket = this.websocket;
|
|
||||||
let term = this.term;
|
let term = this.term;
|
||||||
let token = 'aaaa';
|
let token = this.token;
|
||||||
this.websocket = new WebSocket('ws://' + window?._CONFIG?.WsSsh!, token);
|
let ip = this.ip;
|
||||||
|
// let preSuffix=location.protocol === 'http:' ? 'ws://' : 'wss://';
|
||||||
|
let preSuffix='ws://127.0.0.1:50051/active';
|
||||||
|
// 初始化
|
||||||
|
this.websocket = new WebSocket('ws://127.0.0.1:50051/active');
|
||||||
|
// WebSocket 事件
|
||||||
|
// 连接建立时触发
|
||||||
this.websocket.onopen = function (evt) {
|
this.websocket.onopen = function (evt) {
|
||||||
term.write('connect');
|
term.write('connect');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 连接关闭时触发
|
||||||
this.websocket.onclose = function (evt) {
|
this.websocket.onclose = function (evt) {
|
||||||
term.write('exit');
|
term.write('exit');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 客户端接收服务端数据时触发
|
||||||
this.websocket.onmessage = function (evt) {
|
this.websocket.onmessage = function (evt) {
|
||||||
term.write(evt.data);
|
term.write(evt.data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 通信发生错误时触发
|
||||||
this.websocket.onerror = function (evt) {
|
this.websocket.onerror = function (evt) {
|
||||||
term.write('connect fail err:' + evt.data);
|
term.write('connect fail err:' + evt.data);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
// prompt = (term) => {
|
|
||||||
// this.term.write('\r\n~$ ');
|
|
||||||
// };
|
|
||||||
|
|
||||||
|
prompt = (term) => {
|
||||||
|
this.term.write('\r\n~$ ');
|
||||||
|
};
|
||||||
|
|
||||||
|
// WebSocket 方法 使用连接发送数据
|
||||||
Send = (term, message) => {
|
Send = (term, message) => {
|
||||||
this.websocket.send(message);
|
this.websocket.send(message);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="container-children" style={{ height: '100%' }}>
|
<div className="container-children">
|
||||||
<div id="terminal" style={{ width: '100%' }}></div>
|
<div id="terminal"></div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
import React, { useState } from 'react';
|
import React from 'react';
|
||||||
import { Terminal } from '@zhst/material';
|
import { Terminal } from '@zhst/material';
|
||||||
|
|
||||||
const demo = () => {
|
const demo = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ padding: '24px', width: '500px', border: '1px solid #eee' }}>
|
|
||||||
<Terminal
|
<Terminal
|
||||||
onFinish={val => console.log('val', val)}
|
onFinish={val => console.log('val', val)}
|
||||||
|
websocketUrl={'ws://127.0.0.1:30003'}
|
||||||
|
token={'this is user token'}
|
||||||
|
ip={'127.0.0.1'}
|
||||||
|
onExportLog={(url)=>{console.log(url,'====>url');}}
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
64
packages/material/src/terminal/index.less
Normal file
64
packages/material/src/terminal/index.less
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
.zhst-material-terminal{
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #E5EAEC;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding:30px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
h1{
|
||||||
|
font-family: SourceHanSansCN, SourceHanSansCN;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size:16px;
|
||||||
|
text-align: left;
|
||||||
|
line-height: 24px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: rgba(0,0,0,80%);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.container-children{
|
||||||
|
margin-top: 30px;
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100vh - 180px);
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
#terminal{
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100vh - 180px);
|
||||||
|
|
||||||
|
.xterm-screen{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.zhst-form-item .zhst-form-item-control-input-content{
|
||||||
|
.zhst-btn-default:not(:disabled):not(.zhst-btn-disabled):hover{
|
||||||
|
color: #23ACB2;
|
||||||
|
border-color:#23acb2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zhst-input-affix-wrapper:focus{
|
||||||
|
border-color:#23acb2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zhst-input-affix-wrapper:hover{
|
||||||
|
border-color:#23acb2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*{
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user