Merge branch 'develop-cy' into 'develop'
🦄 refactor: 【CenterLink】完善中心对接模块物料; See merge request web-project/zhst-lambo!15
This commit is contained in:
commit
f2cc70c785
65
packages/material/src/centerLink/CenterLink.tsx
Normal file
65
packages/material/src/centerLink/CenterLink.tsx
Normal file
@ -0,0 +1,65 @@
|
||||
import React,{useRef} from 'react'
|
||||
import TerminalForm from './components/TerminalForm'
|
||||
import WebTerminal from './components/WebTerminal'
|
||||
import './index.less';
|
||||
import style from 'packages/meta/src/badge/style';
|
||||
|
||||
interface CenterLinkProps{
|
||||
websocketUrl:string; // websocket服务地址
|
||||
token:string; // 用户token信息
|
||||
ip:string; // IP地址
|
||||
onExportLogs:()=>void, // 导出日志事件
|
||||
terminalStyle?:React.CSSProperties;
|
||||
onConnect?:(values:any) => void, // 连接服务器事件
|
||||
onOpen?: (event: WebSocketEventMap['open'], instance: WebSocket) => void;
|
||||
onClose?: (event: WebSocketEventMap['close'], instance: WebSocket) => void;
|
||||
onMessage?: (message: WebSocketEventMap['message'], instance: WebSocket) => void;
|
||||
onError?: (event: WebSocketEventMap['error'], instance: WebSocket) => void;
|
||||
style?:React.CSSProperties;
|
||||
}
|
||||
|
||||
const materialName='center-link';
|
||||
|
||||
const CenterLink:React.FC<CenterLinkProps>=(props:CenterLinkProps)=>{
|
||||
const {
|
||||
websocketUrl,
|
||||
ip,
|
||||
token,
|
||||
terminalStyle,
|
||||
onConnect,
|
||||
onExportLogs,
|
||||
onOpen,
|
||||
onClose,
|
||||
onMessage,
|
||||
onError,
|
||||
style
|
||||
}=props;
|
||||
const webRef=useRef(null);
|
||||
|
||||
// 处理开始连接服务器ip的事件
|
||||
const handleConnectClick=(values:any)=>{
|
||||
const {ip}=values;
|
||||
if(ip&&token&&websocketUrl&&webRef.current){
|
||||
webRef.current.connect();
|
||||
}
|
||||
onConnect&&onConnect(values);
|
||||
}
|
||||
return (
|
||||
<div className={materialName} style={style}>
|
||||
<TerminalForm onConnect={handleConnectClick} onExportLogs={onExportLogs} />
|
||||
<WebTerminal
|
||||
ref={webRef}
|
||||
websocketUrl={websocketUrl}
|
||||
ip={ip}
|
||||
token={token}
|
||||
terminalStyle={terminalStyle}
|
||||
onOpen={onOpen}
|
||||
onClose={onClose}
|
||||
onMessage={onMessage}
|
||||
onError={onError}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default CenterLink
|
68
packages/material/src/centerLink/components/TerminalForm.tsx
Normal file
68
packages/material/src/centerLink/components/TerminalForm.tsx
Normal file
@ -0,0 +1,68 @@
|
||||
import React from 'react';
|
||||
import { Button, Form, Input,FormProps } from '@zhst/meta';
|
||||
import '../index.less';
|
||||
|
||||
const materialName='terminal-form';
|
||||
|
||||
export interface TerminalFormProps{
|
||||
onConnect:FormProps['onFinish']; // 开始连接事件
|
||||
onExportLogs:()=>void; // 导出日志事件
|
||||
}
|
||||
|
||||
const TerminalForm:React.FC<TerminalFormProps>=(props:TerminalFormProps)=> {
|
||||
const {
|
||||
onConnect,
|
||||
onExportLogs,
|
||||
}=props;
|
||||
const [form] = Form.useForm();
|
||||
return (
|
||||
<div className={materialName}>
|
||||
<h1>连接中心服务器</h1>
|
||||
<Form form={form} requiredMark={false} layout={'inline'} >
|
||||
<Form.Item
|
||||
label="输入中心服务器IP"
|
||||
name="ip"
|
||||
rules={[
|
||||
{ required: true, message: 'ip不能为空' },
|
||||
{
|
||||
pattern: new RegExp(
|
||||
'^(?=(\\b|\\D))(((\\d{1,2})|(1\\d{1,2})|(2[0-4]\\d)|(25[0-5]))\\.){3}((\\d{1,2})|(1\\d{1,2})|(2[0-4]\\d)|(25[0-5]))(?=(\\b|\\D))$',
|
||||
'g',
|
||||
),
|
||||
message: '输入ip格式不正确',
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
whitespace: true,
|
||||
message: '请输入不包含空格的ip',
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input style={{ width: 320, height: 36 }} allowClear />
|
||||
</Form.Item>
|
||||
<Form.Item >
|
||||
<Button
|
||||
style={{ width: 100, height: 36,background:'#23ACB2' }}
|
||||
type="primary"
|
||||
onClick={async()=>{
|
||||
const values=await form.validateFields();
|
||||
onConnect&&onConnect(values);
|
||||
}}
|
||||
>
|
||||
开始连接
|
||||
</Button>
|
||||
</Form.Item>
|
||||
<Form.Item >
|
||||
<Button
|
||||
style={{ width: 100, height: 36 }}
|
||||
onClick={onExportLogs}
|
||||
>
|
||||
导出日志
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default TerminalForm;
|
133
packages/material/src/centerLink/components/WebTerminal.tsx
Normal file
133
packages/material/src/centerLink/components/WebTerminal.tsx
Normal file
@ -0,0 +1,133 @@
|
||||
|
||||
import React,{useRef,useEffect, useImperativeHandle,
|
||||
forwardRef,} from 'react';
|
||||
import { useWebSocket } from '@zhst/hooks';
|
||||
import { Terminal } from 'xterm';
|
||||
import { FitAddon } from 'xterm-addon-fit';
|
||||
import 'xterm/css/xterm.css';
|
||||
import '../index.less';
|
||||
|
||||
|
||||
export interface WebsocketOptions {
|
||||
reconnectLimit?: number; // 重试次数
|
||||
reconnectInterval?: number; // 重试时间间隔(ms)
|
||||
onOpen?: (event: WebSocketEventMap['open'], instance: WebSocket) => void; // webSocket 连接成功回调
|
||||
onClose?: (event: WebSocketEventMap['close'], instance: WebSocket) => void; // webSocket 关闭回调
|
||||
onMessage?: (message: WebSocketEventMap['message'], instance: WebSocket) => void; // webSocket 收到消息回调
|
||||
onError?: (event: WebSocketEventMap['error'], instance: WebSocket) => void; // webSocket 错误回调
|
||||
protocols?: string | string[]; // 子协议
|
||||
}
|
||||
|
||||
enum ReadyState {
|
||||
Connecting = 0,
|
||||
Open = 1,
|
||||
Closing = 2,
|
||||
Closed = 3,
|
||||
}
|
||||
|
||||
export interface WebsocketResult {
|
||||
latestMessage?: WebSocketEventMap['message']; // 最新消息
|
||||
sendMessage: WebSocket['send']; // 发送消息函数
|
||||
disconnect: () => void; // 手动断开 webSocket 连接
|
||||
connect: () => void; // 手动连接 webSocket,如果当前已有连接,则关闭后重新连接
|
||||
readyState: ReadyState; // 当前 webSocket 连接状态
|
||||
webSocketIns?: WebSocket; // webSocket 实例
|
||||
}
|
||||
interface WebTerminalProps{
|
||||
websocketUrl:string; // websocket服务地址
|
||||
token:string; // 用户token信息
|
||||
ip:string; // IP地址
|
||||
terminalStyle?:React.CSSProperties;
|
||||
onOpen?: (event: WebSocketEventMap['open'], instance: WebSocket) => void;
|
||||
onClose?: (event: WebSocketEventMap['close'], instance: WebSocket) => void;
|
||||
onMessage?: (message: WebSocketEventMap['message'], instance: WebSocket) => void;
|
||||
onError?: (event: WebSocketEventMap['error'], instance: WebSocket) => void;
|
||||
}
|
||||
const materialName = 'web-terminal'
|
||||
|
||||
const WebTerminal:React.FC<WebTerminalProps&WebsocketOptions>=forwardRef((props:WebTerminalProps&WebsocketOptions,ref)=> {
|
||||
const {
|
||||
websocketUrl='',
|
||||
token='',
|
||||
ip='',
|
||||
terminalStyle,
|
||||
onOpen,
|
||||
onClose,
|
||||
onMessage,
|
||||
onError,
|
||||
}=props;
|
||||
const { readyState, sendMessage, latestMessage, disconnect, connect }:WebsocketResult = useWebSocket(
|
||||
`${websocketUrl}?ip=${ip}&Authorization=${token}`,{manual:true,reconnectLimit:0,onOpen,
|
||||
onClose,
|
||||
onMessage,
|
||||
onError}
|
||||
);
|
||||
const termRef = useRef(null);
|
||||
const termClassRef=useRef(null)
|
||||
// const currLine=useRef(null);
|
||||
|
||||
useEffect(()=>{
|
||||
if(termClassRef?.current){
|
||||
termClassRef.current.write(latestMessage?.data+'\r\n\x1b[33m$\x1b[0m ');
|
||||
}
|
||||
},[latestMessage]);
|
||||
|
||||
// terminal初始化
|
||||
useEffect(()=>{
|
||||
// 初始化terminal
|
||||
if(!termRef.current){
|
||||
return;
|
||||
}
|
||||
termClassRef.current=new Terminal({
|
||||
fontFamily: 'Menlo, Monaco, "Courier New", monospace',
|
||||
fontWeight: 400,
|
||||
fontSize: 14,
|
||||
rows: Math.ceil(
|
||||
(termRef.current?.clientHeight -
|
||||
150) /
|
||||
14,
|
||||
),
|
||||
convertEol: true,//控制终端是否自动将 \n 转换为 \r\n。
|
||||
cursorBlink: true,//指定光标是否闪烁
|
||||
scrollback: 50, //终端中的回滚量
|
||||
disableStdin: false, //是否应禁用输入。
|
||||
cursorStyle: "underline", //光标样式
|
||||
windowsMode: true, // 根据窗口换行
|
||||
theme: {
|
||||
foreground: "#ffffff", //字体
|
||||
background: "#1a1a1d", //背景色
|
||||
cursor: "help", //设置光标
|
||||
}
|
||||
})
|
||||
|
||||
let term=termClassRef.current;
|
||||
term.open(termRef.current);
|
||||
term.focus(); // 光标聚集
|
||||
term.promp=(_)=>{
|
||||
term.write('\r\n\x1b[33m$\x1b[0m ');
|
||||
}
|
||||
const fitAddon=new FitAddon();
|
||||
term.loadAddon(fitAddon);
|
||||
fitAddon.fit();
|
||||
term.promp();
|
||||
|
||||
},[]);
|
||||
|
||||
// 自定义暴露给父组件的实例
|
||||
useImperativeHandle(ref,()=>({
|
||||
readyState,
|
||||
sendMessage,
|
||||
latestMessage,
|
||||
disconnect,
|
||||
connect
|
||||
}));
|
||||
|
||||
return (
|
||||
<div className={materialName}>
|
||||
<div style={terminalStyle} ref={termRef}></div>
|
||||
</div>
|
||||
|
||||
)
|
||||
})
|
||||
|
||||
export default WebTerminal;
|
32
packages/material/src/centerLink/demo/basic.tsx
Normal file
32
packages/material/src/centerLink/demo/basic.tsx
Normal file
@ -0,0 +1,32 @@
|
||||
import React from 'react';
|
||||
import { CenterLink } from '@zhst/material';
|
||||
|
||||
const demo = () => {
|
||||
return (
|
||||
<CenterLink
|
||||
style={{width:'100%',height:'600px'}}
|
||||
websocketUrl={'ws://10.0.0.7:50051/active'}
|
||||
token={'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MTM1OTI2NDYsImp0aSI6ImFkbWluIn0._mVU216h0q8va8bZ8PCKfGOKslYJWdRLFvLzUdvGDN4'}
|
||||
ip={'127.0.0.1'}
|
||||
terminalStyle={{width:'100%',height:'calc(100% - 180px)'}}
|
||||
onConnect={(values)=>{
|
||||
console.log(values,'====> Connecting');
|
||||
}}
|
||||
onExportLogs={()=>{console.log('=====> Export Log')}}
|
||||
onOpen={(event: WebSocketEventMap['open'], instance: WebSocket)=>{
|
||||
console.log(event,'===>open'); // webSocket 连接成功回调
|
||||
}}
|
||||
onClose={(event: WebSocketEventMap['close'], instance: WebSocket)=>{
|
||||
console.log(event,'===>close'); // webSocket 关闭回调
|
||||
}}
|
||||
onMessage={(message: WebSocketEventMap['message'], instance: WebSocket)=>{
|
||||
console.log(message,'===>message'); // webSocket 消息回调
|
||||
}}
|
||||
onError={(event: WebSocketEventMap['error'], instance: WebSocket)=>{
|
||||
console.log(event,'===>error'); // webSocket 错误回调
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default demo;
|
32
packages/material/src/centerLink/index.less
Normal file
32
packages/material/src/centerLink/index.less
Normal file
@ -0,0 +1,32 @@
|
||||
.center-link{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 30px;
|
||||
box-sizing: border-box;
|
||||
background-color: #E5EAEC;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.web-terminal{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
// padding: 30px;
|
||||
// box-sizing: border-box;
|
||||
// background-color: #E5EAEC;
|
||||
// overflow: hidden;
|
||||
}
|
||||
|
||||
.terminal-form{
|
||||
width: 100%;
|
||||
margin-bottom: 30px;
|
||||
|
||||
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%);
|
||||
}
|
||||
}
|
30
packages/material/src/centerLink/index.md
Normal file
30
packages/material/src/centerLink/index.md
Normal file
@ -0,0 +1,30 @@
|
||||
---
|
||||
category: Components
|
||||
title: CenterLink 中心对接
|
||||
toc: content
|
||||
group:
|
||||
title: 通用
|
||||
order: 2
|
||||
---
|
||||
|
||||
中心对接
|
||||
|
||||
## 代码演示
|
||||
|
||||
<code src="./demo/basic.tsx">基本用法</code>
|
||||
|
||||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| websocketUrl | websocket地址【必传】 | string | - | - |
|
||||
| ip | 服务器ip地址【必传】 | string | - | - |
|
||||
| token | 用户token信息【必传】 | string | - | - |
|
||||
| terminalStyle | 终端黑盒子样式【可选传】 | React.CSSProperties | - | - |
|
||||
| style | 整个页面的样式【可选传】 | React.CSSProperties | - | - |
|
||||
| onExportLogs | 导出日志事件【可选传】 | ()=>void | - | - |
|
||||
| onConnect | 连接服务器事件【可选传】 | (values:any) => void | - | - |
|
||||
| onOpen | webSocket 连接成功回调【可选传】 | (event: WebSocketEventMap['open'], instance: WebSocket) => void | - | - |
|
||||
| onClose | webSocket 关闭回调【可选传】 | (event: WebSocketEventMap['close'], instance: WebSocket) => void | - | - |
|
||||
| onMessage | webSocket 收到消息回调【可选传】 | (event:WebSocketEventMap['message'], instance: WebSocket) => void | - | - |
|
||||
| onError | webSocket 错误回调【可选传】 | (event: WebSocketEventMap['error'], instance: WebSocket) => void | - | - |
|
3
packages/material/src/centerLink/index.tsx
Normal file
3
packages/material/src/centerLink/index.tsx
Normal file
@ -0,0 +1,3 @@
|
||||
import CenterLink from "./CenterLink";
|
||||
|
||||
export default CenterLink;
|
@ -3,6 +3,6 @@ export { default as AlgorithmConfig } from './algorithmConfig';
|
||||
export type { AlgorithmConfigRef, AlgorithmConfigProps } from './algorithmConfig';
|
||||
export { default as Login } from './login';
|
||||
export { default as Password } from './password';
|
||||
export { default as Terminal } from './terminal';
|
||||
export { default as CenterLink } from './centerLink';
|
||||
export { default as SchemaFormModal } from './algorithmConfig/components/schemaFormModal';
|
||||
export * from 'rc-util'
|
||||
|
@ -1,65 +0,0 @@
|
||||
import { Button, Form, Input,FormProps } from '@zhst/meta';
|
||||
import React from 'react';
|
||||
import WebTerminal from './components/WebTerminal';
|
||||
import './index.less';
|
||||
|
||||
interface TerminalProps{
|
||||
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 {onFinish,websocketUrl='',token='',ip='',onExportLog}=props;
|
||||
const [form] = Form.useForm();
|
||||
|
||||
const handleCenterConnect = async () => {
|
||||
const values = await form.validateFields();
|
||||
onFinish&&onFinish(values);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={materialName} style={{}}>
|
||||
<h1 >连接中心服务器</h1>
|
||||
<Form form={form} requiredMark={false} layout={'inline'} >
|
||||
<Form.Item
|
||||
label="输入中心服务器IP"
|
||||
name="ip"
|
||||
rules={[
|
||||
{ required: true, message: 'ip不能为空' },
|
||||
{
|
||||
pattern: new RegExp(
|
||||
'^(?=(\\b|\\D))(((\\d{1,2})|(1\\d{1,2})|(2[0-4]\\d)|(25[0-5]))\\.){3}((\\d{1,2})|(1\\d{1,2})|(2[0-4]\\d)|(25[0-5]))(?=(\\b|\\D))$',
|
||||
'g',
|
||||
),
|
||||
message: '输入ip格式不正确',
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
whitespace: true,
|
||||
message: '请输入不包含空格的ip',
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input style={{ width: 320, height: 36 }} allowClear />
|
||||
</Form.Item>
|
||||
<Form.Item >
|
||||
<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>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
<WebTerminal websocketUrl={websocketUrl} token={token} ip={ip} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Terminal;
|
@ -1,164 +0,0 @@
|
||||
// @ts-nocheck
|
||||
import React, {Component,useRef,useEffect } from 'react';
|
||||
import { Terminal } from 'xterm';
|
||||
import { FitAddon } from 'xterm-addon-fit';
|
||||
import WebsocketTerm from './WebsocketTerm';
|
||||
import 'xterm/css/xterm.css';
|
||||
|
||||
// TODO:引入xterm 后续需要和后端在建立websocket连接再次调试
|
||||
export default class WebTerminal extends Component {
|
||||
term = null;
|
||||
websocket = null;
|
||||
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() {
|
||||
let term = this.term;
|
||||
// term初始化
|
||||
this.term = new Terminal({
|
||||
fontFamily: 'Menlo, Monaco, "Courier New", monospace',
|
||||
fontWeight: 400,
|
||||
fontSize: 14,
|
||||
rows: Math.ceil(
|
||||
(document.getElementsByClassName('container-children')[0].clientHeight -
|
||||
150) /
|
||||
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.focus(); // 光标聚集
|
||||
this.term.prompt = (_) => {
|
||||
this.term.write('\r\n\x1b[33m$\x1b[0m ');
|
||||
};
|
||||
// // 换行并输入起始符
|
||||
// this.term.prompt = (_) => {
|
||||
// this.term.write("\r\n>>> ")
|
||||
// }
|
||||
|
||||
if(this.ip!==''){
|
||||
this.term.write('root@'+this.ip);
|
||||
}
|
||||
const fitAddon = new FitAddon();
|
||||
this.term.loadAddon(fitAddon);
|
||||
fitAddon.fit();
|
||||
this.term.prompt();
|
||||
|
||||
// 添加事件监听器,支持输入方法
|
||||
this.term.onKey((e) => {
|
||||
const printable =
|
||||
!e.domEvent.altKey &&
|
||||
!e.domEvent.altGraphKey &&
|
||||
!e.domEvent.ctrlKey &&
|
||||
!e.domEvent.metaKey;
|
||||
if (e.domEvent.keyCode === 13) {
|
||||
this.Send(term, this.curr_line);
|
||||
this.term.prompt();
|
||||
this.curr_line = '';
|
||||
} else if (e.domEvent.keyCode === 8) {
|
||||
// back 删除的情况
|
||||
if (this.term._core.buffer.x > 2) {
|
||||
if (this.curr_line.length) {
|
||||
this.curr_line = this.curr_line.slice(0, this.curr_line.length - 1);
|
||||
this.term.write('\b \b');
|
||||
} else {
|
||||
}
|
||||
}
|
||||
} else if (printable) {
|
||||
this.curr_line += e.key;
|
||||
this.term.write(e.key);
|
||||
}
|
||||
this.term.focus();
|
||||
});
|
||||
this.term.onData((key) => {
|
||||
// 粘贴的情况
|
||||
if (key.length > 1) {
|
||||
this.term.write(key);
|
||||
this.curr_line += key;
|
||||
}
|
||||
});
|
||||
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() {
|
||||
this.term.dispose();
|
||||
// WebSocket 方法 关闭连接
|
||||
this.websocket.close();
|
||||
}
|
||||
|
||||
|
||||
initWebsock = () => {
|
||||
let term = this.term;
|
||||
let token = this.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) {
|
||||
term.write('connect');
|
||||
};
|
||||
|
||||
// 连接关闭时触发
|
||||
this.websocket.onclose = function (evt) {
|
||||
term.write('exit');
|
||||
};
|
||||
|
||||
// 客户端接收服务端数据时触发
|
||||
this.websocket.onmessage = function (evt) {
|
||||
term.write(evt.data);
|
||||
};
|
||||
|
||||
// 通信发生错误时触发
|
||||
this.websocket.onerror = function (evt) {
|
||||
term.write('connect fail err:' + evt.data);
|
||||
};
|
||||
};
|
||||
|
||||
prompt = (term) => {
|
||||
this.term.write('\r\n~$ ');
|
||||
};
|
||||
|
||||
// WebSocket 方法 使用连接发送数据
|
||||
Send = (term, message) => {
|
||||
this.websocket.send(message);
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="container-children">
|
||||
<div id="terminal"></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Terminal } from '@zhst/material';
|
||||
|
||||
const demo = () => {
|
||||
|
||||
return (
|
||||
<Terminal
|
||||
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');}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default demo;
|
@ -1,64 +0,0 @@
|
||||
.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;
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
---
|
||||
category: Components
|
||||
title: Terminal 中心对接
|
||||
toc: content
|
||||
group:
|
||||
title: 通用
|
||||
order: 2
|
||||
---
|
||||
|
||||
中心对接
|
||||
|
||||
## 代码演示
|
||||
|
||||
<code src="./demo/basic.tsx">基本用法</code>
|
||||
|
||||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| onFinish | 提交事件 | FormProps['onFinish'] | - | - |
|
@ -1,3 +0,0 @@
|
||||
import Terminal from './Terminal'
|
||||
|
||||
export default Terminal;
|
@ -0,0 +1,15 @@
|
||||
// 可应用于页面跳转以及文件下载
|
||||
// 第一个参数:文件的下载路径/要跳转页面的路径(可携带参数)
|
||||
// 第二个参数:是否新打开一个页面,true为新开一个页面,false是在当前页面进行操作;
|
||||
export const createAElement = (url: string, isBlank: boolean) => {
|
||||
var newLink = document.createElement('a');
|
||||
newLink.className = 'create-link';
|
||||
newLink.href = url;
|
||||
if (isBlank) {
|
||||
newLink.target = '_blank';
|
||||
}
|
||||
document.body.appendChild(newLink);
|
||||
newLink.click();
|
||||
document.body.removeChild(newLink);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user