Browse Source

feat: 接入机器人

pull/107/head
cp3hnu 1 year ago
parent
commit
2ebbc7374a
7 changed files with 133 additions and 0 deletions
  1. +1
    -0
      react-ui/package.json
  2. BIN
      react-ui/src/assets/img/robot.png
  3. +34
    -0
      react-ui/src/components/RobotFrame/index.less
  4. +30
    -0
      react-ui/src/components/RobotFrame/index.tsx
  5. +37
    -0
      react-ui/src/hooks/draggable.ts
  6. +11
    -0
      react-ui/src/pages/Workspace/index.less
  7. +20
    -0
      react-ui/src/pages/Workspace/index.tsx

+ 1
- 0
react-ui/package.json View File

@@ -76,6 +76,7 @@
"react-cropper": "^2.3.3", "react-cropper": "^2.3.3",
"react-dev-inspector": "^1.8.1", "react-dev-inspector": "^1.8.1",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-draggable": "^4.4.6",
"react-helmet-async": "^1.3.0", "react-helmet-async": "^1.3.0",
"react-highlight": "^0.15.0" "react-highlight": "^0.15.0"
}, },


BIN
react-ui/src/assets/img/robot.png View File

Before After
Width: 128  |  Height: 128  |  Size: 1.8 kB

+ 34
- 0
react-ui/src/components/RobotFrame/index.less View File

@@ -0,0 +1,34 @@
.robot-frame {
position: fixed;
top: 55px;
right: -610px;
z-index: 100;
width: 600px;
height: calc(100% - 55px);
background-color: #fff;
box-shadow: -6px 0 16px 0 rgba(0, 0, 0, 0.08), -3px 0 6px -4px rgba(0, 0, 0, 0.12),
-9px 0 28px 8px rgba(0, 0, 0, 0.05);
transition: right 0.3s ease-in-out;

// 增加优先级
&&--visible {
right: 0;
}

&__header {
display: flex;
gap: 10px;
align-items: center;
justify-content: flex-end;
width: 100%;
height: 60px;
padding: 0 15px;
border-bottom: 1px solid #e8e8e8;
}

&__iframe {
width: 100%;
height: calc(100% - 60px);
border: 0;
}
}

+ 30
- 0
react-ui/src/components/RobotFrame/index.tsx View File

@@ -0,0 +1,30 @@
import { CloseOutlined, ExpandOutlined } from '@ant-design/icons';
import { Button } from 'antd';
import classNames from 'classnames';
import styles from './index.less';

type RobotFrameProps = {
onClose: () => void;
visible: boolean;
};

function RobotFrame({ onClose, visible }: RobotFrameProps) {
const url = 'http://172.20.32.181:30080/chat/l4S79c4rly0o1pn7';
const openUrl = () => {
window.open(url, '_blank');
};

return (
<div
className={classNames(styles['robot-frame'], { [styles['robot-frame--visible']]: visible })}
>
<div className={styles['robot-frame__header']}>
<Button icon={<ExpandOutlined />} type="text" onClick={openUrl}></Button>
<Button icon={<CloseOutlined />} type="text" onClick={onClose}></Button>
</div>
<iframe className={styles['robot-frame__iframe']} src={url} allow="microphone"></iframe>
</div>
);
}

export default RobotFrame;

+ 37
- 0
react-ui/src/hooks/draggable.ts View File

@@ -0,0 +1,37 @@
// 处理 react-draggable 组件拖动结束时,响应了点击事件的
import { useState } from 'react';

export const useDraggable = (onClick: () => void) => {
const [isDragging, setIsDragging] = useState(false);

const handleStart = () => {
setIsDragging(false);
};

const handleDrag = () => {
if (!isDragging) {
setIsDragging(true);
}
};

const handleStop = () => {
// 延迟设置 isDragging 为 false 是为了确保在点击事件触发之前它仍然为 true
setTimeout(() => setIsDragging(false), 0);
};

const handleClick = (e: React.MouseEvent<HTMLElement>) => {
if (isDragging) {
e.preventDefault();
e.stopPropagation();
} else {
onClick();
}
};

return {
handleStart,
handleDrag,
handleStop,
handleClick,
};
};

+ 11
- 0
react-ui/src/pages/Workspace/index.less View File

@@ -1,4 +1,5 @@
.workspace { .workspace {
position: relative;
height: 100%; height: 100%;
padding: 20px 30px 10px; padding: 20px 30px 10px;
overflow-y: auto; overflow-y: auto;
@@ -43,4 +44,14 @@
min-width: 326px; min-width: 326px;
height: 700px; height: 700px;
} }

&__robot-img {
position: fixed;
right: 30px;
bottom: 20px;
width: 64px;
height: 64px;
background-color: white;
cursor: pointer;
}
} }

+ 20
- 0
react-ui/src/pages/Workspace/index.tsx View File

@@ -1,7 +1,10 @@
import RobotFrame from '@/components/RobotFrame';
import { useDraggable } from '@/hooks/draggable';
import { getWorkspaceOverviewReq } from '@/services/workspace'; import { getWorkspaceOverviewReq } from '@/services/workspace';
import { ExperimentInstance } from '@/types'; import { ExperimentInstance } from '@/types';
import { to } from '@/utils/promise'; import { to } from '@/utils/promise';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import Draggable from 'react-draggable';
import AssetsManagement from './components/AssetsManagement'; import AssetsManagement from './components/AssetsManagement';
import ExperimentChart, { type ExperimentStatistics } from './components/ExperimentChart'; import ExperimentChart, { type ExperimentStatistics } from './components/ExperimentChart';
import ExperitableTable from './components/ExperimentTable'; import ExperitableTable from './components/ExperimentTable';
@@ -20,6 +23,10 @@ type OverviewData = {


function Workspace() { function Workspace() {
const [overviewData, setOverviewData] = useState<OverviewData>(); const [overviewData, setOverviewData] = useState<OverviewData>();
const [robotFrameVisible, setRobotFrameVisible] = useState(false);
const { handleStart, handleStop, handleDrag, handleClick } = useDraggable(() =>
setRobotFrameVisible((prev) => !prev),
);
const users: number[] = new Array(8).fill(0); const users: number[] = new Array(8).fill(0);
useEffect(() => { useEffect(() => {
getWorkspaceOverview(); getWorkspaceOverview();
@@ -64,6 +71,19 @@ function Workspace() {
<AssetsManagement></AssetsManagement> <AssetsManagement></AssetsManagement>
</div> </div>
</div> </div>
<Draggable onStart={handleStart} onStop={handleStop} onDrag={handleDrag}>
<img
className={styles['workspace__robot-img']}
src={require('@/assets/img/robot.png')}
onClick={handleClick}
onDragStart={(e) => e.preventDefault()}
></img>
</Draggable>

<RobotFrame
visible={robotFrameVisible}
onClose={() => setRobotFrameVisible(false)}
></RobotFrame>
</div> </div>
); );
} }


Loading…
Cancel
Save