745 lines
28 KiB
TypeScript
745 lines
28 KiB
TypeScript
import styles from '@/page/Meeting/index.module.scss'
|
||
import { useEffect, useState } from "react";
|
||
import Operation from '@/components/Operation';
|
||
import { Navigation, Pagination } from 'swiper/modules';
|
||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||
import 'swiper/css';
|
||
import 'swiper/css/navigation';
|
||
import 'swiper/css/pagination';
|
||
import { Button, Input, Popover, Modal, Checkbox, message, Select, Slider, Table, Pagination as AntdPagination } from "antd";
|
||
import { DeleteOutlined, FolderOutlined, ProfileOutlined, ReloadOutlined, SearchOutlined, VerticalAlignBottomOutlined } from '@ant-design/icons';
|
||
import { useLocation, useNavigate } from 'react-router-dom';
|
||
import { thumbImageBufferToBase64 } from '@/utils/package/base64'
|
||
import { storage } from '@/utils';
|
||
import { GetRoomFile, PostRoomFile, DeleteRoomFile, GetRoomUpFileurl, GetRoomFileDwUrl } from '@/api/Meeting';
|
||
import axios from 'axios';
|
||
const { Column } = Table
|
||
const Meeting: React.FC = () => {
|
||
const navigate = useNavigate();
|
||
const { state } = useLocation();
|
||
const [statusList, setStatusList] = useState({
|
||
userList: false,
|
||
userChatList: false,
|
||
})
|
||
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
|
||
const [isSharedScreenModal, setIsSharedScreenModal] = useState(false);
|
||
const [isInit, setIsInit] = useState(true);
|
||
const [user, setUser] = useState<any>({});
|
||
const [isStupWizard, setIsStupWizard] = useState(false);
|
||
const [showRowSelection, setShowRowSelection] = useState(false);
|
||
const [isSharedFilesModel, setIsSharedFilesModel] = useState(false);
|
||
const [sharedScreenList, setSharedScreenList] = useState<any>([]);
|
||
const [sharedScreenItem, setSharedScreenItem] = useState<any>('');
|
||
const [footerList, setFooterList] = useState([
|
||
[
|
||
{
|
||
title: '关闭声音',
|
||
icon: '/src/assets/icon22',
|
||
active: false,
|
||
},
|
||
{
|
||
title: '关闭视频',
|
||
icon: '/src/assets/icon23',
|
||
active: false,
|
||
},
|
||
],
|
||
[
|
||
{
|
||
title: '共享屏幕',
|
||
icon: '/src/assets/icon24',
|
||
active: false,
|
||
},
|
||
{
|
||
title: '共享文件',
|
||
icon: '/src/assets/icon25',
|
||
active: false,
|
||
},
|
||
{
|
||
title: '邀请人员',
|
||
icon: '/src/assets/icon26',
|
||
active: false,
|
||
},
|
||
{
|
||
title: '录制',
|
||
icon: '/src/assets/icon27',
|
||
active: false,
|
||
},
|
||
{
|
||
title: '设置向导',
|
||
icon: '/src/assets/icon28',
|
||
active: false,
|
||
},
|
||
{
|
||
title: '结束',
|
||
icon: '/src/assets/icon29',
|
||
active: false,
|
||
},
|
||
],
|
||
[
|
||
{
|
||
title: '成员列表',
|
||
icon: '/src/assets/icon30',
|
||
active: false,
|
||
},
|
||
{
|
||
title: '聊天',
|
||
icon: '/src/assets/icon31',
|
||
active: false,
|
||
},
|
||
],
|
||
])
|
||
const [footerListIndex, setFooterListIndex] = useState<any>({
|
||
itemIndex: 0,
|
||
rowIndex: 0,
|
||
});
|
||
const [audioDeviceManager, setAudioDeviceManager] = useState<any>({
|
||
currentDevices: [],
|
||
currentDevice: {},
|
||
currentVolume: 0,
|
||
});
|
||
const [fileList, setFileList] = useState({
|
||
data: [],
|
||
keyword: '',
|
||
total: 0,
|
||
pageIndex: 1,
|
||
pageSize: 10,
|
||
})
|
||
|
||
const [stepsStatus, setStepsStatus] = useState<boolean>(true);
|
||
const [isVideoLoad, setIsVideoLoad] = useState<boolean>(false);
|
||
const [list] = useState<number[]>([1, 2, 3, 4, 5, 6, 7])
|
||
const [open, setOpen] = useState(false)
|
||
const [videoID, setVideoID] = useState('')
|
||
|
||
useEffect(() => {
|
||
if (isInit) {
|
||
setUser(JSON.parse(storage.getItem('user') as string))
|
||
// window.electron.setJoinChannel({
|
||
// channelId: state.channelId,
|
||
// userid: user.userName,
|
||
// token: state.token,
|
||
// })
|
||
setIsInit(false)
|
||
} else {
|
||
getRoomFile()
|
||
}
|
||
}, [fileList.pageIndex]);
|
||
|
||
const changeStatusList = async (row: any, itemIndex: number, rowIndex: number): Promise<void> => {
|
||
const footerListTemplate = [...footerList]
|
||
setFooterListIndex({
|
||
itemIndex,
|
||
rowIndex,
|
||
})
|
||
switch (row.title) {
|
||
case '成员列表':
|
||
setStatusList({
|
||
userList: true,
|
||
userChatList: false,
|
||
})
|
||
break;
|
||
case '聊天':
|
||
setStatusList({
|
||
userList: false,
|
||
userChatList: true,
|
||
})
|
||
break;
|
||
case '共享屏幕':
|
||
getDesktopCapturerVideo()
|
||
setIsSharedScreenModal(true)
|
||
break;
|
||
case '停止共享':
|
||
window.electron.stopScreenCapture()
|
||
footerListTemplate[itemIndex][rowIndex].title = '共享屏幕'
|
||
break;
|
||
case '关闭声音':
|
||
footerListTemplate[itemIndex][rowIndex].title = '开启声音'
|
||
footerListTemplate[itemIndex][rowIndex].active = true
|
||
setFooterList(footerListTemplate)
|
||
window.electron.muteLocalAudioStream(true)
|
||
break;
|
||
case '开启声音':
|
||
footerListTemplate[itemIndex][rowIndex].title = '关闭声音'
|
||
footerListTemplate[itemIndex][rowIndex].active = false
|
||
setFooterList(footerListTemplate)
|
||
window.electron.muteLocalAudioStream(false)
|
||
break;
|
||
case '关闭视频':
|
||
footerListTemplate[itemIndex][rowIndex].title = '开启视频'
|
||
footerListTemplate[itemIndex][rowIndex].active = true
|
||
setFooterList(footerListTemplate)
|
||
window.electron.muteLocalVideoStream(true)
|
||
break;
|
||
case '开启视频':
|
||
footerListTemplate[itemIndex][rowIndex].title = '关闭视频'
|
||
footerListTemplate[itemIndex][rowIndex].active = false
|
||
setFooterList(footerListTemplate)
|
||
window.electron.muteLocalVideoStream(false)
|
||
break;
|
||
case '设置向导':
|
||
getAudioMediaList()
|
||
window.electron.startRecordingDeviceTest(200)
|
||
setIsStupWizard(true)
|
||
break;
|
||
case '录制':
|
||
footerListTemplate[itemIndex][rowIndex].title = '录制中'
|
||
footerListTemplate[itemIndex][rowIndex].active = true
|
||
setFooterList(footerListTemplate)
|
||
window.electron.startRecording()
|
||
break;
|
||
case '录制中':
|
||
footerListTemplate[itemIndex][rowIndex].title = '录制'
|
||
footerListTemplate[itemIndex][rowIndex].active = false
|
||
setFooterList(footerListTemplate)
|
||
window.electron.stopRecording()
|
||
break;
|
||
case '共享文件':
|
||
await getRoomFile()
|
||
setIsSharedFilesModel(true)
|
||
break;
|
||
}
|
||
}
|
||
|
||
const changeVdeio = async (bool: boolean): Promise<void> => {
|
||
if (bool) {
|
||
|
||
} else {
|
||
let data = sharedScreenList.find((item: any) => item.sourceId === sharedScreenItem.sourceId)
|
||
if (data) {
|
||
const footerListTemplate = [...footerList]
|
||
footerListTemplate[footerListIndex.itemIndex][footerListIndex.rowIndex].title = '停止共享'
|
||
setIsSharedScreenModal(false)
|
||
window.electron.setDesktopCapturerVideo(sharedScreenItem)
|
||
setVideoID(window.electron.getVideoId())
|
||
} else {
|
||
message.error('请选择应用!')
|
||
}
|
||
}
|
||
}
|
||
|
||
const getDesktopCapturerVideo = (): void => {
|
||
window.electron.getDesktopCapturerVideo().then((res: any) => {
|
||
if (sharedScreenList.length !== res.length) {
|
||
res.forEach((item: any) => {
|
||
if (item.thumbImage.buffer) {
|
||
item.thumbnailUrl = thumbImageBufferToBase64(item.thumbImage)
|
||
}
|
||
if (item.iconImage.buffer) {
|
||
item.iconDataUrl = thumbImageBufferToBase64(item.iconImage)
|
||
}
|
||
})
|
||
setSharedScreenList(res)
|
||
}
|
||
})
|
||
};
|
||
|
||
const getAudioMediaList = (): void => {
|
||
const { currentDevices, currentDevice, currentVolume } = window.electron.getAudioMediaList();
|
||
setAudioDeviceManager({
|
||
currentDevices: currentDevices.map((row: any) => {
|
||
return {
|
||
value: row.deviceId,
|
||
label: row.deviceName
|
||
}
|
||
}),
|
||
currentDevice: currentDevice.deviceId,
|
||
currentVolume,
|
||
})
|
||
}
|
||
|
||
const getRoomFile = async (): Promise<void> => {
|
||
await GetRoomFile({
|
||
pageIndex: fileList.pageIndex,
|
||
pageSize: fileList.pageSize,
|
||
keyword: fileList.keyword,
|
||
roomId: state.channelId
|
||
}).then(res => {
|
||
if (res.code === 200) {
|
||
setFileList({
|
||
...fileList,
|
||
data: res.data.items.map((item: any) => {
|
||
return {
|
||
...item,
|
||
key: item.id,
|
||
}
|
||
}),
|
||
total: res.data.total
|
||
})
|
||
}
|
||
})
|
||
}
|
||
|
||
return (
|
||
<>
|
||
<div className={styles.meeting}>
|
||
<div className={styles.meetingHeader}>
|
||
<div>
|
||
<div>
|
||
<span></span>
|
||
<span></span>
|
||
<span></span>
|
||
<span></span>
|
||
</div>
|
||
<div>00:13:45</div>
|
||
</div>
|
||
<div>会议号:2323235</div>
|
||
<div className='drag'>
|
||
<div className={styles.meetingGrayButton}>演讲者模式</div>
|
||
<Operation></Operation>
|
||
</div>
|
||
</div>
|
||
<div className={styles.meetingContent}>
|
||
<div className={styles.meetingContentBody}>
|
||
<div className={styles.meetingContentBodyLeft}>
|
||
<div className={`${styles.meetingContentSwiper} drag`}>
|
||
<Swiper
|
||
loop={false}
|
||
centeredSlides={true}
|
||
modules={[Navigation, Pagination]}
|
||
spaceBetween={20}
|
||
slidesPerView={6}
|
||
navigation
|
||
pagination={false}
|
||
scrollbar={{ draggable: true }}
|
||
onSwiper={(swiper: any) => {
|
||
swiper.on('click', (e: any) => {
|
||
swiper.slideTo(e.clickedIndex)
|
||
})
|
||
}}
|
||
onSlideChange={() => { }}
|
||
>
|
||
{list.map((item, index) =>
|
||
<SwiperSlide key={item}>
|
||
<div className={styles.meetingContentSwiperCard}>
|
||
<div className={styles.meetingContentSwiperCardVdeio} id={`video-${index}`}></div>
|
||
{meetingContentUser()}
|
||
</div>
|
||
</SwiperSlide>
|
||
)}
|
||
</Swiper>
|
||
</div>
|
||
<div className={`${styles.meetingContentVideo} drag`}>
|
||
<div className={styles.meetingContentVideoDom}></div>
|
||
{meetingContentUser()}
|
||
</div>
|
||
</div>
|
||
{
|
||
(statusList.userList || statusList.userChatList) ? (
|
||
<div className={styles.meetingContentBodyRight}>
|
||
{statusList.userList ?
|
||
<div className={styles.meetingUserList}>
|
||
<div className={styles.meetingUserListTitle}>
|
||
<span>成员列表</span>
|
||
<img src="/src/assets/icon18.png" alt="" className='drag' onClick={() => {
|
||
setStatusList({
|
||
userList: false,
|
||
userChatList: false,
|
||
})
|
||
}} />
|
||
</div>
|
||
<Input placeholder="请输入用户名" className='drag' prefix={<SearchOutlined style={{ color: 'white' }} />} />
|
||
<div className={styles.meetingUserListContent}>
|
||
{list.map((item: number) =>
|
||
<div key={item} className='drag'>
|
||
<div>
|
||
<div><img src="/src/assets/avatar.png" alt="" /></div>
|
||
<span>潇潇<span style={{ color: '#02B188', marginLeft: '4px' }}>主持人</span></span>
|
||
</div>
|
||
<div>
|
||
<img src="/src/assets/icon22.png" alt="" />
|
||
<img src="/src/assets/icon23.png" alt="" />
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
<div className={`${styles.meetingUserListFooter} drag`}>
|
||
<div>邀请</div>
|
||
<div>全员静音</div>
|
||
</div>
|
||
</div>
|
||
:
|
||
<div className={styles.meetingUserChat}>
|
||
<div className={styles.meetingUserChatTitle}>
|
||
<span>聊天</span>
|
||
<img src="/src/assets/icon18.png" alt="" className='drag' onClick={() => {
|
||
setStatusList({
|
||
userList: false,
|
||
userChatList: false,
|
||
})
|
||
}} />
|
||
</div>
|
||
<div className={styles.meetingUserChatContent}>
|
||
{list.map((item: number) =>
|
||
<div key={item} className={`${styles.meetingUserChatContentLeft} drag`}>
|
||
<div>
|
||
<div><img src="/src/assets/avatar.png" alt="" /></div>
|
||
<span>潇潇</span>
|
||
</div>
|
||
<div>哈哈哈哈</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
<div className={`${styles.meetingUserChatInput} drag`}>
|
||
<Input.TextArea placeholder="请输入消息" style={{ flexGrow: 1 }}></Input.TextArea>
|
||
<Button type="primary" className='m-ant-btn' style={{ flexShrink: 0, marginTop: '4px' }}>发送</Button>
|
||
</div>
|
||
</div>
|
||
}
|
||
</div>
|
||
) : null
|
||
}
|
||
</div>
|
||
<div className={styles.meetingContentFooter}>
|
||
{footerList.map((item, itemIndex) => {
|
||
return (
|
||
<div key={itemIndex}>
|
||
{item.map((row, rowIndex) => {
|
||
return (
|
||
row.title === '结束' ?
|
||
<Popover key={rowIndex}
|
||
content={
|
||
<div className='meetingContentFooterPopover'>
|
||
<div onClick={() => {
|
||
window.electron.leaveChannel()
|
||
window.electron.stopScreenCapture()
|
||
navigate(-1)
|
||
}}>全员结束会议</div>
|
||
<div onClick={() => {
|
||
window.electron.leaveChannel()
|
||
window.electron.stopScreenCapture()
|
||
navigate(-1)
|
||
}}>仅自己离开</div>
|
||
<div onClick={() => { setOpen(false) }}>取消</div>
|
||
</div>
|
||
}
|
||
title=""
|
||
trigger="click"
|
||
open={open}
|
||
onOpenChange={() => setOpen(true)}
|
||
>
|
||
<div className='drag'>
|
||
<img src={row.active ? row.icon + '-active.png' : row.icon + '.png'} alt="" />
|
||
<span>{row.title}</span>
|
||
</div>
|
||
</Popover> :
|
||
<div className='drag' onClick={() => changeStatusList(row, itemIndex, rowIndex)} key={rowIndex}>
|
||
<img src={row.active ? row.icon + '-active.png' : row.icon + '.png'} alt="" />
|
||
<span>{row.title}</span>
|
||
</div>
|
||
)
|
||
})}
|
||
</div>
|
||
)
|
||
})}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<Modal title="共享屏幕" open={isSharedScreenModal} footer={null} closable={false} centered width={'40vw'}>
|
||
<div className={styles.sharedScreenModal}>
|
||
<div>
|
||
{sharedScreenList.map((item: any, index: number) => {
|
||
return (
|
||
<div
|
||
className={sharedScreenItem.sourceId === item.sourceId ? styles.active : ''}
|
||
key={index}
|
||
onClick={() => {
|
||
setSharedScreenItem(item)
|
||
}}>
|
||
{item.iconDataUrl ? <img src={item.iconDataUrl} alt="" /> : ''}
|
||
<div><img src={item.thumbnailUrl} alt="" /></div>
|
||
<span>{item.sourceTitle}</span>
|
||
</div>
|
||
)
|
||
})}
|
||
</div>
|
||
<div>
|
||
<Checkbox onChange={() => {
|
||
|
||
}}>共享电脑音频</Checkbox>
|
||
<div>
|
||
<Button type="primary" onClick={() => { setIsSharedScreenModal(false) }} style={{ backgroundColor: '#31353A', marginRight: '14px' }}>取消</Button>
|
||
<Button type="primary" className='m-ant-btn' onClick={() => changeVdeio(false)}>共享</Button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</Modal>
|
||
<Modal title="设置向导" open={isStupWizard} footer={null} closable={false} centered width={'40vw'}>
|
||
<div className={styles.stupWizard}>
|
||
<div>
|
||
<div>{stepsStatus ? '音频设置向导' : '视频测试'}</div>
|
||
<div>
|
||
<div>
|
||
<span>音频输出设备:</span>
|
||
<Select
|
||
options={audioDeviceManager.currentDevices} style={{ flexGrow: 1 }}
|
||
value={audioDeviceManager.currentDevice} onChange={(e) => {
|
||
setAudioDeviceManager({
|
||
...audioDeviceManager,
|
||
currentDevice: e
|
||
})
|
||
window.electron.setRecordingDevice(e);
|
||
getAudioMediaList()
|
||
}} />;
|
||
<audio src="" id='startAudio'></audio>
|
||
</div>
|
||
{stepsStatus ? <div>
|
||
<span>调节声音大小:</span>
|
||
<Slider min={0} max={255} value={audioDeviceManager.currentVolume} onChange={(e) => {
|
||
setAudioDeviceManager({
|
||
...audioDeviceManager,
|
||
currentVolume: e
|
||
})
|
||
window.electron.setRecordingDeviceVolume(e)
|
||
}} style={{ flexGrow: 1 }} />
|
||
</div> :
|
||
<div>
|
||
<span>视频预览:</span>
|
||
<video id='startPreview'
|
||
poster={'/src/assets/error.png'}
|
||
style={{ width: '226px', height: '136px', backgroundColor: 'black' }}>
|
||
</video>
|
||
</div>
|
||
}
|
||
</div>
|
||
{stepsStatus ? <div>
|
||
<span>您可以对着麦克风说话,试听表克风的输入质量</span>
|
||
<div>
|
||
<img src="/src/assets/icon33.png" alt="" />
|
||
<div>
|
||
<img src="/src/assets/icon34.png" alt="" />
|
||
<div id='recordingDeviceTest'>
|
||
<img src="/src/assets/icon35.png" alt="" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div> : null}
|
||
</div>
|
||
<div>
|
||
{stepsStatus ? <div>
|
||
<Button type="primary" className='m-ant-btn' onClick={() => {
|
||
let audio = document.getElementById('startAudio') as any;
|
||
if (audio.srcObject) {
|
||
const tracks = audio.srcObject.getTracks();
|
||
tracks.forEach((track: any) => {
|
||
track.stop();
|
||
});
|
||
audio.srcObject = null;
|
||
}
|
||
setStepsStatus(false)
|
||
window.electron.startPreview().then((res: boolean) => {
|
||
setIsVideoLoad(res)
|
||
})
|
||
}}>下一步</Button>
|
||
</div> :
|
||
<div>
|
||
<Button
|
||
type="primary"
|
||
style={{ backgroundColor: '#31353A', marginRight: '14px' }}
|
||
onClick={() => {
|
||
if (isVideoLoad) {
|
||
setIsVideoLoad(false)
|
||
window.electron.stopAudioDeviceLoopbackTest()
|
||
setStepsStatus(true)
|
||
window.electron.startRecordingDeviceTest(200)
|
||
} else {
|
||
message.error('视频加载中!')
|
||
}
|
||
}}
|
||
>上一步</Button>
|
||
<Button
|
||
type="primary"
|
||
className='m-ant-btn'
|
||
onClick={() => {
|
||
if (isVideoLoad) {
|
||
window.electron.stopAudioDeviceLoopbackTest()
|
||
window.electron.setRecordingDeviceVolume(audioDeviceManager.currentVolume)
|
||
setIsStupWizard(false)
|
||
setStepsStatus(true)
|
||
setIsVideoLoad(false)
|
||
} else {
|
||
message.error('视频加载中!')
|
||
}
|
||
}}
|
||
>完成
|
||
</Button>
|
||
</div>}
|
||
</div>
|
||
</div>
|
||
</Modal>
|
||
<Modal
|
||
title="共享文件"
|
||
open={isSharedFilesModel}
|
||
footer={null}
|
||
centered
|
||
width={'60vw'}
|
||
onCancel={() => setIsSharedFilesModel(false)}
|
||
maskClosable
|
||
>
|
||
<div>
|
||
<div className={styles.sharedFilesModel}>
|
||
<div>
|
||
<span>共{fileList.total}个文件</span>
|
||
<div style={{ color: 'white' }}>
|
||
<Input
|
||
placeholder="搜索"
|
||
style={{ width: '200px' }}
|
||
prefix={<SearchOutlined style={{ color: 'white' }} />}
|
||
onChange={(e) => {
|
||
setFileList({
|
||
...fileList,
|
||
keyword: e.target.value
|
||
})
|
||
}}
|
||
onBlur={() => {
|
||
if (fileList.pageIndex === 1) {
|
||
getRoomFile()
|
||
} else {
|
||
setFileList({
|
||
...fileList,
|
||
pageIndex: 1
|
||
})
|
||
}
|
||
}}
|
||
/>
|
||
<ReloadOutlined title='刷新' onClick={() => {
|
||
if (fileList.pageIndex === 1) {
|
||
getRoomFile()
|
||
} else {
|
||
setFileList({
|
||
...fileList,
|
||
pageIndex: 1
|
||
})
|
||
}
|
||
}} />
|
||
<ProfileOutlined title={showRowSelection ? '取消框选' : '显示框选'} onClick={() => {
|
||
setShowRowSelection(!showRowSelection)
|
||
}} style={{ color: showRowSelection ? '#5575F2' : 'white' }} />
|
||
{showRowSelection ? <DeleteOutlined title='删除' onClick={() => {
|
||
if (selectedRowKeys.length) {
|
||
DeleteRoomFile(selectedRowKeys).then(res => {
|
||
if (res.code === 200) {
|
||
message.success('删除成功!')
|
||
getRoomFile()
|
||
}
|
||
})
|
||
} else {
|
||
message.error('请选择文件!')
|
||
}
|
||
}} /> : null}
|
||
<Button type="primary" style={{ backgroundColor: '#31353A' }}
|
||
onClick={() => {
|
||
const file = document.createElement("input") as any;
|
||
file.type = "file";
|
||
file.onchange = async () => {
|
||
const fileInfo = file.files[0];
|
||
const fileType = fileInfo.name.split('.');
|
||
const fileTypeName = fileType[fileType.length - 1];
|
||
await GetRoomUpFileurl(state.channelId, fileTypeName).then(async res => {
|
||
const formData = new FormData();
|
||
formData.append("name", fileInfo.name);
|
||
formData.append("OSSAccessKeyId", res.data.ossAccessKeyId);
|
||
formData.append("key", res.data.key);
|
||
formData.append("policy", res.data.policy);
|
||
formData.append("signature", res.data.signature);
|
||
formData.append("success_action_status", res.data.success_action_status);
|
||
formData.append("file", fileInfo);
|
||
await axios.post(res.data.host, formData, {
|
||
headers: {
|
||
"Content-Type": "multipart/form-data",
|
||
"Authorization": `Bearer ${user.token}`
|
||
},
|
||
withCredentials: false
|
||
})
|
||
await PostRoomFile({
|
||
fileUrl: res.data.key,
|
||
size: fileInfo.size,
|
||
fileName: fileInfo.name,
|
||
roomId: state.channelId
|
||
})
|
||
getRoomFile()
|
||
})
|
||
};
|
||
file.click();
|
||
}}
|
||
>上传</Button>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<Table
|
||
size={'small'}
|
||
rowSelection={showRowSelection ? {
|
||
selectedRowKeys,
|
||
onChange: (newSelectedRowKeys: React.Key[]) => {
|
||
setSelectedRowKeys(newSelectedRowKeys);
|
||
}
|
||
} : undefined}
|
||
dataSource={fileList.data}
|
||
pagination={false}
|
||
scroll={{ y: '40vh' }}
|
||
style={{ width: '100%' }}
|
||
>
|
||
<Column title="文件" dataIndex="fileName" key="fileName" width={140} />
|
||
<Column title="更新时间" dataIndex="modifyTime" key="modifyTime" width={200} />
|
||
<Column title="大小" render={(item) => (
|
||
<>
|
||
<span>{item.size / 1024 > 1000 ? (item.size / (1024 * 1024)).toFixed(2) + 'MB' : (item.size / 1024).toFixed(2) + 'KB'}</span>
|
||
</>
|
||
)} />
|
||
<Column title="上传者" dataIndex="userName" key="userName" />
|
||
<Column title="下载次数"
|
||
render={(item) => (
|
||
<>
|
||
<span>{item.downloadCount}次</span>
|
||
</>
|
||
)}
|
||
/>
|
||
<Column title="操作" render={(item) => (
|
||
<>
|
||
<VerticalAlignBottomOutlined title='下载' style={{ color: '#5575F2', cursor: 'pointer' }} onClick={() => {
|
||
GetRoomFileDwUrl(item.fileUrl).then(res => {
|
||
if (res.code === 200) {
|
||
window.electron.dwFile(res.data)
|
||
}
|
||
})
|
||
}} />
|
||
{/* <FolderOutlined title='文件' style={{ color: '#FFA000', cursor: 'pointer' }} /> */}
|
||
</>
|
||
)} />
|
||
</Table>
|
||
<div style={{ display: 'flex', justifyContent: 'center', marginTop: '10px' }}>
|
||
<AntdPagination size="small" total={fileList.total} onChange={(e) => {
|
||
setFileList({
|
||
...fileList,
|
||
pageIndex: e
|
||
})
|
||
}} pageSize={fileList.pageSize} current={fileList.pageIndex} hideOnSinglePage={true} />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end' }}>
|
||
|
||
</div>
|
||
</div>
|
||
</Modal>
|
||
</>
|
||
)
|
||
}
|
||
|
||
const meetingContentUser = () => {
|
||
return (
|
||
<>
|
||
<div className={styles.meetingContentUser}>
|
||
<div className={styles.meetingContentUserRole}>
|
||
<img src="/src/assets/icon32.png" alt="" />
|
||
</div>
|
||
<div className={styles.meetingContentUserName}>
|
||
<img src="/src/assets/icon22.png" alt="" />
|
||
<span>张大龙</span>
|
||
</div>
|
||
</div>
|
||
</>
|
||
)
|
||
}
|
||
|
||
export default Meeting
|