From 7d0b53cf3e771b9b13f956f3ec63d3373c9bef74 Mon Sep 17 00:00:00 2001 From: yj <1336058017@qq.com> Date: Fri, 26 Jul 2024 13:56:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=B1=E4=BA=AB=E6=96=87=E4=BB=B6=E5=8D=95?= =?UTF-8?q?=E7=8B=AC=E6=8F=90=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SharedFilesModel/index.module.scss | 27 ++ src/components/SharedFilesModel/index.tsx | 239 +++++++++++++ src/page/Meeting/index.module.scss | 29 -- src/page/Meeting/index.tsx | 333 ++++-------------- 4 files changed, 326 insertions(+), 302 deletions(-) create mode 100644 src/components/SharedFilesModel/index.module.scss create mode 100644 src/components/SharedFilesModel/index.tsx diff --git a/src/components/SharedFilesModel/index.module.scss b/src/components/SharedFilesModel/index.module.scss new file mode 100644 index 0000000..58bf4e5 --- /dev/null +++ b/src/components/SharedFilesModel/index.module.scss @@ -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; + } +} \ No newline at end of file diff --git a/src/components/SharedFilesModel/index.tsx b/src/components/SharedFilesModel/index.tsx new file mode 100644 index 0000000..c631862 --- /dev/null +++ b/src/components/SharedFilesModel/index.tsx @@ -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([]); + const [showRowSelection, setShowRowSelection] = useState(false); + const [isSharedFilesModel, setIsSharedFilesModel] = useState(false); + const [user, setUser] = useState({}); + 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 => { + 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 ( + <> + setIsSharedFilesModel(false)} + maskClosable + > +
+
+
+ 共{fileList.total}个文件 +
+ } + 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 + }) + } + }} + /> + { + if (fileList.pageIndex === 1) { + getRoomFile() + } else { + setFileList({ + ...fileList, + pageIndex: 1 + }) + } + }} /> + { + setShowRowSelection(!showRowSelection) + }} style={{ color: showRowSelection ? '#5575F2' : 'white' }} /> + {showRowSelection ? { + if (selectedRowKeys.length) { + DeleteRoomFile(selectedRowKeys).then(res => { + if (res.code === 200) { + message.success('删除成功!') + getRoomFile() + } + }) + } else { + message.error('请选择文件!') + } + }} /> : null} + +
+
+
+ { + setSelectedRowKeys(newSelectedRowKeys); + } + } : undefined} + dataSource={fileList.data} + pagination={false} + scroll={{ y: '40vh' }} + style={{ width: '100%' }} + > + + + ( + <> + {item.size / 1024 > 1000 ? (item.size / (1024 * 1024)).toFixed(2) + 'MB' : (item.size / 1024).toFixed(2) + 'KB'} + + )} /> + + ( + <> + {item.downloadCount}次 + + )} + /> + ( + <> + { + 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() + } + }) + }} /> + {/* */} + + )} /> +
+
+ { + setFileList({ + ...fileList, + pageIndex: e + }) + }} pageSize={fileList.pageSize} current={fileList.pageIndex} hideOnSinglePage={true} /> +
+
+
+
+ +
+
+
+ + ) +}) + +export default SharedFilesModel \ No newline at end of file diff --git a/src/page/Meeting/index.module.scss b/src/page/Meeting/index.module.scss index 4568eef..0e02401 100644 --- a/src/page/Meeting/index.module.scss +++ b/src/page/Meeting/index.module.scss @@ -706,33 +706,4 @@ justify-content: space-between; 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; - } } \ No newline at end of file diff --git a/src/page/Meeting/index.tsx b/src/page/Meeting/index.tsx index 000869e..f9e4b12 100644 --- a/src/page/Meeting/index.tsx +++ b/src/page/Meeting/index.tsx @@ -3,13 +3,12 @@ import { useEffect, useRef, useState } from "react"; import Operation from '@/components/Operation'; import SpeakerModeModal from '@/components/SpeakerModeModal'; import InvitingPersonnelModal from '@/components/InvitingPersonnelModal'; -import { Button, Input, Popover, Modal, Checkbox, message, Table, Pagination } from "antd"; -import { DeleteOutlined, ProfileOutlined, ReloadOutlined, SearchOutlined, VerticalAlignBottomOutlined } from '@ant-design/icons'; +import { Button, Input, Popover, Modal, Checkbox, message } from "antd"; +import { SearchOutlined } 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, GetRoomUser, PostOpenMicr, PostOpenCamera, PostRoomManager, DeleteRoomManager, GetRoomKickout } from '@/api/Meeting'; -import axios from 'axios'; +import { GetRoomUser, PostOpenMicr, PostOpenCamera, PostRoomManager, DeleteRoomManager, GetRoomKickout } from '@/api/Meeting'; import ImageUrl from '@/utils/package/ImageUrl' import agora from '@/utils/package/agora' 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 { GetUserList } from '@/api/Home/User'; import Avatar from '@/components/Avatar'; +import SharedFilesModel from '@/components/SharedFilesModel'; dayjs.extend(durationPlugin); -const { Column } = Table const Meeting: React.FC = () => { const navigate = useNavigate(); const { state } = useLocation(); const speakerModeModalRef = useRef(); + const sharedFilesModelRef = useRef(); const invitingPersonnelRef = useRef(); const [statusList, setStatusList] = useState({ userList: false, userChatList: false, }) - const [selectedRowKeys, setSelectedRowKeys] = useState([]); const [isSharedScreenModal, setIsSharedScreenModal] = useState(false); - const [isInit, setIsInit] = useState(true); const [user, setUser] = useState({}); - const [showRowSelection, setShowRowSelection] = useState(false); - const [isSharedFilesModel, setIsSharedFilesModel] = useState(false); const [sharedScreenList, setSharedScreenList] = useState([]); const [sharedScreenItem, setSharedScreenItem] = useState(''); const [textMsg, setTextMsg] = useState(''); @@ -103,13 +99,6 @@ const Meeting: React.FC = () => { itemIndex: 0, rowIndex: 0, }); - const [fileList, setFileList] = useState({ - data: [], - keyword: '', - total: 0, - pageIndex: 1, - pageSize: 10, - }) const [roomUserList, setRoomUserList] = useState([]) const [allUserList, setAllUserList] = useState([]) const [chatList, setChatList] = useState([]) @@ -122,73 +111,69 @@ const Meeting: React.FC = () => { const [noViewChatList, setNoViewChatList] = useState(0) useEffect(() => { let time = null as any; - if (isInit) { - let userInfo = JSON.parse(storage.getItem('user') as string) - setMeetingMode('StandardMode'); - agora.init() - agora.registerEventHandler({ - onJoinChannelSuccess: async (info: any, _elapsed: any) => { - await onInvoke('joinChannel', { - roomNum: info.channelId, - enableMicr: true, - enableCamera: true + let userInfo = JSON.parse(storage.getItem('user') as string) + setUser(userInfo) + setMeetingMode('StandardMode'); + agora.init() + agora.registerEventHandler({ + onJoinChannelSuccess: async (info: any, _elapsed: any) => { + await onInvoke('joinChannel', { + roomNum: info.channelId, + enableMicr: 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() - setTimeout(() => { - agora.setupLocalVideo({ - account: Number(info.localUid), - view: document.getElementById(`video-${info.localUid}`) as HTMLElement, - channelId: info.channelId, - }) - }, 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({ + }, 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, }) - setTimeout(() => { - getRoomUser() - }, 1000); - } - }) - agora.setCameraCapture(VideoSourceType.VideoSourceCameraPrimary) - agora.setJoinChannel({ - channelId: state.channelId, - userid: userInfo.account, - token: state.token, - }) - setCurrentVideoId(userInfo.account) - setUser(userInfo) - setIsInit(false) - storage.setItem('noViewChatList', 0) - window.addEventListener('customStorageChange', handleCustomStorageChange); - window.addEventListener('online', handleNetworkChange); - window.addEventListener('offline', handleNetworkChange); - time = setInterval(() => { - setCurrentSeconds(currentSeconds++) - }, 1000) - } else { - getRoomFile() - } + }, 1000); + }, + onUserOffline: async (info: any, remoteUid: any, _reason: any) => { + await agora.setupRemoteVideo({ + account: Number(remoteUid), + view: document.getElementById(`video-${remoteUid}`) as HTMLElement, + channelId: info.channelId, + }) + setTimeout(() => { + getRoomUser() + }, 1000); + } + }) + agora.setCameraCapture(VideoSourceType.VideoSourceCameraPrimary) + agora.setJoinChannel({ + channelId: state.channelId, + userid: userInfo.account, + token: state.token, + }) + setCurrentVideoId(userInfo.account) + storage.setItem('noViewChatList', 0) + window.addEventListener('customStorageChange', handleCustomStorageChange); + window.addEventListener('online', handleNetworkChange); + window.addEventListener('offline', handleNetworkChange); + time = setInterval(() => { + setCurrentSeconds(currentSeconds++) + }, 1000) + return () => { window.removeEventListener('customStorageChange', handleCustomStorageChange); window.removeEventListener('online', handleNetworkChange); window.removeEventListener('offline', handleNetworkChange); clearInterval(time) }; - }, [fileList.pageIndex]); + }, []); useEffect(() => { roomUserList.forEach((item: any) => { @@ -364,8 +349,7 @@ const Meeting: React.FC = () => { agora.stopRecording() break; case '共享文件': - await getRoomFile() - setIsSharedFilesModel(true) + sharedFilesModelRef.current.getData() break; } } @@ -407,28 +391,7 @@ const Meeting: React.FC = () => { } }) }; - // 获取共享文件列表 - const getRoomFile = async (): Promise => { - 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 => { Promise.all([ @@ -848,183 +811,7 @@ const Meeting: React.FC = () => { - setIsSharedFilesModel(false)} - maskClosable - > -
-
-
- 共{fileList.total}个文件 -
- } - 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 - }) - } - }} - /> - { - if (fileList.pageIndex === 1) { - getRoomFile() - } else { - setFileList({ - ...fileList, - pageIndex: 1 - }) - } - }} /> - { - setShowRowSelection(!showRowSelection) - }} style={{ color: showRowSelection ? '#5575F2' : 'white' }} /> - {showRowSelection ? { - if (selectedRowKeys.length) { - DeleteRoomFile(selectedRowKeys).then(res => { - if (res.code === 200) { - message.success('删除成功!') - getRoomFile() - } - }) - } else { - message.error('请选择文件!') - } - }} /> : null} - -
-
-
- { - setSelectedRowKeys(newSelectedRowKeys); - } - } : undefined} - dataSource={fileList.data} - pagination={false} - scroll={{ y: '40vh' }} - style={{ width: '100%' }} - > - - - ( - <> - {item.size / 1024 > 1000 ? (item.size / (1024 * 1024)).toFixed(2) + 'MB' : (item.size / 1024).toFixed(2) + 'KB'} - - )} /> - - ( - <> - {item.downloadCount}次 - - )} - /> - ( - <> - { - 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() - } - }) - }} /> - {/* */} - - )} /> -
-
- { - setFileList({ - ...fileList, - pageIndex: e - }) - }} pageSize={fileList.pageSize} current={fileList.pageIndex} hideOnSinglePage={true} /> -
-
-
-
- -
-
-
+