Merge pull request '合并dev' (#107) from dev-zw into dev

This commit is contained in:
cp3hnu 2024-07-19 14:27:43 +08:00
commit 9fbfb5cda2
8 changed files with 133 additions and 1 deletions

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"
}, },

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

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;
}
}

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/EruwZfxVgDkWdLYs';
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;

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,
};
};

View File

@ -134,7 +134,6 @@ function LogGroup({
// 建立 socket 连接 // 建立 socket 连接
const setupSockect = () => { const setupSockect = () => {
let { host } = location; let { host } = location;
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
host = '172.20.32.181:31213'; host = '172.20.32.181:31213';
} }

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;
}
} }

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>
); );
} }