122 lines
4.0 KiB
TypeScript
122 lines
4.0 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { Card, Form, Input, Button, Upload, message, Progress, Select, Row, Col } from 'antd';
|
|
import { InboxOutlined, AudioOutlined, UserAddOutlined } from '@ant-design/icons';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { api } from '../api';
|
|
import PageHeader from '../components/PageHeader/PageHeader';
|
|
|
|
const { Dragger } = Upload;
|
|
const { Option } = Select;
|
|
|
|
const MeetingLive: React.FC = () => {
|
|
const [form] = Form.useForm();
|
|
const [uploading, setUploading] = useState(false);
|
|
const [progress, setProgress] = useState(0);
|
|
const navigate = useNavigate();
|
|
|
|
const handleCreate = async (values: any) => {
|
|
try {
|
|
const res = await api.createMeeting(values);
|
|
message.success('会议创建成功');
|
|
navigate(`/meeting/history/${res.meeting_id}`);
|
|
} catch (error) {
|
|
console.error(error);
|
|
message.error('创建失败');
|
|
}
|
|
};
|
|
|
|
const handleUpload = async (file: File) => {
|
|
setUploading(true);
|
|
setProgress(0);
|
|
try {
|
|
// Mock progress since fetch doesn't support it easily without XHR
|
|
const timer = setInterval(() => {
|
|
setProgress((prev) => {
|
|
if (prev >= 90) {
|
|
clearInterval(timer);
|
|
return 90;
|
|
}
|
|
return prev + 10;
|
|
});
|
|
}, 500);
|
|
|
|
const res = await api.uploadMeetingAudio(file);
|
|
clearInterval(timer);
|
|
setProgress(100);
|
|
message.success('上传成功,开始转译');
|
|
// Assuming upload returns meeting_id or we navigate to list
|
|
if (res && res.meeting_id) {
|
|
navigate(`/meeting/history/${res.meeting_id}`);
|
|
} else {
|
|
navigate('/meeting/history');
|
|
}
|
|
} catch (error) {
|
|
console.error(error);
|
|
message.error('上传失败');
|
|
setUploading(false);
|
|
}
|
|
return false; // Prevent default upload behavior
|
|
};
|
|
|
|
return (
|
|
<div style={{ padding: 24 }}>
|
|
<PageHeader
|
|
title="新建会议"
|
|
description="创建实时会议或上传音频文件进行转写"
|
|
/>
|
|
|
|
<Row gutter={[24, 24]}>
|
|
<Col span={12}>
|
|
<Card title="创建实时会议" bordered={false} hoverable>
|
|
<Form form={form} layout="vertical" onFinish={handleCreate}>
|
|
<Form.Item name="title" label="会议标题" rules={[{ required: true }]}>
|
|
<Input placeholder="请输入会议标题" prefix={<AudioOutlined />} />
|
|
</Form.Item>
|
|
<Form.Item name="participants" label="参会人">
|
|
<Select mode="tags" placeholder="请输入参会人姓名" open={false}>
|
|
</Select>
|
|
</Form.Item>
|
|
<Form.Item>
|
|
<Button type="primary" htmlType="submit" icon={<UserAddOutlined />} block>
|
|
开始会议
|
|
</Button>
|
|
</Form.Item>
|
|
</Form>
|
|
</Card>
|
|
</Col>
|
|
|
|
<Col span={12}>
|
|
<Card title="上传录音文件" variant="borderless" hoverable>
|
|
<Dragger
|
|
name="file"
|
|
multiple={false}
|
|
beforeUpload={handleUpload}
|
|
showUploadList={false}
|
|
accept="audio/*,video/*"
|
|
disabled={uploading}
|
|
>
|
|
<p className="ant-upload-drag-icon">
|
|
<InboxOutlined />
|
|
</p>
|
|
<p className="ant-upload-text">点击或拖拽文件到此区域上传</p>
|
|
<p className="ant-upload-hint">
|
|
支持 MP3, WAV, M4A 等常见音频格式
|
|
</p>
|
|
</Dragger>
|
|
{uploading && (
|
|
<div style={{ marginTop: 16 }}>
|
|
<Progress percent={progress} status={progress === 100 ? 'success' : 'active'} />
|
|
<div style={{ textAlign: 'center', marginTop: 8 }}>
|
|
{progress === 100 ? '上传完成,正在处理...' : '上传中...'}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</Card>
|
|
</Col>
|
|
</Row>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default MeetingLive;
|