Merge pull request 'yangjie' (#45) from yangjie into master
Reviewed-on: #45
This commit is contained in:
commit
f47681d2f1
9
main.js
9
main.js
|
|
@ -181,6 +181,7 @@ app.on('ready', () => {
|
||||||
connection.off('DriverList');
|
connection.off('DriverList');
|
||||||
connection.off('SetDriver');
|
connection.off('SetDriver');
|
||||||
connection.off('ShowDriverList');
|
connection.off('ShowDriverList');
|
||||||
|
connection.off('ModifyNickName');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ipcMain.handle('onStop', (event) => {
|
ipcMain.handle('onStop', (event) => {
|
||||||
|
|
@ -370,6 +371,14 @@ app.on('ready', () => {
|
||||||
driversJsonString
|
driversJsonString
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
// 修改用户名称
|
||||||
|
connection.on("ModifyNickName", (uid, nickName) => {
|
||||||
|
mainWindow.webContents.send('onSignalr', {
|
||||||
|
key: 'ModifyNickName',
|
||||||
|
uid,
|
||||||
|
nickName
|
||||||
|
})
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// 放大缩小退出窗口
|
// 放大缩小退出窗口
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "WGShare.Metting",
|
"name": "WGShare.Metting",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.6.0",
|
"version": "0.6.3",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"authors": "yj",
|
"authors": "yj",
|
||||||
"description": "智汇享",
|
"description": "智汇享",
|
||||||
|
|
|
||||||
|
|
@ -147,4 +147,11 @@ export const PostRoomSingnIn = (data: any) =>
|
||||||
url: `/room/sign-in`,
|
url: `/room/sign-in`,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
|
})
|
||||||
|
|
||||||
|
export const PutAlterUname = (data: any) =>
|
||||||
|
request({
|
||||||
|
url: `/room/alter-uname`,
|
||||||
|
method: 'put',
|
||||||
|
data
|
||||||
})
|
})
|
||||||
|
|
@ -20,18 +20,17 @@ const JoinSetting = forwardRef((_props: any, ref: any) => {
|
||||||
if (location.hash.indexOf('/meeting') === -1) {
|
if (location.hash.indexOf('/meeting') === -1) {
|
||||||
await agora.init()
|
await agora.init()
|
||||||
}
|
}
|
||||||
setJoinRoomSettingForm((res: any) => {
|
const list = [...joinRoomSettingForm]
|
||||||
res.forEach(async (item: any, index: number) => {
|
list.forEach(async (item: any, index: number) => {
|
||||||
if (index === 0 && role.ID.includes(userInfo.roleId)) {
|
if (index === 0 && role.ID.includes(userInfo.roleId)) {
|
||||||
await agora.getAudioMediaList().then(res => {
|
await agora.getAudioMediaList().then(res => {
|
||||||
item.active = res.ecordingList.length ? true : false
|
item.active = res.ecordingList.length ? true : false
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
item.active = false
|
item.active = false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return res
|
setJoinRoomSettingForm(list)
|
||||||
})
|
|
||||||
setRoomNumber(roomNum)
|
setRoomNumber(roomNum)
|
||||||
getDeviceList()
|
getDeviceList()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
import styles from '@/components/SharedFilesModel/index.module.scss'
|
import styles from '@/components/SharedFilesModel/index.module.scss'
|
||||||
import {
|
import {
|
||||||
DeleteOutlined,
|
DeleteOutlined,
|
||||||
|
LoadingOutlined,
|
||||||
ProfileOutlined,
|
ProfileOutlined,
|
||||||
ReloadOutlined,
|
ReloadOutlined,
|
||||||
SearchOutlined,
|
SearchOutlined,
|
||||||
VerticalAlignBottomOutlined
|
VerticalAlignBottomOutlined
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
import { Button, Input, message, Modal, Pagination, Progress, Table } from 'antd';
|
import { Button, Input, message, Modal, Pagination, Popconfirm, Progress, Table } from 'antd';
|
||||||
import { forwardRef, useEffect, useImperativeHandle, useState, useRef } from "react";
|
import { forwardRef, useEffect, useImperativeHandle, useState, useRef } from "react";
|
||||||
import { DeleteRoomFile, GetRoomFile, GetRoomFileDwUrl, GetRoomUpFileurl, GetRoomUserItem, PostRoomFile } from '@/api/Meeting';
|
import { DeleteRoomFile, GetRoomFile, GetRoomFileDwUrl, GetRoomUpFileurl, GetRoomUserItem, PostRoomFile } from '@/api/Meeting';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
@ -100,10 +101,10 @@ const SharedFilesModel = forwardRef((props: any, ref: any) => {
|
||||||
</div>
|
</div>
|
||||||
<div style={{ color: 'white' }}>
|
<div style={{ color: 'white' }}>
|
||||||
<Input
|
<Input
|
||||||
placeholder="搜索"
|
placeholder="请输入文件名"
|
||||||
style={{ width: '200px' }}
|
style={{ width: '200px' }}
|
||||||
prefix={<SearchOutlined style={{ color: 'white' }} />}
|
prefix={<SearchOutlined style={{ color: 'white' }} />}
|
||||||
onChange={(e) => {
|
onPressEnter={(e: any) => {
|
||||||
if (fileList.pageIndex === 1) {
|
if (fileList.pageIndex === 1) {
|
||||||
setFileList({
|
setFileList({
|
||||||
...fileList,
|
...fileList,
|
||||||
|
|
@ -116,8 +117,30 @@ const SharedFilesModel = forwardRef((props: any, ref: any) => {
|
||||||
pageIndex: 1
|
pageIndex: 1
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
onBlur={(e) => {
|
||||||
|
if (fileList.pageIndex === 1) {
|
||||||
|
setFileList({
|
||||||
|
...fileList,
|
||||||
|
keyword: e.target.value,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
setFileList({
|
||||||
|
...fileList,
|
||||||
|
keyword: e.target.value,
|
||||||
|
pageIndex: 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
suffix={
|
||||||
|
<span
|
||||||
|
style={{ color: '#47D3D0', cursor: 'pointer' }}
|
||||||
|
onClick={() => {
|
||||||
|
getRoomFile()
|
||||||
|
}}
|
||||||
|
>搜索
|
||||||
|
</span>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<ReloadOutlined title='刷新' onClick={() => {
|
<ReloadOutlined title='刷新' onClick={() => {
|
||||||
if (fileList.pageIndex === 1) {
|
if (fileList.pageIndex === 1) {
|
||||||
|
|
@ -129,29 +152,41 @@ const SharedFilesModel = forwardRef((props: any, ref: any) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}} />
|
}} />
|
||||||
{roomUserItem && role.ID.includes(roomUserItem.roleId) || roomUserItem.isRoomManager ? <ProfileOutlined title={showRowSelection ? '取消框选' : '显示框选'} onClick={() => {
|
{roomUserItem && (role.ID.includes(roomUserItem.roleId) || roomUserItem.isRoomManager) && fileList.data.length ? <ProfileOutlined title={showRowSelection ? '取消框选' : '显示框选'} onClick={() => {
|
||||||
setShowRowSelection(!showRowSelection)
|
setShowRowSelection(!showRowSelection)
|
||||||
}} style={{ color: showRowSelection ? '#5575F2' : 'white' }} /> : null}
|
}} style={{ color: showRowSelection ? '#5575F2' : 'white' }} /> : null}
|
||||||
{showRowSelection ? <DeleteOutlined title='删除' onClick={() => {
|
{showRowSelection && fileList.data.length && selectedRowKeys.length ?
|
||||||
if (selectedRowKeys.length) {
|
<Popconfirm
|
||||||
DeleteRoomFile(selectedRowKeys).then(res => {
|
title="提示"
|
||||||
if (res.code === 200) {
|
description="确认删除吗?"
|
||||||
message.success('删除成功!')
|
onConfirm={() => {
|
||||||
if (fileList.pageIndex === 1) {
|
if (selectedRowKeys.length) {
|
||||||
getRoomFile()
|
DeleteRoomFile(selectedRowKeys).then(res => {
|
||||||
} else {
|
if (res.code === 200) {
|
||||||
setFileList({
|
message.success('删除成功!')
|
||||||
...fileList,
|
if (fileList.pageIndex === 1) {
|
||||||
pageIndex: 1
|
getRoomFile()
|
||||||
})
|
} else {
|
||||||
}
|
setFileList({
|
||||||
|
...fileList,
|
||||||
|
pageIndex: 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
message.error('请选择文件!')
|
||||||
}
|
}
|
||||||
})
|
}}
|
||||||
} else {
|
onCancel={() => {
|
||||||
message.error('请选择文件!')
|
|
||||||
}
|
}}
|
||||||
}} /> : null}
|
okText="确认"
|
||||||
<Button type="primary" style={{ backgroundColor: '#31353A' }}
|
cancelText="取消"
|
||||||
|
>
|
||||||
|
<DeleteOutlined title='删除' />
|
||||||
|
</Popconfirm> : null}
|
||||||
|
{roomUserItem && role.ID.includes(roomUserItem.roleId) || roomUserItem.isRoomManager ? <Button type="primary" style={{ backgroundColor: '#31353A' }}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (isUpFile) {
|
if (isUpFile) {
|
||||||
message.error('文件上传中,请稍后上传。')
|
message.error('文件上传中,请稍后上传。')
|
||||||
|
|
@ -211,7 +246,7 @@ const SharedFilesModel = forwardRef((props: any, ref: any) => {
|
||||||
};
|
};
|
||||||
file.click();
|
file.click();
|
||||||
}}
|
}}
|
||||||
>上传</Button>
|
>上传</Button> : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -258,9 +293,10 @@ const SharedFilesModel = forwardRef((props: any, ref: any) => {
|
||||||
/>
|
/>
|
||||||
<Column title="操作" render={(item) => (
|
<Column title="操作" render={(item) => (
|
||||||
<>
|
<>
|
||||||
<VerticalAlignBottomOutlined title='下载'
|
{!item.showPercentComplete ? <VerticalAlignBottomOutlined title='下载'
|
||||||
style={{ color: '#5575F2', cursor: 'pointer' }}
|
style={{ color: '#5575F2', cursor: 'pointer' }}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
|
storage.setItem('loading', true)
|
||||||
GetRoomFileDwUrl(item.fileUrl, item.id).then(res => {
|
GetRoomFileDwUrl(item.fileUrl, item.id).then(res => {
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
axios({
|
axios({
|
||||||
|
|
@ -329,8 +365,10 @@ const SharedFilesModel = forwardRef((props: any, ref: any) => {
|
||||||
}, 2000)
|
}, 2000)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
storage.setItem('loading', false)
|
||||||
})
|
})
|
||||||
}} />
|
}} /> : <LoadingOutlined />}
|
||||||
{/* <FolderOutlined title='文件' style={{ color: '#FFA000', cursor: 'pointer', marginLeft: '10px' }} /> */}
|
{/* <FolderOutlined title='文件' style={{ color: '#FFA000', cursor: 'pointer', marginLeft: '10px' }} /> */}
|
||||||
</>
|
</>
|
||||||
)} />
|
)} />
|
||||||
|
|
@ -341,7 +379,7 @@ const SharedFilesModel = forwardRef((props: any, ref: any) => {
|
||||||
...fileList,
|
...fileList,
|
||||||
pageIndex: e
|
pageIndex: e
|
||||||
})
|
})
|
||||||
}} pageSize={fileList.pageSize} current={fileList.pageIndex} hideOnSinglePage={true} showSizeChanger={false}/>
|
}} pageSize={fileList.pageSize} current={fileList.pageIndex} hideOnSinglePage={true} showSizeChanger={false} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
.userNameModal {
|
||||||
|
|
||||||
|
.userNameModalFooter {
|
||||||
|
margin-top: 10px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
import { PutAlterUname } from '@/api/Meeting';
|
||||||
|
import styles from '@/components/UserName/index.module.scss'
|
||||||
|
import { storage } from '@/utils';
|
||||||
|
import { Button, Input, message, Modal } from 'antd';
|
||||||
|
import { useState, useImperativeHandle, forwardRef } from "react";
|
||||||
|
const UserName = forwardRef((props: any, ref: any) => {
|
||||||
|
useImperativeHandle(ref, () => ({
|
||||||
|
changeModal: (data: any) => {
|
||||||
|
setInfo(data)
|
||||||
|
setUserNameModal(true)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
const [userNameModal, setUserNameModal] = useState(false);
|
||||||
|
const [info, setInfo] = useState({
|
||||||
|
userName: '',
|
||||||
|
uid: ''
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Modal
|
||||||
|
title="修改用户名"
|
||||||
|
open={userNameModal}
|
||||||
|
footer={null}
|
||||||
|
destroyOnClose={true}
|
||||||
|
onCancel={() => setUserNameModal(false)}
|
||||||
|
centered
|
||||||
|
width={'300px'}
|
||||||
|
>
|
||||||
|
<div className={styles.userNameModal}>
|
||||||
|
<div className={styles.userNameModalContent}>
|
||||||
|
<Input
|
||||||
|
placeholder="请输入用户名称"
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
value={info.userName}
|
||||||
|
onChange={(e) => {
|
||||||
|
setInfo({
|
||||||
|
...info,
|
||||||
|
userName: e.target.value
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className={styles.userNameModalFooter}>
|
||||||
|
<Button type="primary" style={{ backgroundColor: 'rgb(16,20,24)', marginRight: '14px' }}
|
||||||
|
onClick={() => setUserNameModal(false)}>关闭</Button>
|
||||||
|
<Button type="primary"
|
||||||
|
onClick={async () => {
|
||||||
|
const stateInfo = await JSON.parse(storage.getItem('stateInfo') as string);
|
||||||
|
if (info.userName) {
|
||||||
|
PutAlterUname({
|
||||||
|
nickName: info.userName,
|
||||||
|
roomNum: stateInfo.channelId,
|
||||||
|
uid: info.uid,
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
message.success('修改成功')
|
||||||
|
setUserNameModal(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
message.error('请输入用户名')
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
className='m-ant-btn'>
|
||||||
|
修改
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
export default UserName
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import styles from '@/page/Home/Index/index.module.scss'
|
import styles from '@/page/Home/Index/index.module.scss'
|
||||||
import { useEffect, useState, useRef } from "react";
|
import { useEffect, useState, useRef } from "react";
|
||||||
import Operation from '@/components/Operation';
|
import Operation from '@/components/Operation';
|
||||||
import { Button, Input, Modal, Pagination, Empty, message, Popover, Popconfirm, DatePicker, Select } from "antd";
|
import { Button, Input, Modal, Pagination, Empty, message, Popover, Popconfirm, DatePicker, Select, Radio } from "antd";
|
||||||
import { GetRoom, PostRoom, GetCheckoutRoomNum, GetRoomRtcToken, DeleteRoom, GetRecord, PostRoomInfo, GetQrcode } from '@/api/Home/Index';
|
import { GetRoom, PostRoom, GetCheckoutRoomNum, GetRoomRtcToken, DeleteRoom, GetRecord, PostRoomInfo, GetQrcode } from '@/api/Home/Index';
|
||||||
import ImageUrl from '@/utils/package/imageUrl'
|
import ImageUrl from '@/utils/package/imageUrl'
|
||||||
import { ExclamationCircleFilled, ReloadOutlined } from '@ant-design/icons';
|
import { ExclamationCircleFilled, ReloadOutlined } from '@ant-design/icons';
|
||||||
|
|
@ -42,6 +42,7 @@ const Index: React.FC = () => {
|
||||||
const [subjectList, setSubjectList] = useState<any>([]);
|
const [subjectList, setSubjectList] = useState<any>([]);
|
||||||
const [timeData, setTimeData] = useState<any>([]);
|
const [timeData, setTimeData] = useState<any>([]);
|
||||||
const [isCreateRoom, setIsCreateRoom] = useState<boolean>(false);
|
const [isCreateRoom, setIsCreateRoom] = useState<boolean>(false);
|
||||||
|
const [allowAnonymous, setAllowAnonymous] = useState(true);
|
||||||
const [baseImage, setBaseImage] = useState('');
|
const [baseImage, setBaseImage] = useState('');
|
||||||
const userInfo = JSON.parse(storage.getItem('user') as string)
|
const userInfo = JSON.parse(storage.getItem('user') as string)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -305,6 +306,7 @@ const Index: React.FC = () => {
|
||||||
year: item.year,
|
year: item.year,
|
||||||
id: item.id,
|
id: item.id,
|
||||||
})
|
})
|
||||||
|
setAllowAnonymous(item.allowAnonymous)
|
||||||
getSubDpList()
|
getSubDpList()
|
||||||
setIsCreateRoom(false)
|
setIsCreateRoom(false)
|
||||||
setCreateRoomModal(true)
|
setCreateRoomModal(true)
|
||||||
|
|
@ -385,7 +387,6 @@ const Index: React.FC = () => {
|
||||||
placeholder="请输入房间号"
|
placeholder="请输入房间号"
|
||||||
style={{ flexGrow: 1 }}
|
style={{ flexGrow: 1 }}
|
||||||
className={styles.letterSpacing}
|
className={styles.letterSpacing}
|
||||||
showCount
|
|
||||||
maxLength={8}
|
maxLength={8}
|
||||||
value={createRoomFrom.roomNum}
|
value={createRoomFrom.roomNum}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
|
|
@ -422,7 +423,6 @@ const Index: React.FC = () => {
|
||||||
<Input.TextArea
|
<Input.TextArea
|
||||||
placeholder="请输入房间名字"
|
placeholder="请输入房间名字"
|
||||||
style={{ flexGrow: 1 }}
|
style={{ flexGrow: 1 }}
|
||||||
showCount
|
|
||||||
maxLength={30}
|
maxLength={30}
|
||||||
value={createRoomFrom.roomName}
|
value={createRoomFrom.roomName}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
|
|
@ -437,6 +437,7 @@ const Index: React.FC = () => {
|
||||||
<span>届:</span>
|
<span>届:</span>
|
||||||
<Input
|
<Input
|
||||||
placeholder="请输入届"
|
placeholder="请输入届"
|
||||||
|
maxLength={4}
|
||||||
style={{ flexGrow: 1 }}
|
style={{ flexGrow: 1 }}
|
||||||
value={createRoomFrom.year}
|
value={createRoomFrom.year}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
|
|
@ -463,6 +464,15 @@ const Index: React.FC = () => {
|
||||||
})
|
})
|
||||||
}} />
|
}} />
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>游客入会:</span>
|
||||||
|
<Radio.Group onChange={(e) => {
|
||||||
|
setAllowAnonymous(e.target.value);
|
||||||
|
}} value={allowAnonymous}>
|
||||||
|
<Radio value={true}>开启</Radio>
|
||||||
|
<Radio value={false}>关闭</Radio>
|
||||||
|
</Radio.Group>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style={{
|
<div style={{
|
||||||
display: 'flex', justifyContent: 'center'
|
display: 'flex', justifyContent: 'center'
|
||||||
|
|
@ -483,20 +493,22 @@ const Index: React.FC = () => {
|
||||||
if (bool) {
|
if (bool) {
|
||||||
message.error('房间号已存在!')
|
message.error('房间号已存在!')
|
||||||
} else {
|
} else {
|
||||||
PostRoom(createRoomFrom).then(res => {
|
PostRoom({ ...createRoomFrom, allowAnonymous }).then(res => {
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
message.success('创建成功!')
|
message.success('创建成功!')
|
||||||
setCreateRoomModal(false)
|
setCreateRoomModal(false)
|
||||||
|
setAllowAnonymous(true)
|
||||||
getRoomList()
|
getRoomList()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
PostRoomInfo(createRoomFrom).then(res => {
|
PostRoomInfo({ ...createRoomFrom, allowAnonymous }).then(res => {
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
message.success('更新成功!')
|
message.success('更新成功!')
|
||||||
setCreateRoomModal(false)
|
setCreateRoomModal(false)
|
||||||
|
setAllowAnonymous(true)
|
||||||
getRoomList()
|
getRoomList()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -221,7 +221,7 @@ const User: React.FC = () => {
|
||||||
>
|
>
|
||||||
删除用户
|
删除用户
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div className={`${styles.userBtnsRight} drag`}>
|
<div className={`${styles.userBtnsRight} drag`}>
|
||||||
<Input
|
<Input
|
||||||
|
|
@ -415,6 +415,7 @@ const User: React.FC = () => {
|
||||||
<Input
|
<Input
|
||||||
placeholder="请输入届"
|
placeholder="请输入届"
|
||||||
value={addUserFrom.year}
|
value={addUserFrom.year}
|
||||||
|
maxLength={4}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const regex = /^[0-9]*$/;
|
const regex = /^[0-9]*$/;
|
||||||
if (regex.test(e.target.value)) {
|
if (regex.test(e.target.value)) {
|
||||||
|
|
@ -602,7 +603,7 @@ const User: React.FC = () => {
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const file = document.createElement("input") as any;
|
const file = document.createElement("input") as any;
|
||||||
file.type = "file";
|
file.type = "file";
|
||||||
// file.accept = ".xls,.xlsx";
|
file.accept = ".xls,.xlsx";
|
||||||
file.onchange = async () => {
|
file.onchange = async () => {
|
||||||
const setting = await JSON.parse(storage.getItem('setting') as string)
|
const setting = await JSON.parse(storage.getItem('setting') as string)
|
||||||
const fileInfo = file.files[0];
|
const fileInfo = file.files[0];
|
||||||
|
|
@ -669,7 +670,7 @@ const User: React.FC = () => {
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const file = document.createElement("input") as any;
|
const file = document.createElement("input") as any;
|
||||||
file.type = "file";
|
file.type = "file";
|
||||||
// file.accept = ".xls,.xlsx";
|
file.accept = ".xls,.xlsx";
|
||||||
file.onchange = async () => {
|
file.onchange = async () => {
|
||||||
const setting = await JSON.parse(storage.getItem('setting') as string)
|
const setting = await JSON.parse(storage.getItem('setting') as string)
|
||||||
const fileInfo = file.files[0];
|
const fileInfo = file.files[0];
|
||||||
|
|
@ -762,12 +763,17 @@ const User: React.FC = () => {
|
||||||
<Button type="primary" style={{ backgroundColor: '#31353A', marginRight: '14px' }}
|
<Button type="primary" style={{ backgroundColor: '#31353A', marginRight: '14px' }}
|
||||||
onClick={() => setSignInUserModal(false)}>取消</Button>
|
onClick={() => setSignInUserModal(false)}>取消</Button>
|
||||||
<Button type="primary" className='m-ant-btn' onClick={() => {
|
<Button type="primary" className='m-ant-btn' onClick={() => {
|
||||||
PutSigns(signInUserForm.uid, signInUserForm.currentUserList).then(res => {
|
let signInNameNull = signInUserForm.currentUserList.find((item: any) => !item.signInName)
|
||||||
if (res.code === 200) {
|
if (signInNameNull) {
|
||||||
message.success('签到绑定成功')
|
message.error('请输入用户名称');
|
||||||
setSignInUserModal(false)
|
} else {
|
||||||
}
|
PutSigns(signInUserForm.uid, signInUserForm.currentUserList).then(res => {
|
||||||
})
|
if (res.code === 200) {
|
||||||
|
message.success('签到绑定成功')
|
||||||
|
setSignInUserModal(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}}>确定</Button>
|
}}>确定</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import Avatar from '@/components/Avatar';
|
||||||
import { useEffect, useState, useRef } from "react";
|
import { useEffect, useState, useRef } from "react";
|
||||||
import { storage } from '@/utils';
|
import { storage } from '@/utils';
|
||||||
import EquipmentManagement from '@/components/EquipmentManagement';
|
import EquipmentManagement from '@/components/EquipmentManagement';
|
||||||
|
import UserName from '@/components/UserName';
|
||||||
const { confirm } = Modal;
|
const { confirm } = Modal;
|
||||||
|
|
||||||
const UserListWindow: React.FC = () => {
|
const UserListWindow: React.FC = () => {
|
||||||
|
|
@ -14,6 +15,7 @@ const UserListWindow: React.FC = () => {
|
||||||
const [user, setUser] = useState<any>({});
|
const [user, setUser] = useState<any>({});
|
||||||
const [roomUserList, setRoomUserList] = useState<any>([])
|
const [roomUserList, setRoomUserList] = useState<any>([])
|
||||||
const equipmentManagementRef = useRef<any>();
|
const equipmentManagementRef = useRef<any>();
|
||||||
|
const userNameRef = useRef<any>();
|
||||||
const channel = new BroadcastChannel('meeting_channel');
|
const channel = new BroadcastChannel('meeting_channel');
|
||||||
const userInfo = JSON.parse(storage.getItem('user') as string)
|
const userInfo = JSON.parse(storage.getItem('user') as string)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -149,6 +151,18 @@ const UserListWindow: React.FC = () => {
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>移出会议</Button>
|
>移出会议</Button>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
className='m-ant-btn'
|
||||||
|
style={{ width: '100%', marginTop: '10px' }}
|
||||||
|
size={'small'}
|
||||||
|
onClick={() => {
|
||||||
|
userNameRef.current.changeModal({
|
||||||
|
userName: item.userName,
|
||||||
|
uid: item.uid
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>修改用户名</Button>
|
||||||
</div>
|
</div>
|
||||||
}>
|
}>
|
||||||
<EllipsisOutlined style={{
|
<EllipsisOutlined style={{
|
||||||
|
|
@ -192,6 +206,7 @@ const UserListWindow: React.FC = () => {
|
||||||
}}>全员静音</div>
|
}}>全员静音</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<UserName ref={userNameRef} />
|
||||||
<EquipmentManagement ref={equipmentManagementRef} getDriver={(uid: string) => {
|
<EquipmentManagement ref={equipmentManagementRef} getDriver={(uid: string) => {
|
||||||
channel.postMessage({
|
channel.postMessage({
|
||||||
type: 'userListWindowEquipmentManagement',
|
type: 'userListWindowEquipmentManagement',
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import { fixWebmDuration } from "webm-duration-fix-buffer";
|
||||||
import { getKeyOpenChildWindow, setKeyOpenChildWindow } from '@/utils/package/public';
|
import { getKeyOpenChildWindow, setKeyOpenChildWindow } from '@/utils/package/public';
|
||||||
import MeetingDisconnected from '@/components/MeetingDisconnected';
|
import MeetingDisconnected from '@/components/MeetingDisconnected';
|
||||||
import SingIn from '@/components/SingIn';
|
import SingIn from '@/components/SingIn';
|
||||||
|
import UserName from '@/components/UserName';
|
||||||
const { setTimeout, setInterval, clearTimeout, clearInterval } = require('timers');
|
const { setTimeout, setInterval, clearTimeout, clearInterval } = require('timers');
|
||||||
const { confirm } = Modal;
|
const { confirm } = Modal;
|
||||||
const { exec } = require('child_process');
|
const { exec } = require('child_process');
|
||||||
|
|
@ -39,7 +40,9 @@ const Meeting: React.FC = () => {
|
||||||
const equipmentManagementRef = useRef<any>();
|
const equipmentManagementRef = useRef<any>();
|
||||||
const meetingDisconnectedRef = useRef<any>();
|
const meetingDisconnectedRef = useRef<any>();
|
||||||
const singInRef = useRef<any>();
|
const singInRef = useRef<any>();
|
||||||
|
const userNameRef = useRef<any>();
|
||||||
const [isClicked, setIsClicked] = useState(false);
|
const [isClicked, setIsClicked] = useState(false);
|
||||||
|
const [isClickedMediaSteam, setIsClickedMediaSteam] = useState(false);
|
||||||
const [statusList, setStatusList] = useState({
|
const [statusList, setStatusList] = useState({
|
||||||
userList: false,
|
userList: false,
|
||||||
userChatList: false,
|
userChatList: false,
|
||||||
|
|
@ -431,7 +434,7 @@ const Meeting: React.FC = () => {
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
const setting = await JSON.parse(storage.getItem('setting') as string);
|
const setting = await JSON.parse(storage.getItem('setting') as string);
|
||||||
const stateInfo = await JSON.parse(storage.getItem('stateInfo') as string);
|
const stateInfo = await JSON.parse(storage.getItem('stateInfo') as string);
|
||||||
if (stateInfo && setting.isRecordingTips) {
|
if (stateInfo && setting.isRecordingTips && location.href.indexOf('/meeting') !== -1) {
|
||||||
setRecorder((data: any) => {
|
setRecorder((data: any) => {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
setIsScreenCapture(bool => {
|
setIsScreenCapture(bool => {
|
||||||
|
|
@ -855,6 +858,10 @@ const Meeting: React.FC = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
// 修改用户名称
|
||||||
|
case 'ModifyNickName':
|
||||||
|
setAllUserListData('ModifyNickName', item)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return () => {
|
return () => {
|
||||||
|
|
@ -912,6 +919,18 @@ const Meeting: React.FC = () => {
|
||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
}, [isClicked]);
|
}, [isClicked]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let timer: NodeJS.Timeout;
|
||||||
|
|
||||||
|
if (isClickedMediaSteam) {
|
||||||
|
timer = setTimeout(() => {
|
||||||
|
setIsClickedMediaSteam(false)
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
}, [isClickedMediaSteam]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const elements = document.querySelectorAll('.intersectionObserver-view');
|
const elements = document.querySelectorAll('.intersectionObserver-view');
|
||||||
if (elements.length && currentVideoId) {
|
if (elements.length && currentVideoId) {
|
||||||
|
|
@ -1276,6 +1295,15 @@ const Meeting: React.FC = () => {
|
||||||
return res
|
return res
|
||||||
})
|
})
|
||||||
break;
|
break;
|
||||||
|
case 'ModifyNickName':
|
||||||
|
setRoomUserList((res: any) => {
|
||||||
|
let userItem = res.find((row: any) => row.uid == item.uid)
|
||||||
|
if (userItem) {
|
||||||
|
userItem.userName = item.nickName
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
})
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
changeAgoraDevice()
|
changeAgoraDevice()
|
||||||
}
|
}
|
||||||
|
|
@ -1506,52 +1534,57 @@ const Meeting: React.FC = () => {
|
||||||
case '录制':
|
case '录制':
|
||||||
const setting = await JSON.parse(storage.getItem('setting') as string);
|
const setting = await JSON.parse(storage.getItem('setting') as string);
|
||||||
try {
|
try {
|
||||||
await fs.access(setting.recordingFilesPath, fs.constants.F_OK);
|
if (!isClickedMediaSteam) {
|
||||||
footerListTemplate[itemIndex][rowIndex].title = '录制中';
|
setIsClickedMediaSteam(true)
|
||||||
footerListTemplate[itemIndex][rowIndex].active = true;
|
await fs.access(setting.recordingFilesPath, fs.constants.F_OK);
|
||||||
setFooterList(footerListTemplate);
|
footerListTemplate[itemIndex][rowIndex].title = '录制中';
|
||||||
window.electron.getSources().then(async (sources: any) => {
|
footerListTemplate[itemIndex][rowIndex].active = true;
|
||||||
const screenId = sources[0].id;
|
setFooterList(footerListTemplate);
|
||||||
const stream = await navigator.mediaDevices.getUserMedia({
|
window.electron.getSources().then(async (sources: any) => {
|
||||||
audio: {
|
const screenId = sources[0].id;
|
||||||
mandatory: {
|
const stream = await navigator.mediaDevices.getUserMedia({
|
||||||
chromeMediaSource: 'desktop',
|
audio: {
|
||||||
chromeMediaSourceId: screenId,
|
mandatory: {
|
||||||
}
|
chromeMediaSource: 'desktop',
|
||||||
} as any,
|
chromeMediaSourceId: screenId,
|
||||||
video: {
|
}
|
||||||
mandatory: {
|
} as any,
|
||||||
chromeMediaSource: 'desktop',
|
video: {
|
||||||
chromeMediaSourceId: screenId,
|
mandatory: {
|
||||||
}
|
chromeMediaSource: 'desktop',
|
||||||
} as any
|
chromeMediaSourceId: screenId,
|
||||||
|
}
|
||||||
|
} as any
|
||||||
|
});
|
||||||
|
// 获取所有音频输入设备
|
||||||
|
const devices = await navigator.mediaDevices.enumerateDevices();
|
||||||
|
const audioInputDevices = devices.filter(device => device.kind === 'audioinput' &&
|
||||||
|
device.deviceId !== 'default' &&
|
||||||
|
device.deviceId !== 'communications');
|
||||||
|
// 使用Web Audio API来捕获系统声音和麦克风声音,将它们合并到同一个MediaStream中。
|
||||||
|
const audioCtx = new (window.AudioContext || (window as any).webkitAudioContext)();
|
||||||
|
const systemSoundSource = audioCtx.createMediaStreamSource(stream);
|
||||||
|
const systemSoundDestination = audioCtx.createMediaStreamDestination();
|
||||||
|
systemSoundSource.connect(systemSoundDestination);
|
||||||
|
// 录制所有音频输入设备
|
||||||
|
audioInputDevices.forEach(async device => {
|
||||||
|
const micStream = await navigator.mediaDevices.getUserMedia({ audio: { deviceId: { exact: device.deviceId } } });
|
||||||
|
setMediaStream((res: any) => [...res, micStream]);
|
||||||
|
const micSoundSource = audioCtx.createMediaStreamSource(micStream);
|
||||||
|
micSoundSource.connect(systemSoundDestination);
|
||||||
|
})
|
||||||
|
// 合并音频流与视频流
|
||||||
|
const combinedSource = new MediaStream([...stream.getVideoTracks(), ...systemSoundDestination.stream.getAudioTracks()]);
|
||||||
|
// 开始录制
|
||||||
|
const mediaRecorder = new MediaRecorder(combinedSource, {
|
||||||
|
mimeType: 'video/webm;codecs=vp9,opus',
|
||||||
|
videoBitsPerSecond: 1.5e6,
|
||||||
|
});
|
||||||
|
setRecorder(mediaRecorder);
|
||||||
});
|
});
|
||||||
// 获取所有音频输入设备
|
} else {
|
||||||
const devices = await navigator.mediaDevices.enumerateDevices();
|
message.error('录制太频繁了,请稍后重试!');
|
||||||
const audioInputDevices = devices.filter(device => device.kind === 'audioinput' &&
|
}
|
||||||
device.deviceId !== 'default' &&
|
|
||||||
device.deviceId !== 'communications');
|
|
||||||
// 使用Web Audio API来捕获系统声音和麦克风声音,将它们合并到同一个MediaStream中。
|
|
||||||
const audioCtx = new (window.AudioContext || (window as any).webkitAudioContext)();
|
|
||||||
const systemSoundSource = audioCtx.createMediaStreamSource(stream);
|
|
||||||
const systemSoundDestination = audioCtx.createMediaStreamDestination();
|
|
||||||
systemSoundSource.connect(systemSoundDestination);
|
|
||||||
// 录制所有音频输入设备
|
|
||||||
audioInputDevices.forEach(async device => {
|
|
||||||
const micStream = await navigator.mediaDevices.getUserMedia({ audio: { deviceId: { exact: device.deviceId } } });
|
|
||||||
setMediaStream((res: any) => [...res, micStream]);
|
|
||||||
const micSoundSource = audioCtx.createMediaStreamSource(micStream);
|
|
||||||
micSoundSource.connect(systemSoundDestination);
|
|
||||||
})
|
|
||||||
// 合并音频流与视频流
|
|
||||||
const combinedSource = new MediaStream([...stream.getVideoTracks(), ...systemSoundDestination.stream.getAudioTracks()]);
|
|
||||||
// 开始录制
|
|
||||||
const mediaRecorder = new MediaRecorder(combinedSource, {
|
|
||||||
mimeType: 'video/webm;codecs=vp9,opus',
|
|
||||||
videoBitsPerSecond: 1.5e6,
|
|
||||||
});
|
|
||||||
setRecorder(mediaRecorder);
|
|
||||||
});
|
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
if (error.code === 'ENOENT') {
|
if (error.code === 'ENOENT') {
|
||||||
message.error({
|
message.error({
|
||||||
|
|
@ -1567,10 +1600,14 @@ const Meeting: React.FC = () => {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case '录制中':
|
case '录制中':
|
||||||
footerListTemplate[itemIndex][rowIndex].title = '录制'
|
if (isClickedMediaSteam) {
|
||||||
footerListTemplate[itemIndex][rowIndex].active = false
|
message.error('录制时长不足3秒,请稍后重试!');
|
||||||
setFooterList(footerListTemplate)
|
} else {
|
||||||
stopRecorderMedia()
|
footerListTemplate[itemIndex][rowIndex].title = '录制'
|
||||||
|
footerListTemplate[itemIndex][rowIndex].active = false
|
||||||
|
setFooterList(footerListTemplate)
|
||||||
|
stopRecorderMedia()
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case '共享文件':
|
case '共享文件':
|
||||||
sharedFilesModelRef.current.getData()
|
sharedFilesModelRef.current.getData()
|
||||||
|
|
@ -2329,6 +2366,17 @@ const Meeting: React.FC = () => {
|
||||||
getRoomKickout(state.channelId, item.uid, item.userName)
|
getRoomKickout(state.channelId, item.uid, item.userName)
|
||||||
}}
|
}}
|
||||||
>移出会议</Button> : null}
|
>移出会议</Button> : null}
|
||||||
|
{item.uid !== user.uid ? <Button
|
||||||
|
type="primary"
|
||||||
|
className='m-ant-btn'
|
||||||
|
size={'small'}
|
||||||
|
onClick={() => {
|
||||||
|
userNameRef.current.changeModal({
|
||||||
|
userName: item.userName,
|
||||||
|
uid: item.uid
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>修改用户名</Button> : null}
|
||||||
</div>
|
</div>
|
||||||
}>
|
}>
|
||||||
<div className={styles.meetingContentOperation}>
|
<div className={styles.meetingContentOperation}>
|
||||||
|
|
@ -2487,6 +2535,18 @@ const Meeting: React.FC = () => {
|
||||||
getRoomKickout(state.channelId, item.uid, item.userName)
|
getRoomKickout(state.channelId, item.uid, item.userName)
|
||||||
}}
|
}}
|
||||||
>移出会议</Button>
|
>移出会议</Button>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
className='m-ant-btn'
|
||||||
|
style={{ width: '100%', marginTop: '10px' }}
|
||||||
|
size={'small'}
|
||||||
|
onClick={() => {
|
||||||
|
userNameRef.current.changeModal({
|
||||||
|
userName: item.userName,
|
||||||
|
uid: item.uid
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>修改用户名</Button>
|
||||||
</div>
|
</div>
|
||||||
}>
|
}>
|
||||||
<EllipsisOutlined style={{ color: '#fff', fontSize: '20px' }} />
|
<EllipsisOutlined style={{ color: '#fff', fontSize: '20px' }} />
|
||||||
|
|
@ -2995,6 +3055,7 @@ const Meeting: React.FC = () => {
|
||||||
<EquipmentManagement ref={equipmentManagementRef} />
|
<EquipmentManagement ref={equipmentManagementRef} />
|
||||||
<MeetingDisconnected ref={meetingDisconnectedRef} />
|
<MeetingDisconnected ref={meetingDisconnectedRef} />
|
||||||
<SingIn ref={singInRef} />
|
<SingIn ref={singInRef} />
|
||||||
|
<UserName ref={userNameRef} />
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue