This commit is contained in:
parent
20132c3086
commit
1b02462e4b
|
|
@ -93,3 +93,8 @@ export const PostRoomInvite = (roomId: string, data: any) =>
|
|||
method: 'post',
|
||||
data
|
||||
})
|
||||
export const GetShowUser = (roomNum: string) =>
|
||||
request({
|
||||
url: `/room/show-user?roomNum=${roomNum}`,
|
||||
method: 'get'
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,35 +1,47 @@
|
|||
.sharedFilesModel {
|
||||
> div:nth-child(1) {
|
||||
>div:nth-child(1) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
> span {
|
||||
color: #EEEEEE;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
> div {
|
||||
>div:nth-child(1) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
> span {
|
||||
>span {
|
||||
color: #EEEEEE;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
>div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 10px;
|
||||
|
||||
>span {
|
||||
color: #EEEEEE;
|
||||
font-size: 14px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
>div:nth-child(2) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
>span {
|
||||
margin-right: 20px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
> div:nth-child(2) {
|
||||
>div:nth-child(2) {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.updateDiv {
|
||||
color: #ffffff;
|
||||
|
||||
.ant-progress .ant-progress-text {
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,14 +6,14 @@ import {
|
|||
SearchOutlined,
|
||||
VerticalAlignBottomOutlined
|
||||
} from '@ant-design/icons';
|
||||
import {Button, Input, message, Modal, Pagination, Progress, Table} from 'antd';
|
||||
import {forwardRef, useEffect, useImperativeHandle, useState} from "react";
|
||||
import {DeleteRoomFile, GetRoomFile, GetRoomFileDwUrl, GetRoomUpFileurl, PostRoomFile} from '@/api/Meeting';
|
||||
import { Button, Input, message, Modal, Pagination, Progress, Table } from 'antd';
|
||||
import { forwardRef, useEffect, useImperativeHandle, useState } from "react";
|
||||
import { DeleteRoomFile, GetRoomFile, GetRoomFileDwUrl, GetRoomUpFileurl, PostRoomFile } from '@/api/Meeting';
|
||||
import axios from 'axios';
|
||||
import {useLocation} from 'react-router-dom';
|
||||
import {storage} from '@/utils';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { storage } from '@/utils';
|
||||
|
||||
const {Column} = Table
|
||||
const { Column } = Table
|
||||
|
||||
const SharedFilesModel = forwardRef((props: any, ref: any) => {
|
||||
useImperativeHandle(ref, () => ({
|
||||
|
|
@ -21,7 +21,7 @@ const SharedFilesModel = forwardRef((props: any, ref: any) => {
|
|||
setIsSharedFilesModel(true)
|
||||
}
|
||||
}))
|
||||
const {state} = useLocation();
|
||||
const { state } = useLocation();
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
|
||||
const [showRowSelection, setShowRowSelection] = useState(false);
|
||||
const [isSharedFilesModel, setIsSharedFilesModel] = useState(false);
|
||||
|
|
@ -74,18 +74,24 @@ const SharedFilesModel = forwardRef((props: any, ref: any) => {
|
|||
>
|
||||
<div>
|
||||
<div className={styles.sharedFilesModel}>
|
||||
<div className={styles.updateDiv}>
|
||||
<span>共{fileList.total}个文件</span>
|
||||
<div>
|
||||
<div>
|
||||
<Progress percent={uploadProgress} strokeColor={'green'} trailColor={'#e8e8e8'}
|
||||
percentPosition={{align: 'center', type: 'inner'}}
|
||||
size={{width: 100, height: 20}}/>
|
||||
<span>
|
||||
共{fileList.total}个文件
|
||||
</span>
|
||||
<div>
|
||||
<span>上传进度:</span>
|
||||
{/* <span>{uploadProgress === 100 ? '上传完成' : '上传中'} </span> */}
|
||||
<Progress percent={uploadProgress} trailColor={'#e8e8e8'}
|
||||
percentPosition={{ align: 'center', type: 'inner' }}
|
||||
size={{ width: 100, height: 20 }} />
|
||||
</div>
|
||||
</div>
|
||||
<div style={{color: 'white'}}>
|
||||
<div style={{ color: 'white' }}>
|
||||
<Input
|
||||
placeholder="搜索"
|
||||
style={{width: '200px'}}
|
||||
prefix={<SearchOutlined style={{color: 'white'}}/>}
|
||||
style={{ width: '200px' }}
|
||||
prefix={<SearchOutlined style={{ color: 'white' }} />}
|
||||
onChange={(e) => {
|
||||
setFileList({
|
||||
...fileList,
|
||||
|
|
@ -122,10 +128,10 @@ const SharedFilesModel = forwardRef((props: any, ref: any) => {
|
|||
pageIndex: 1
|
||||
})
|
||||
}
|
||||
}}/>
|
||||
}} />
|
||||
<ProfileOutlined title={showRowSelection ? '取消框选' : '显示框选'} onClick={() => {
|
||||
setShowRowSelection(!showRowSelection)
|
||||
}} style={{color: showRowSelection ? '#5575F2' : 'white'}}/>
|
||||
}} style={{ color: showRowSelection ? '#5575F2' : 'white' }} />
|
||||
{showRowSelection ? <DeleteOutlined title='删除' onClick={() => {
|
||||
if (selectedRowKeys.length) {
|
||||
DeleteRoomFile(selectedRowKeys).then(res => {
|
||||
|
|
@ -137,57 +143,56 @@ const SharedFilesModel = forwardRef((props: any, ref: any) => {
|
|||
} 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
|
||||
}} /> : 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,
|
||||
onUploadProgress: (progressEvent: any) => {
|
||||
// 获取上传进度
|
||||
const {loaded, total} = progressEvent;
|
||||
const progress = Math.round((loaded * 100) / total);
|
||||
console.log(`上传进度: ${progress}%`);
|
||||
setUploadProgress(progress)
|
||||
}
|
||||
})
|
||||
await PostRoomFile({
|
||||
fileUrl: res.data.key,
|
||||
size: fileInfo.size,
|
||||
fileName: fileInfo.name,
|
||||
roomId: state.roomId
|
||||
})
|
||||
getRoomFile()
|
||||
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,
|
||||
onUploadProgress: (progressEvent: any) => {
|
||||
// 获取上传进度
|
||||
const { loaded, total } = progressEvent;
|
||||
const progress = Math.round((loaded * 100) / total);
|
||||
setUploadProgress(progress)
|
||||
}
|
||||
})
|
||||
};
|
||||
file.click();
|
||||
}}
|
||||
await PostRoomFile({
|
||||
fileUrl: res.data.key,
|
||||
size: fileInfo.size,
|
||||
fileName: fileInfo.name,
|
||||
roomId: state.roomId
|
||||
})
|
||||
getRoomFile()
|
||||
})
|
||||
};
|
||||
file.click();
|
||||
}}
|
||||
>上传</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -202,130 +207,97 @@ const SharedFilesModel = forwardRef((props: any, ref: any) => {
|
|||
} : undefined}
|
||||
dataSource={fileList.data}
|
||||
pagination={false}
|
||||
scroll={{y: '40vh'}}
|
||||
style={{width: '100%'}}
|
||||
scroll={{ y: '40vh' }}
|
||||
style={{ width: '100%' }}
|
||||
>
|
||||
<Column title="文件" dataIndex="fileName" key="fileName" width={140}/>
|
||||
<Column title="更新时间" dataIndex="modifyTime" key="modifyTime" width={200}/>
|
||||
<Column title="文件" width={140}
|
||||
render={(item) => (
|
||||
<>
|
||||
<div style={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap' }}>
|
||||
<span>{item.fileName}</span>
|
||||
<span>
|
||||
{item.showPercentComplete ? <Progress percent={item.percentComplete} trailColor={'#e8e8e8'}
|
||||
percentPosition={{ align: 'center', type: 'inner' }}
|
||||
size={{ width: 40, height: 10 }} /> : null}
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
<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="上传者" dataIndex="userName" key="userName" />
|
||||
<Column title="下载次数"
|
||||
render={(item) => (
|
||||
<>
|
||||
<span>{item.downloadCount}次</span>
|
||||
</>
|
||||
)}
|
||||
render={(item) => (
|
||||
<>
|
||||
<span>{item.downloadCount}次</span>
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
<Column title="操作" render={(item) => (
|
||||
<>
|
||||
<VerticalAlignBottomOutlined title='下载'
|
||||
style={{color: '#5575F2', cursor: 'pointer'}}
|
||||
onClick={async () => {
|
||||
GetRoomFileDwUrl(item.fileUrl, item.id).then(res => {
|
||||
console.log(res)
|
||||
if (res.code === 200) {
|
||||
// const downloadLink = document.createElement("a");
|
||||
// downloadLink.href = res.data;
|
||||
// downloadLink.download = item.fileName;
|
||||
axios({
|
||||
url: res.data,
|
||||
method: 'GET',
|
||||
// headers: {
|
||||
// "Authorization": `Bearer ${user.token}`,
|
||||
// "responseType": 'stream'
|
||||
// },
|
||||
onDownloadProgress: (progressEvent: any) => {
|
||||
const totalLength = item.size;
|
||||
console.log(2222222)
|
||||
if (totalLength !== null) {
|
||||
const percentComplete = (progressEvent.loaded / totalLength * 100).toFixed(2);
|
||||
console.log(`下载进度: ${percentComplete}%`);
|
||||
item.percentComplete = percentComplete
|
||||
}
|
||||
}
|
||||
}).then(() => {
|
||||
const downloadLink = document.createElement("a");
|
||||
downloadLink.href = res.data;
|
||||
downloadLink.download = item.fileName;
|
||||
downloadLink.click();
|
||||
getRoomFile()
|
||||
})
|
||||
// downloadLink.click();
|
||||
// getRoomFile()
|
||||
}
|
||||
})
|
||||
style={{ color: '#5575F2', cursor: 'pointer' }}
|
||||
onClick={async () => {
|
||||
GetRoomFileDwUrl(item.fileUrl, item.id).then(res => {
|
||||
if (res.code === 200) {
|
||||
axios({
|
||||
url: res.data,
|
||||
method: 'GET',
|
||||
onDownloadProgress: (progressEvent: any) => {
|
||||
const totalLength = item.size;
|
||||
if (totalLength !== null) {
|
||||
const percentComplete = (progressEvent.loaded / totalLength * 100).toFixed(2);
|
||||
const fileIndex = fileList.data.findIndex((row: any) => row.id === item.id);
|
||||
let fileItem = [...fileList.data] as any;
|
||||
fileItem[fileIndex].percentComplete = percentComplete
|
||||
fileItem[fileIndex].showPercentComplete = true
|
||||
setFileList({
|
||||
...fileList,
|
||||
data: fileItem,
|
||||
})
|
||||
}
|
||||
}
|
||||
}).then(() => {
|
||||
const fileIndex = fileList.data.findIndex((row: any) => row.id === item.id);
|
||||
let fileItem = [...fileList.data] as any;
|
||||
fileItem[fileIndex].percentComplete = 100
|
||||
setTimeout(() => {
|
||||
fileItem[fileIndex].showPercentComplete = false
|
||||
}, 3000)
|
||||
setFileList({
|
||||
...fileList,
|
||||
data: fileItem,
|
||||
})
|
||||
const downloadLink = document.createElement("a");
|
||||
downloadLink.href = res.data;
|
||||
downloadLink.download = item.fileName;
|
||||
downloadLink.click();
|
||||
getRoomFile()
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// const url = "https://wgshare.oss-cn-chengdu.aliyuncs.com/share_file/559167236182085/20421555/b24e2c41f47140308c47cdd77e6305c7.jpg?Expires=1722923931&OSSAccessKeyId=LTAI5tQYVQHkkXxXTmjwiSDv&Signature=eJTWD93ifV2v1R6XCHSOa6j1R%2FE%3D"
|
||||
// axios({
|
||||
// url,
|
||||
// method: 'GET',
|
||||
// // headers: {
|
||||
// // "Authorization": `Bearer ${user.token}`,
|
||||
// // "responseType": 'stream'
|
||||
// // },
|
||||
// onDownloadProgress: (progressEvent: any) => {
|
||||
// const totalLength = item.size;
|
||||
// console.log(2222222)
|
||||
// if (totalLength !== null) {
|
||||
// const percentComplete = (progressEvent.loaded / totalLength * 100).toFixed(2);
|
||||
// console.log(`下载进度: ${percentComplete}%`);
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// .then((response: any) => {
|
||||
// const downloadLink = document.createElement("a");
|
||||
// downloadLink.href = response.data;
|
||||
// downloadLink.download = item.fileName;
|
||||
// downloadLink.click();
|
||||
// getRoomFile()
|
||||
// })
|
||||
|
||||
// await axios.get(`${import.meta.env.VITE_BASE_URL_API}/room/file-dw-url?fileUrl=${item.fileUrl}&fileId=${item.id}`, {
|
||||
// headers: {
|
||||
// "Authorization": `Bearer ${user.token}`,
|
||||
// "responseType": 'stream'
|
||||
// },
|
||||
// onDownloadProgress: (progressEvent: any) => {
|
||||
// const totalLength = item.size;
|
||||
// const percentComplete = (progressEvent.loaded / totalLength * 100).toFixed(2);
|
||||
// console.log(`下载进度: ${percentComplete}%`);
|
||||
// }
|
||||
// })
|
||||
// await axios.get(`${import.meta.env.VITE_BASE_URL_API}/room/file-dw-url?fileUrl=${item.fileUrl}&fileId=${item.id}`, {
|
||||
// headers: {
|
||||
// "ResponseType": "blob",
|
||||
// "Authorization": `Bearer ${user.token}`
|
||||
// },
|
||||
// withCredentials: false,
|
||||
// onDownloadProgress: (progressEvent: any) => {
|
||||
// console.log(progressEvent, 33333)
|
||||
// // 获取上传进度
|
||||
// const {loaded, total} = progressEvent;
|
||||
// const progress = Math.round((loaded * 100) / total);
|
||||
// console.log(`下载进度: ${progress}%`);
|
||||
// setUploadProgress(progress)
|
||||
// }
|
||||
// })
|
||||
}}/>
|
||||
}} />
|
||||
{/* <FolderOutlined title='文件' style={{ color: '#FFA000', cursor: 'pointer' }} /> */}
|
||||
</>
|
||||
)}/>
|
||||
)} />
|
||||
</Table>
|
||||
<div style={{display: 'flex', justifyContent: 'center', marginTop: '10px'}}>
|
||||
<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}/>
|
||||
}} pageSize={fileList.pageSize} current={fileList.pageIndex} hideOnSinglePage={true} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{display: 'flex', alignItems: 'center', justifyContent: 'flex-end'}}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end' }}>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ const Index: React.FC = () => {
|
|||
maxLength={8}
|
||||
value={createRoomFrom.roomNum}
|
||||
onChange={(e) => {
|
||||
const regex = /^[0-9 ]*$/;
|
||||
const regex = /^[0-9]*$/;
|
||||
if (regex.test(e.target.value)) {
|
||||
setCreateRoomFrom({
|
||||
...createRoomFrom,
|
||||
|
|
|
|||
|
|
@ -225,10 +225,13 @@ const User: React.FC = () => {
|
|||
showCount={true}
|
||||
value={addUserFrom.Account}
|
||||
onChange={(e) => {
|
||||
setAddUserFrom({
|
||||
...addUserFrom,
|
||||
Account: e.target.value,
|
||||
});
|
||||
const regex = /^[0-9]*$/;
|
||||
if (regex.test(e.target.value)) {
|
||||
setAddUserFrom({
|
||||
...addUserFrom,
|
||||
Account: e.target.value,
|
||||
});
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -82,7 +82,6 @@ const Login: React.FC = () => {
|
|||
if (!operation.account) {
|
||||
return message.error('请输入账号!')
|
||||
}
|
||||
operation.password = "";
|
||||
GetCheckUser(operation.account).then(res => {
|
||||
if (res.code === 200) {
|
||||
res.data ? setAccountPasswordStatus(true) : message.error('账号不存在!')
|
||||
|
|
|
|||
|
|
@ -694,7 +694,7 @@
|
|||
|
||||
.active {
|
||||
>div {
|
||||
// border: 1px solid #EBEBEB;
|
||||
border: 1px solid #EBEBEB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { SearchOutlined } from '@ant-design/icons';
|
|||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import { thumbImageBufferToBase64 } from '@/utils/package/base64'
|
||||
import { storage } from '@/utils';
|
||||
import { GetRoomUser, PostOpenMicr, PostOpenCamera, PostRoomManager, DeleteRoomManager, GetRoomKickout } from '@/api/Meeting';
|
||||
import { GetRoomUser, PostOpenMicr, PostOpenCamera, PostRoomManager, DeleteRoomManager, GetRoomKickout, GetShowUser } from '@/api/Meeting';
|
||||
import ImageUrl from '@/utils/package/ImageUrl'
|
||||
import agora from '@/utils/package/agora'
|
||||
import { onInvoke, onSignalr, offSignalr, onStart } from '@/utils/package/signalr';
|
||||
|
|
@ -112,6 +112,7 @@ const Meeting: React.FC = () => {
|
|||
const [meetingMode, setMeetingMode] = useState('')
|
||||
const [userSearchValue, setUserSearchValue] = useState('')
|
||||
const [noViewChatList, setNoViewChatList] = useState(0)
|
||||
const [currentLookUserAccount, setCurrentLookUserAccount] = useState<string>('')
|
||||
useEffect(() => {
|
||||
let time = null as any;
|
||||
let userInfo = JSON.parse(storage.getItem('user') as string)
|
||||
|
|
@ -131,7 +132,9 @@ const Meeting: React.FC = () => {
|
|||
account: Number(info.localUid),
|
||||
view: document.getElementById(`video-${info.localUid}`) as HTMLElement,
|
||||
channelId: info.channelId,
|
||||
sourceType: VideoSourceType.VideoSourceCameraPrimary,
|
||||
})
|
||||
getShowUser();
|
||||
}, 1000);
|
||||
},
|
||||
onUserJoined: async (info: any, remoteUid: any, _elapsed: any) => {
|
||||
|
|
@ -155,7 +158,7 @@ const Meeting: React.FC = () => {
|
|||
}, 1000);
|
||||
}
|
||||
})
|
||||
agora.setCameraCapture(VideoSourceType.VideoSourceCameraPrimary)
|
||||
agora.setCameraCapture()
|
||||
agora.setJoinChannel({
|
||||
channelId: state.channelId,
|
||||
userid: userInfo.account,
|
||||
|
|
@ -249,6 +252,27 @@ const Meeting: React.FC = () => {
|
|||
|
||||
}, [currentVideoId])
|
||||
|
||||
useEffect(() => {
|
||||
const userItem = allUserList.find((item: any) => item.account === currentLookUserAccount)
|
||||
if (userItem) {
|
||||
if (userItem.account === user.account) {
|
||||
// agora.setupLocalVideo({
|
||||
// account: Number(userItem.account),
|
||||
// view: document.getElementById(`look-video`) as HTMLElement,
|
||||
// channelId: state.channelId,
|
||||
// sourceType: VideoSourceType.VideoSourceCameraPrimary,
|
||||
// })
|
||||
} else {
|
||||
// agora.setupRemoteVideoJoin({
|
||||
// account: Number(userItem.account),
|
||||
// view: document.getElementById(`look-video`) as HTMLElement,
|
||||
// channelId: state.channelId,
|
||||
// sourceType: VideoSourceType.VideoSourceCameraPrimary,
|
||||
// })
|
||||
}
|
||||
}
|
||||
}, [allUserList, currentLookUserAccount])
|
||||
|
||||
// 网络
|
||||
const handleNetworkChange = (): void => {
|
||||
if (navigator.onLine) {
|
||||
|
|
@ -267,6 +291,14 @@ const Meeting: React.FC = () => {
|
|||
message.error('网络已断开!')
|
||||
}
|
||||
}
|
||||
// 全员观看
|
||||
const getShowUser = async (): Promise<void> => {
|
||||
await GetShowUser(state.channelId).then(res => {
|
||||
if (res.code === 200 && res.data) {
|
||||
setCurrentLookUserAccount(res.data)
|
||||
}
|
||||
})
|
||||
}
|
||||
// 加入房间时间
|
||||
const changeCurrentSeconds = (): string => {
|
||||
const duration = dayjs.duration(currentSeconds, 'seconds');
|
||||
|
|
@ -304,7 +336,7 @@ const Meeting: React.FC = () => {
|
|||
setIsSharedScreenModal(true)
|
||||
break;
|
||||
case '停止共享':
|
||||
agora.setCameraCapture(VideoSourceType.VideoSourceCameraPrimary)
|
||||
agora.setCameraCapture()
|
||||
footerListTemplate[itemIndex][rowIndex].title = '共享屏幕'
|
||||
break;
|
||||
case '关闭声音':
|
||||
|
|
@ -386,7 +418,7 @@ const Meeting: React.FC = () => {
|
|||
const footerListTemplate = [...footerList]
|
||||
footerListTemplate[footerListIndex.itemIndex][footerListIndex.rowIndex].title = '停止共享'
|
||||
setIsSharedScreenModal(false)
|
||||
agora.setDesktopCapturerVideo(sharedScreenItem, VideoSourceType.VideoSourceScreen)
|
||||
agora.setDesktopCapturerVideo(sharedScreenItem)
|
||||
} else {
|
||||
message.error('请选择应用!')
|
||||
}
|
||||
|
|
@ -538,8 +570,8 @@ const Meeting: React.FC = () => {
|
|||
return ''
|
||||
}
|
||||
// 设置单个视频样式
|
||||
const setMeetingContentSwiperCardClass = (account: string): string => {
|
||||
if (currentVideoId === account && (meetingMode === 'StandardMode' || meetingMode === 'SpeakerMode')) {
|
||||
const setMeetingContentSwiperCardClass = (account: string, bool: boolean = false): string => {
|
||||
if ((bool || currentVideoId === account) && (meetingMode === 'StandardMode' || meetingMode === 'SpeakerMode')) {
|
||||
switch (meetingMode) {
|
||||
case 'StandardMode':
|
||||
return styles.meetingContentSwiperCardStandardMode
|
||||
|
|
@ -569,11 +601,12 @@ const Meeting: React.FC = () => {
|
|||
<div className={styles.meetingContentBody}>
|
||||
<div className={`${styles.meetingContentBodyLeft} drag`}>
|
||||
<div className={getMeetingContentBodyLeftModeClass()} >
|
||||
{/* ${setMeetingContentSwiperCardClass(item.account)} */}
|
||||
{allUserList.map((item: any, index: number) => {
|
||||
return (
|
||||
item.isRoom ?
|
||||
<div
|
||||
className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass(item.account)}`}
|
||||
className={`${styles.meetingContentSwiperCard}`}
|
||||
key={index}
|
||||
onClick={() => {
|
||||
if (footerList[1][3].active) {
|
||||
|
|
@ -593,6 +626,19 @@ const Meeting: React.FC = () => {
|
|||
)
|
||||
}
|
||||
)}
|
||||
{currentLookUserAccount ?
|
||||
<div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass(currentLookUserAccount)}`}>
|
||||
<div className={`${styles.meetingContentSwiperCardVdeio}`} id={`look-video`}>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
<div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass(currentLookUserAccount, true)}`}>
|
||||
<div className={`${styles.meetingContentSwiperCardVdeio}`} style={{ color: 'white', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||||
暂无视频
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ const option: any = {
|
|||
token: '',
|
||||
channelId: '',
|
||||
userid: '',
|
||||
sourceType: VideoSourceType.VideoSourceCameraPrimary,
|
||||
}
|
||||
let iMediaRecorder: any = '';
|
||||
let rtcEngine: any = '';
|
||||
|
|
@ -80,19 +79,11 @@ const agora = {
|
|||
setupLocalVideo: async (item: any) => {
|
||||
await rtcEngine.setupLocalVideo({
|
||||
renderMode: RenderModeType.RenderModeFit,
|
||||
sourceType: option.sourceType,
|
||||
sourceType: item.sourceType,
|
||||
uid: item.account,
|
||||
view: item.view,
|
||||
setupMode: VideoViewSetupMode.VideoViewSetupAdd,
|
||||
});
|
||||
switch (option.sourceType) {
|
||||
case VideoSourceType.VideoSourceCameraPrimary:
|
||||
agora.updateChannelMediaOptions(true)
|
||||
break;
|
||||
case VideoSourceType.VideoSourceScreen:
|
||||
agora.updateChannelMediaOptions(false)
|
||||
break;
|
||||
}
|
||||
},
|
||||
// 远端加入
|
||||
setupRemoteVideoJoin: async (item: any) => {
|
||||
|
|
@ -135,33 +126,14 @@ const agora = {
|
|||
},
|
||||
// 加入频道
|
||||
joinChannel: () => {
|
||||
rtcEngine.joinChannel(option.token, option.channelId, option.userid, {});
|
||||
},
|
||||
// 更新频道信息
|
||||
updateChannelMediaOptions: (bool: boolean) => {
|
||||
if (bool) {
|
||||
// 摄像头
|
||||
rtcEngine.updateChannelMediaOptions({
|
||||
channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting, //设置频道场景为直播场景
|
||||
clientRoleType: ClientRoleType.ClientRoleBroadcaster, //设置用户角色为主播;如果要将用户角色设置为观众,保持默认值即可
|
||||
publishMicrophoneTrack: true, //发布麦克风采集的音频
|
||||
publishCameraTrack: true, //发布摄像头采集的视频
|
||||
publishScreenTrack: false, //设置是否发布屏幕采集的视频
|
||||
autoSubscribeAudio: true, //自动订阅所有音频流
|
||||
autoSubscribeVideo: true, //自动订阅所有视频流
|
||||
})
|
||||
} else {
|
||||
// 屏幕
|
||||
rtcEngine.updateChannelMediaOptions({
|
||||
channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting, //设置频道场景为直播场景
|
||||
clientRoleType: ClientRoleType.ClientRoleBroadcaster, //用户角色 1主播 2观众
|
||||
publishMicrophoneTrack: true, //设置是否发布麦克风采集到的音频
|
||||
publishCameraTrack: false, //设置是否发布摄像头采集的视频
|
||||
publishScreenTrack: true, //设置是否发布屏幕采集的视频
|
||||
autoSubscribeAudio: true, //设置是否自动订阅所有音频流
|
||||
autoSubscribeVideo: true, //设置是否自动订阅所有视频流
|
||||
})
|
||||
}
|
||||
rtcEngine.joinChannel(option.token, option.channelId, option.userid, {
|
||||
autoSubscribeAudio: true,
|
||||
autoSubscribeVideo: true,
|
||||
publishMicrophoneTrack: true,
|
||||
publishCameraTrack: true,
|
||||
clientRoleType: ClientRoleType.ClientRoleBroadcaster,
|
||||
publishScreenTrack: false,
|
||||
});
|
||||
},
|
||||
// 停止共享屏幕
|
||||
stopScreenCapture: () => {
|
||||
|
|
@ -176,17 +148,15 @@ const agora = {
|
|||
rtcEngine.muteLocalVideoStream(mute)
|
||||
},
|
||||
// 摄像头采集
|
||||
setCameraCapture: (sourceType: number) => {
|
||||
setCameraCapture: () => {
|
||||
agora.stopScreenCapture()
|
||||
if (sourceType !== option.sourceType) {
|
||||
rtcEngine.destroyRendererByConfig(option.sourceType, option.channelId, option.account)
|
||||
option.sourceType = sourceType
|
||||
agora.setupLocalVideo({
|
||||
account: Number(option.userid),
|
||||
view: document.getElementById(`video-${option.userid}`),
|
||||
channelId: option.channelId,
|
||||
})
|
||||
}
|
||||
// rtcEngine.destroyRendererByConfig(option.sourceType, option.channelId, option.account)
|
||||
agora.setupLocalVideo({
|
||||
account: Number(option.userid),
|
||||
view: document.getElementById(`video-${option.userid}`),
|
||||
channelId: option.channelId,
|
||||
sourceType: VideoSourceType.VideoSourceCameraPrimary,
|
||||
})
|
||||
rtcEngine.startCameraCapture(VideoSourceType.VideoSourceCamera, {})
|
||||
},
|
||||
// 加入频道
|
||||
|
|
@ -201,18 +171,28 @@ const agora = {
|
|||
return rtcEngine.getScreenCaptureSources({ width: 300, height: 300 }, { width: 300, height: 300 }, true);
|
||||
},
|
||||
// 共享屏幕采集
|
||||
setDesktopCapturerVideo: async (targetSource: any, sourceType: number) => {
|
||||
if (sourceType !== option.sourceType) {
|
||||
await rtcEngine.stopCameraCapture(option.sourceType)
|
||||
rtcEngine.destroyRendererByConfig(option.sourceType, option.channelId, option.account)
|
||||
option.sourceType = sourceType
|
||||
agora.setupLocalVideo({
|
||||
account: Number(option.userid),
|
||||
view: document.getElementById(`video-${option.userid}`),
|
||||
channelId: option.channelId,
|
||||
})
|
||||
}
|
||||
setDesktopCapturerVideo: async (targetSource: any) => {
|
||||
// await rtcEngine.stopCameraCapture(option.sourceType)
|
||||
// rtcEngine.destroyRendererByConfig(option.sourceType, option.channelId, option.account)
|
||||
await agora.setupLocalVideo({
|
||||
account: Number(option.userid),
|
||||
view: document.getElementById(`look-video`),
|
||||
channelId: option.channelId,
|
||||
sourceType: VideoSourceType.VideoSourceScreen,
|
||||
})
|
||||
agora.stopScreenCapture();
|
||||
rtcEngine.joinChannelEx(
|
||||
option.token,
|
||||
{ channelId: option.channelId, localUid: option.account },
|
||||
{
|
||||
autoSubscribeAudio: false,
|
||||
autoSubscribeVideo: false,
|
||||
publishMicrophoneTrack: false,
|
||||
publishCameraTrack: false,
|
||||
clientRoleType: ClientRoleType.ClientRoleBroadcaster,
|
||||
publishScreenTrack: true,
|
||||
}
|
||||
);
|
||||
if (
|
||||
targetSource.type ===
|
||||
ScreenCaptureSourceType.ScreencapturesourcetypeScreen
|
||||
|
|
|
|||
|
|
@ -58,6 +58,12 @@ class Request {
|
|||
message.error(resData.message)
|
||||
}
|
||||
}
|
||||
if (resData.code === 1403) {
|
||||
setTimeout(() => {
|
||||
storage.removeItem('user')
|
||||
location.href = location.origin + '/#/login'
|
||||
}, 3000)
|
||||
}
|
||||
return resData
|
||||
},
|
||||
(err: any) => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue