feat: 【中心对接】中心对接模块写入物料库

This commit is contained in:
chaiying 2024-04-17 14:22:48 +08:00
parent 8866db8058
commit 60f913c5a5
7 changed files with 220 additions and 1 deletions

View File

@ -52,7 +52,10 @@
"prettier --parser=typescript --write"
]
},
"dependencies": {},
"dependencies": {
"xterm": "^5.3.0",
"xterm-addon-fit": "^0.8.0"
},
"devDependencies": {
"@changesets/cli": "^2.27.1",
"@commitlint/cli": "^17.1.2",

View File

@ -3,5 +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 SchemaFormModal } from './algorithmConfig/components/schemaFormModal';
export * from 'rc-util'

View File

@ -0,0 +1,63 @@
import { Button, Form, Input,FormProps } from '@zhst/meta';
import React from 'react';
import WebTerminal from './components/WebTerminal';
interface TerminalProps{
onFinish:FormProps['onFinish']
}
const Terminal: React.FC<TerminalProps> = (props:TerminalProps) => {
const {onFinish}=props;
const [form] = Form.useForm();
const handleCenterConnect = async () => {
const values = await form.validateFields();
onFinish&&onFinish(values);
};
return (
<div style={{width:'100%',height:'100%',boxSizing:'border-box',padding:'30px',overflow:"hidden"}}>
<h1 style={{
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.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 type="primary" onClick={handleCenterConnect}>
</Button>
</Form.Item>
</Form>
<div style={{marginTop:30,width:'100%',height:'calc(100% - 120px)',boxSizing:'border-box',overflow:'hidden'}}>
<WebTerminal />
</div>
</div>
);
};
export default Terminal;

View File

@ -0,0 +1,114 @@
// import { getToken } from '@libs/auth';
import React, { Component } from 'react';
import { Terminal } from 'xterm';
import { FitAddon } from 'xterm-addon-fit';
import 'xterm/css/xterm.css';
// TODO:引入xterm 后续需要和后端在建立websocket连接再次调试
export default class WebTerminal extends Component {
term = null;
websocket = null;
curr_line = '';
componentDidMount() {
let term = this.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,
),
});
this.term.open(document.getElementById('terminal'));
this.term.focus();
this.term.prompt = (_) => {
this.term.write('\r\n\x1b[33m$\x1b[0m ');
};
this.term.prompt();
const fitAddon = new FitAddon();
this.term.loadAddon(fitAddon);
fitAddon.fit();
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) => {
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();
console.log(1, 'print', e.key);
});
this.term.onData((key) => {
// 粘贴的情况
if (key.length > 1) {
this.term.write(key);
this.curr_line += key;
}
});
this.initWebsock();
}
componentWillUnmount() {
this.term.dispose();
this.websocket.close();
}
initWebsock = () => {
// let websocket = this.websocket;
let term = this.term;
let token = 'aaaa';
this.websocket = new WebSocket('ws://' + window?._CONFIG?.WsSsh!, token);
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~$ ');
// };
Send = (term, message) => {
this.websocket.send(message);
};
render() {
return (
<div className="container-children" style={{ height: '100%' }}>
<div id="terminal" style={{ width: '100%' }}></div>
</div>
);
}
}

View File

@ -0,0 +1,15 @@
import React, { useState } from 'react';
import { Terminal } from '@zhst/material';
const demo = () => {
return (
<div style={{ padding: '24px', width: '500px', border: '1px solid #eee' }}>
<Terminal
onFinish={val => console.log('val', val)}
/>
</div>
);
};
export default demo;

View File

@ -0,0 +1,20 @@
---
category: Components
title: Terminal 中心对接
toc: content
group:
title: 通用
order: 2
---
中心对接
## 代码演示
<code src="./demo/basic.tsx">基本用法</code>
## API
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| onFinish | 提交事件 | FormProps['onFinish'] | - | - |

View File

@ -0,0 +1,3 @@
import Terminal from './Terminal'
export default Terminal;