共享文件单独提出
This commit is contained in:
parent
0de1122908
commit
7d0b53cf3e
|
|
@ -0,0 +1,27 @@
|
||||||
|
.sharedFilesModel {
|
||||||
|
>div:nth-child(1) {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
>span {
|
||||||
|
color: #EEEEEE;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
>div {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
>span {
|
||||||
|
margin-right: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
>div:nth-child(2) {
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,239 @@
|
||||||
|
import styles from '@/components/SharedFilesModel/index.module.scss'
|
||||||
|
import { DeleteOutlined, ProfileOutlined, ReloadOutlined, SearchOutlined, VerticalAlignBottomOutlined } from '@ant-design/icons';
|
||||||
|
import { Button, Input, Modal, Pagination, Table, message } from 'antd';
|
||||||
|
import { useState, useImperativeHandle, forwardRef, useEffect } from "react";
|
||||||
|
import { PostRoomFile, DeleteRoomFile, GetRoomUpFileurl, GetRoomFileDwUrl, GetRoomFile } from '@/api/Meeting';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { useLocation } from 'react-router-dom';
|
||||||
|
import { storage } from '@/utils';
|
||||||
|
const { Column } = Table
|
||||||
|
|
||||||
|
const SharedFilesModel = forwardRef((props: any, ref: any) => {
|
||||||
|
useImperativeHandle(ref, () => ({
|
||||||
|
getData: () => {
|
||||||
|
setIsSharedFilesModel(true)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
const { state } = useLocation();
|
||||||
|
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
|
||||||
|
const [showRowSelection, setShowRowSelection] = useState(false);
|
||||||
|
const [isSharedFilesModel, setIsSharedFilesModel] = useState(false);
|
||||||
|
const [user, setUser] = useState<any>({});
|
||||||
|
const [fileList, setFileList] = useState({
|
||||||
|
data: [],
|
||||||
|
keyword: '',
|
||||||
|
total: 0,
|
||||||
|
pageIndex: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
})
|
||||||
|
useEffect(() => {
|
||||||
|
let userInfo = JSON.parse(storage.getItem('user') as string)
|
||||||
|
setUser(userInfo)
|
||||||
|
getRoomFile()
|
||||||
|
}, [fileList.pageIndex]);
|
||||||
|
// 获取共享文件列表
|
||||||
|
const getRoomFile = async (): Promise<void> => {
|
||||||
|
await GetRoomFile({
|
||||||
|
pageIndex: fileList.pageIndex,
|
||||||
|
pageSize: fileList.pageSize,
|
||||||
|
keyword: fileList.keyword,
|
||||||
|
roomId: state.roomId
|
||||||
|
}).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 (
|
||||||
|
<>
|
||||||
|
<Modal
|
||||||
|
title="共享文件"
|
||||||
|
open={isSharedFilesModel}
|
||||||
|
footer={null}
|
||||||
|
centered
|
||||||
|
width={'800px'}
|
||||||
|
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
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
onPressEnter={() => {
|
||||||
|
if (fileList.pageIndex === 1) {
|
||||||
|
getRoomFile()
|
||||||
|
} else {
|
||||||
|
setFileList({
|
||||||
|
...fileList,
|
||||||
|
pageIndex: 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
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.accept = "image/*,.doc,.docx,.ppt,.pptx,.xls,.xlsx,application/pdf";
|
||||||
|
file.type = "file";
|
||||||
|
file.onchange = async () => {
|
||||||
|
const fileInfo = file.files[0];
|
||||||
|
const maxSize = 100 * 1024 * 1024; // 100MB in bytes
|
||||||
|
|
||||||
|
if (fileInfo.size > maxSize) {
|
||||||
|
message.error('文件太大!请上传小于100MB的文件。')
|
||||||
|
// 清除文件输入框的值,以便用户可以选择其他文件
|
||||||
|
return
|
||||||
|
}
|
||||||
|
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.roomId
|
||||||
|
})
|
||||||
|
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, item.id).then(res => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
const downloadLink = document.createElement("a");
|
||||||
|
downloadLink.href = res.data;
|
||||||
|
downloadLink.download = item.fileName;
|
||||||
|
downloadLink.click();
|
||||||
|
getRoomFile()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}} />
|
||||||
|
{/* <FolderOutlined title='文件' style={{ color: '#FFA000', cursor: 'pointer' }} /> */}
|
||||||
|
</>
|
||||||
|
)} />
|
||||||
|
</Table>
|
||||||
|
<div style={{ display: 'flex', justifyContent: 'center', marginTop: '10px' }}>
|
||||||
|
<Pagination 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>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
export default SharedFilesModel
|
||||||
|
|
@ -706,33 +706,4 @@
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 共享文件
|
|
||||||
.sharedFilesModel {
|
|
||||||
>div:nth-child(1) {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
>span {
|
|
||||||
color: #EEEEEE;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
>div {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
>span {
|
|
||||||
margin-right: 20px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
>div:nth-child(2) {
|
|
||||||
margin: 20px 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -3,13 +3,12 @@ import { useEffect, useRef, useState } from "react";
|
||||||
import Operation from '@/components/Operation';
|
import Operation from '@/components/Operation';
|
||||||
import SpeakerModeModal from '@/components/SpeakerModeModal';
|
import SpeakerModeModal from '@/components/SpeakerModeModal';
|
||||||
import InvitingPersonnelModal from '@/components/InvitingPersonnelModal';
|
import InvitingPersonnelModal from '@/components/InvitingPersonnelModal';
|
||||||
import { Button, Input, Popover, Modal, Checkbox, message, Table, Pagination } from "antd";
|
import { Button, Input, Popover, Modal, Checkbox, message } from "antd";
|
||||||
import { DeleteOutlined, ProfileOutlined, ReloadOutlined, SearchOutlined, VerticalAlignBottomOutlined } from '@ant-design/icons';
|
import { SearchOutlined } from '@ant-design/icons';
|
||||||
import { useLocation, useNavigate } from 'react-router-dom';
|
import { useLocation, useNavigate } from 'react-router-dom';
|
||||||
import { thumbImageBufferToBase64 } from '@/utils/package/base64'
|
import { thumbImageBufferToBase64 } from '@/utils/package/base64'
|
||||||
import { storage } from '@/utils';
|
import { storage } from '@/utils';
|
||||||
import { GetRoomFile, PostRoomFile, DeleteRoomFile, GetRoomUpFileurl, GetRoomFileDwUrl, GetRoomUser, PostOpenMicr, PostOpenCamera, PostRoomManager, DeleteRoomManager, GetRoomKickout } from '@/api/Meeting';
|
import { GetRoomUser, PostOpenMicr, PostOpenCamera, PostRoomManager, DeleteRoomManager, GetRoomKickout } from '@/api/Meeting';
|
||||||
import axios from 'axios';
|
|
||||||
import ImageUrl from '@/utils/package/ImageUrl'
|
import ImageUrl from '@/utils/package/ImageUrl'
|
||||||
import agora from '@/utils/package/agora'
|
import agora from '@/utils/package/agora'
|
||||||
import { onInvoke, onSignalr, offSignalr, onStart } from '@/utils/package/signalr';
|
import { onInvoke, onSignalr, offSignalr, onStart } from '@/utils/package/signalr';
|
||||||
|
|
@ -18,23 +17,20 @@ import durationPlugin from 'dayjs/plugin/duration';
|
||||||
import { VideoSourceType } from 'agora-electron-sdk';
|
import { VideoSourceType } from 'agora-electron-sdk';
|
||||||
import { GetUserList } from '@/api/Home/User';
|
import { GetUserList } from '@/api/Home/User';
|
||||||
import Avatar from '@/components/Avatar';
|
import Avatar from '@/components/Avatar';
|
||||||
|
import SharedFilesModel from '@/components/SharedFilesModel';
|
||||||
dayjs.extend(durationPlugin);
|
dayjs.extend(durationPlugin);
|
||||||
const { Column } = Table
|
|
||||||
const Meeting: React.FC = () => {
|
const Meeting: React.FC = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { state } = useLocation();
|
const { state } = useLocation();
|
||||||
const speakerModeModalRef = useRef<any>();
|
const speakerModeModalRef = useRef<any>();
|
||||||
|
const sharedFilesModelRef = useRef<any>();
|
||||||
const invitingPersonnelRef = useRef<any>();
|
const invitingPersonnelRef = useRef<any>();
|
||||||
const [statusList, setStatusList] = useState({
|
const [statusList, setStatusList] = useState({
|
||||||
userList: false,
|
userList: false,
|
||||||
userChatList: false,
|
userChatList: false,
|
||||||
})
|
})
|
||||||
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
|
|
||||||
const [isSharedScreenModal, setIsSharedScreenModal] = useState(false);
|
const [isSharedScreenModal, setIsSharedScreenModal] = useState(false);
|
||||||
const [isInit, setIsInit] = useState(true);
|
|
||||||
const [user, setUser] = useState<any>({});
|
const [user, setUser] = useState<any>({});
|
||||||
const [showRowSelection, setShowRowSelection] = useState(false);
|
|
||||||
const [isSharedFilesModel, setIsSharedFilesModel] = useState(false);
|
|
||||||
const [sharedScreenList, setSharedScreenList] = useState<any>([]);
|
const [sharedScreenList, setSharedScreenList] = useState<any>([]);
|
||||||
const [sharedScreenItem, setSharedScreenItem] = useState<any>('');
|
const [sharedScreenItem, setSharedScreenItem] = useState<any>('');
|
||||||
const [textMsg, setTextMsg] = useState('');
|
const [textMsg, setTextMsg] = useState('');
|
||||||
|
|
@ -103,13 +99,6 @@ const Meeting: React.FC = () => {
|
||||||
itemIndex: 0,
|
itemIndex: 0,
|
||||||
rowIndex: 0,
|
rowIndex: 0,
|
||||||
});
|
});
|
||||||
const [fileList, setFileList] = useState({
|
|
||||||
data: [],
|
|
||||||
keyword: '',
|
|
||||||
total: 0,
|
|
||||||
pageIndex: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
})
|
|
||||||
const [roomUserList, setRoomUserList] = useState<any>([])
|
const [roomUserList, setRoomUserList] = useState<any>([])
|
||||||
const [allUserList, setAllUserList] = useState<any>([])
|
const [allUserList, setAllUserList] = useState<any>([])
|
||||||
const [chatList, setChatList] = useState<any>([])
|
const [chatList, setChatList] = useState<any>([])
|
||||||
|
|
@ -122,73 +111,69 @@ const Meeting: React.FC = () => {
|
||||||
const [noViewChatList, setNoViewChatList] = useState(0)
|
const [noViewChatList, setNoViewChatList] = useState(0)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let time = null as any;
|
let time = null as any;
|
||||||
if (isInit) {
|
let userInfo = JSON.parse(storage.getItem('user') as string)
|
||||||
let userInfo = JSON.parse(storage.getItem('user') as string)
|
setUser(userInfo)
|
||||||
setMeetingMode('StandardMode');
|
setMeetingMode('StandardMode');
|
||||||
agora.init()
|
agora.init()
|
||||||
agora.registerEventHandler({
|
agora.registerEventHandler({
|
||||||
onJoinChannelSuccess: async (info: any, _elapsed: any) => {
|
onJoinChannelSuccess: async (info: any, _elapsed: any) => {
|
||||||
await onInvoke('joinChannel', {
|
await onInvoke('joinChannel', {
|
||||||
roomNum: info.channelId,
|
roomNum: info.channelId,
|
||||||
enableMicr: true,
|
enableMicr: true,
|
||||||
enableCamera: true
|
enableCamera: true
|
||||||
|
})
|
||||||
|
await getRoomUser()
|
||||||
|
setTimeout(() => {
|
||||||
|
agora.setupLocalVideo({
|
||||||
|
account: Number(info.localUid),
|
||||||
|
view: document.getElementById(`video-${info.localUid}`) as HTMLElement,
|
||||||
|
channelId: info.channelId,
|
||||||
})
|
})
|
||||||
await getRoomUser()
|
}, 1000);
|
||||||
setTimeout(() => {
|
},
|
||||||
agora.setupLocalVideo({
|
onUserJoined: async (info: any, remoteUid: any, _elapsed: any) => {
|
||||||
account: Number(info.localUid),
|
await getRoomUser()
|
||||||
view: document.getElementById(`video-${info.localUid}`) as HTMLElement,
|
setTimeout(() => {
|
||||||
channelId: info.channelId,
|
agora.setupRemoteVideoJoin({
|
||||||
})
|
|
||||||
}, 1000);
|
|
||||||
},
|
|
||||||
onUserJoined: async (info: any, remoteUid: any, _elapsed: any) => {
|
|
||||||
await getRoomUser()
|
|
||||||
setTimeout(() => {
|
|
||||||
agora.setupRemoteVideoJoin({
|
|
||||||
account: Number(remoteUid),
|
|
||||||
view: document.getElementById(`video-${remoteUid}`) as HTMLElement,
|
|
||||||
channelId: info.channelId,
|
|
||||||
})
|
|
||||||
}, 1000);
|
|
||||||
},
|
|
||||||
onUserOffline: async (info: any, remoteUid: any, _reason: any) => {
|
|
||||||
await agora.setupRemoteVideo({
|
|
||||||
account: Number(remoteUid),
|
account: Number(remoteUid),
|
||||||
view: document.getElementById(`video-${remoteUid}`) as HTMLElement,
|
view: document.getElementById(`video-${remoteUid}`) as HTMLElement,
|
||||||
channelId: info.channelId,
|
channelId: info.channelId,
|
||||||
})
|
})
|
||||||
setTimeout(() => {
|
}, 1000);
|
||||||
getRoomUser()
|
},
|
||||||
}, 1000);
|
onUserOffline: async (info: any, remoteUid: any, _reason: any) => {
|
||||||
}
|
await agora.setupRemoteVideo({
|
||||||
})
|
account: Number(remoteUid),
|
||||||
agora.setCameraCapture(VideoSourceType.VideoSourceCameraPrimary)
|
view: document.getElementById(`video-${remoteUid}`) as HTMLElement,
|
||||||
agora.setJoinChannel({
|
channelId: info.channelId,
|
||||||
channelId: state.channelId,
|
})
|
||||||
userid: userInfo.account,
|
setTimeout(() => {
|
||||||
token: state.token,
|
getRoomUser()
|
||||||
})
|
}, 1000);
|
||||||
setCurrentVideoId(userInfo.account)
|
}
|
||||||
setUser(userInfo)
|
})
|
||||||
setIsInit(false)
|
agora.setCameraCapture(VideoSourceType.VideoSourceCameraPrimary)
|
||||||
storage.setItem('noViewChatList', 0)
|
agora.setJoinChannel({
|
||||||
window.addEventListener('customStorageChange', handleCustomStorageChange);
|
channelId: state.channelId,
|
||||||
window.addEventListener('online', handleNetworkChange);
|
userid: userInfo.account,
|
||||||
window.addEventListener('offline', handleNetworkChange);
|
token: state.token,
|
||||||
time = setInterval(() => {
|
})
|
||||||
setCurrentSeconds(currentSeconds++)
|
setCurrentVideoId(userInfo.account)
|
||||||
}, 1000)
|
storage.setItem('noViewChatList', 0)
|
||||||
} else {
|
window.addEventListener('customStorageChange', handleCustomStorageChange);
|
||||||
getRoomFile()
|
window.addEventListener('online', handleNetworkChange);
|
||||||
}
|
window.addEventListener('offline', handleNetworkChange);
|
||||||
|
time = setInterval(() => {
|
||||||
|
setCurrentSeconds(currentSeconds++)
|
||||||
|
}, 1000)
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener('customStorageChange', handleCustomStorageChange);
|
window.removeEventListener('customStorageChange', handleCustomStorageChange);
|
||||||
window.removeEventListener('online', handleNetworkChange);
|
window.removeEventListener('online', handleNetworkChange);
|
||||||
window.removeEventListener('offline', handleNetworkChange);
|
window.removeEventListener('offline', handleNetworkChange);
|
||||||
clearInterval(time)
|
clearInterval(time)
|
||||||
};
|
};
|
||||||
}, [fileList.pageIndex]);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
roomUserList.forEach((item: any) => {
|
roomUserList.forEach((item: any) => {
|
||||||
|
|
@ -364,8 +349,7 @@ const Meeting: React.FC = () => {
|
||||||
agora.stopRecording()
|
agora.stopRecording()
|
||||||
break;
|
break;
|
||||||
case '共享文件':
|
case '共享文件':
|
||||||
await getRoomFile()
|
sharedFilesModelRef.current.getData()
|
||||||
setIsSharedFilesModel(true)
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -407,28 +391,7 @@ const Meeting: React.FC = () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
// 获取共享文件列表
|
|
||||||
const getRoomFile = async (): Promise<void> => {
|
|
||||||
await GetRoomFile({
|
|
||||||
pageIndex: fileList.pageIndex,
|
|
||||||
pageSize: fileList.pageSize,
|
|
||||||
keyword: fileList.keyword,
|
|
||||||
roomId: state.roomId
|
|
||||||
}).then(res => {
|
|
||||||
if (res.code === 200) {
|
|
||||||
setFileList({
|
|
||||||
...fileList,
|
|
||||||
data: res.data.items.map((item: any) => {
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
key: item.id,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
total: res.data.total
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 获取房间用户
|
// 获取房间用户
|
||||||
const getRoomUser = async (): Promise<void> => {
|
const getRoomUser = async (): Promise<void> => {
|
||||||
Promise.all([
|
Promise.all([
|
||||||
|
|
@ -848,183 +811,7 @@ const Meeting: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
<Modal
|
<SharedFilesModel ref={sharedFilesModelRef} />
|
||||||
title="共享文件"
|
|
||||||
open={isSharedFilesModel}
|
|
||||||
footer={null}
|
|
||||||
centered
|
|
||||||
width={'800px'}
|
|
||||||
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
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
onPressEnter={() => {
|
|
||||||
if (fileList.pageIndex === 1) {
|
|
||||||
getRoomFile()
|
|
||||||
} else {
|
|
||||||
setFileList({
|
|
||||||
...fileList,
|
|
||||||
pageIndex: 1
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
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.accept = "image/*,.doc,.docx,.ppt,.pptx,.xls,.xlsx,application/pdf";
|
|
||||||
file.type = "file";
|
|
||||||
file.onchange = async () => {
|
|
||||||
const fileInfo = file.files[0];
|
|
||||||
const maxSize = 100 * 1024 * 1024; // 100MB in bytes
|
|
||||||
|
|
||||||
if (fileInfo.size > maxSize) {
|
|
||||||
message.error('文件太大!请上传小于100MB的文件。')
|
|
||||||
// 清除文件输入框的值,以便用户可以选择其他文件
|
|
||||||
return
|
|
||||||
}
|
|
||||||
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.roomId
|
|
||||||
})
|
|
||||||
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, item.id).then(res => {
|
|
||||||
if (res.code === 200) {
|
|
||||||
const downloadLink = document.createElement("a");
|
|
||||||
downloadLink.href = res.data;
|
|
||||||
downloadLink.download = item.fileName;
|
|
||||||
downloadLink.click();
|
|
||||||
getRoomFile()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}} />
|
|
||||||
{/* <FolderOutlined title='文件' style={{ color: '#FFA000', cursor: 'pointer' }} /> */}
|
|
||||||
</>
|
|
||||||
)} />
|
|
||||||
</Table>
|
|
||||||
<div style={{ display: 'flex', justifyContent: 'center', marginTop: '10px' }}>
|
|
||||||
<Pagination 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>
|
|
||||||
<SpeakerModeModal ref={speakerModeModalRef} />
|
<SpeakerModeModal ref={speakerModeModalRef} />
|
||||||
<InvitingPersonnelModal ref={invitingPersonnelRef} />
|
<InvitingPersonnelModal ref={invitingPersonnelRef} />
|
||||||
</>
|
</>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue