imetting/frontend/src/components/MeetingFormDrawer.jsx

177 lines
6.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import React from 'react';
import { Drawer, Form, Input, Button, DatePicker, Select, Space, Upload, Card, Progress, Typography } from 'antd';
import { SaveOutlined, UploadOutlined, DeleteOutlined, AudioOutlined } from '@ant-design/icons';
import configService from '../utils/configService';
import { AUDIO_UPLOAD_ACCEPT } from '../services/meetingAudioService';
import useMeetingFormDrawer from '../hooks/useMeetingFormDrawer';
const { Text } = Typography;
const MeetingFormDrawer = ({ open, onClose, onSuccess, meetingId = null }) => {
const {
form,
isEdit,
loading,
users,
prompts,
selectedAudioFile,
audioUploading,
audioUploadProgress,
audioUploadMessage,
maxAudioSize,
handleAudioBeforeUpload,
clearSelectedAudio,
handleSubmit,
} = useMeetingFormDrawer({ open, onClose, onSuccess, meetingId });
return (
<Drawer
title={isEdit ? '编辑会议' : '新建会议'}
placement="right"
width={560}
open={open}
onClose={onClose}
destroyOnClose
extra={
<Space>
<Button type="primary" icon={<SaveOutlined />} loading={loading || audioUploading} onClick={handleSubmit}>
{isEdit ? '保存修改' : '创建会议'}
</Button>
</Space>
}
>
<Form form={form} layout="vertical">
<Form.Item label="会议主题" name="title" rules={[{ required: true, message: '请输入会议主题' }]}>
<Input placeholder="请输入会议主题..." />
</Form.Item>
<Form.Item label="开始时间" name="meeting_time" rules={[{ required: true }]}>
<DatePicker showTime style={{ width: '100%' }} />
</Form.Item>
<Form.Item label="使用总结模板" name="prompt_id">
<Select allowClear placeholder="选择总结模版">
{prompts.map((p) => (
<Select.Option key={p.id} value={p.id}>{p.name}</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item label="参会人员" name="attendee_ids">
<Select mode="multiple" placeholder="可不选参会人">
{users.map((u) => (
<Select.Option key={u.user_id} value={u.user_id}>{u.caption}</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item label="标签" name="tags">
<Select mode="tags" placeholder="输入标签按回车" />
</Form.Item>
{!isEdit ? (
<Form.Item label="会议音频">
<Card
variant="borderless"
style={{
borderRadius: 14,
border: '1px solid #d9e2f2',
background: selectedAudioFile ? 'linear-gradient(135deg, #f8fbff 0%, #ffffff 100%)' : '#fbfdff',
boxShadow: 'inset 0 1px 0 rgba(255,255,255,0.86)',
}}
styles={{ body: { padding: 18 } }}
>
<Space direction="vertical" size={14} style={{ width: '100%' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', gap: 16, alignItems: 'flex-start' }}>
<div>
<Text type="secondary">
支持 {AUDIO_UPLOAD_ACCEPT.replace(/\./g, '').toUpperCase()}
<br/>音频文件最大 {maxAudioSize ? configService.formatFileSize(maxAudioSize) : '加载中'}
</Text>
</div>
<Upload accept={AUDIO_UPLOAD_ACCEPT} showUploadList={false} beforeUpload={handleAudioBeforeUpload}>
<Button icon={<UploadOutlined />} disabled={audioUploading}>选择音频</Button>
</Upload>
</div>
{selectedAudioFile ? (
<div
style={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
gap: 16,
padding: '12px 14px',
borderRadius: 12,
background: '#ffffff',
border: '1px solid #dbe7f5',
}}
>
<Space size={12}>
<div
style={{
width: 36,
height: 36,
borderRadius: 12,
display: 'grid',
placeItems: 'center',
background: '#edf4ff',
color: '#1d4ed8',
}}
>
<AudioOutlined />
</div>
<div>
<Text strong style={{ display: 'block' }}>{selectedAudioFile.name}</Text>
<Text type="secondary">{configService.formatFileSize(selectedAudioFile.size)}</Text>
</div>
</Space>
<Button type="text" icon={<DeleteOutlined />} onClick={clearSelectedAudio} disabled={audioUploading}>
移除
</Button>
</div>
) : (
<div
style={{
borderRadius: 12,
border: '1px dashed #c7d5ea',
padding: '18px 16px',
background: '#ffffff',
color: 'rgba(17, 43, 78, 0.66)',
textAlign: 'center',
}}
>
可在会议详情中补传
</div>
)}
{audioUploading ? (
<div
style={{
padding: '12px 14px',
borderRadius: 12,
background: '#f0f7ff',
border: '1px solid #bfdbfe',
}}
>
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 8 }}>
<Text strong>音频上传中</Text>
<Text strong style={{ color: '#1677ff' }}>{audioUploadProgress}%</Text>
</div>
<Text type="secondary" style={{ display: 'block', marginBottom: 10 }}>
{audioUploadMessage || '正在上传音频文件...'}
</Text>
<Progress percent={audioUploadProgress} status="active" strokeColor={{ from: '#69b1ff', to: '#1677ff' }} />
</div>
) : null}
</Space>
</Card>
</Form.Item>
) : null}
</Form>
</Drawer>
);
};
export default MeetingFormDrawer;