Merge pull request '重新打开应用是否自动登录判断优化' (#18) from yangjie into master

Reviewed-on: #18
This commit is contained in:
yangqiang 2024-10-11 14:15:18 +08:00
commit 8f2f93d0a4
18 changed files with 509 additions and 203 deletions

25
main.js
View File

@ -17,6 +17,7 @@ const { autoUpdater, CancellationToken } = require('electron-updater');
const cancellationToken = new CancellationToken()
app.allowRendererProcessReuse = false;
let mainWindow = null;
let childWindow = {}
let isMaximized = false;
let env;
let regKey;
@ -299,6 +300,30 @@ app.on('ready', () => {
})
});
});
// 创建子窗口
ipcMain.handle('createChildWindow', (event, config) => {
const child = new BrowserWindow({
parent: mainWindow,
webPreferences: {
contextIsolation: false,
nodeIntegration: true,
enableRemoteModule: true,
nodeIntegrationInWorker: true,
allowMediaDevices: true,
preload: path.join(__dirname, 'preload.js')
},
show: false,
frame: false,
backgroundColor: '#00000000',
transparent: true,
})
child.loadURL(config.url)
childWindow[config.key] = child
child.once('ready-to-show', () => {
child.show()
child.setSize(config.width, config.height)
})
});
}
});
// 检测更新在你想要检查更新的时候执行renderer事件触发后的操作自行编写

View File

@ -73,4 +73,8 @@ window.electron = {
setRegistry: (uuid) => {
ipcRenderer.invoke('setRegistry', uuid)
},
// 创建子窗口
createChildWindow: (config) => {
ipcRenderer.invoke('createChildWindow', config)
},
}

View File

@ -18,6 +18,7 @@ import { agora } from "@/utils/package/agora";
import QuitTips from "@/components/QuitTips";
import { GetLeave } from "@/api/Meeting";
import path from "path";
import ShareScreenWindow from "./page/ShareScreenWindow";
const fs = require('fs').promises;
const { exec } = require('child_process');
const App: React.FC = () => {
@ -32,10 +33,11 @@ const App: React.FC = () => {
});
const [spinning, setSpinning] = useState(false);
const [isState, setIsState] = useState(true);
if (location.hash.indexOf('shareScreenWindow') == -1) {
useEffect(() => {
let userInfo = JSON.parse(storage.getItem('user') as string)
let loginInfo = JSON.parse(storage.getItem('login') as string)
if (userInfo && Number(userInfo.perms)) {
if (userInfo && !userInfo.isAnonymous) {
if (loginInfo && loginInfo.isAutoLogin) {
PostLogin({
account: loginInfo.account,
@ -148,6 +150,7 @@ const App: React.FC = () => {
onStop()
}
}, [navigate])
}
useEffect(() => {
document.addEventListener('keydown', (event) => {
if (event.key === 'F11') {
@ -239,6 +242,7 @@ const App: React.FC = () => {
</Route>
<Route path='/login' element={<Login />} />
<Route path='/meeting' element={<Meeting />} />
<Route path='/shareScreenWindow' element={<ShareScreenWindow />} />
<Route path='*' element={<NotFound />} />
</Routes>
<Spin spinning={spinning} fullscreen />

View File

@ -11,6 +11,12 @@ export const PostRoom = (data: any) =>
method: 'post',
data,
})
export const PostRoomInfo = (data: any) =>
request({
url: `/home/room-info`,
method: 'put',
data,
})
export const DeleteRoom = (roomId: string) =>
request({
url: `/home/room?roomId=${roomId}`,

View File

@ -19,6 +19,13 @@ export const PutUser = (data: any) =>
method: 'put',
data
})
export const PutUserBth = (data: any) =>
request({
url: `/user/bth`,
method: 'put',
data
})
export const DeleteUser = (data: any) =>
request({
url: `/user`,
@ -33,6 +40,12 @@ export const PutUserPwd = (data: { id: string, pwd: string }) =>
data
})
export const GetSubDpList = () =>
request({
url: `/pub/sub-dp-list`,
method: 'get',
})
export const GetRoleDpList = () =>
request({
url: `/pub/role-dp-list`,

View File

@ -158,7 +158,7 @@ const InvitingPersonnelModal = forwardRef((props: any, ref: any) => {
</div>
</div>) : <span style={{ display: 'block', textAlign: 'center', color: 'white', padding: '30px 0' }}></span>}
</div>
<Pagination size="small" total={list.total} style={{ flexShrink: 0, margin: '10px 0 0' }} onChange={(e) => {
<Pagination size="small" total={list.total} showSizeChanger={false} style={{ flexShrink: 0, margin: '10px 0 0' }} onChange={(e) => {
setList({
...list,
pageIndex: e

View File

@ -341,7 +341,7 @@ const SharedFilesModel = forwardRef((props: any, ref: any) => {
...fileList,
pageIndex: e
})
}} pageSize={fileList.pageSize} current={fileList.pageIndex} hideOnSinglePage={true} />
}} pageSize={fileList.pageSize} current={fileList.pageIndex} hideOnSinglePage={true} showSizeChanger={false}/>
</div>
</div>
</div>

View File

@ -3,7 +3,7 @@ import App from './App.tsx'
import '@/utils/styles/main.css'
import { HashRouter } from 'react-router-dom';
import { ConfigProvider } from 'antd';
import zhCN from 'antd/locale/zh_CN';
import zhCN from 'antd/es/locale/zh_CN';
import 'animate.css';
ReactDOM.createRoot(document.getElementById('root')!).render(
<HashRouter>

View File

@ -1,8 +1,8 @@
import styles from '@/page/Home/Index/index.module.scss'
import { useEffect, useState, useRef } from "react";
import Operation from '@/components/Operation';
import { Button, Input, Modal, Pagination, Empty, message, Popover, Popconfirm, DatePicker } from "antd";
import { GetRoom, PostRoom, GetCheckoutRoomNum, GetRoomRtcToken, DeleteRoom, GetRecord } from '@/api/Home/Index';
import { Button, Input, Modal, Pagination, Empty, message, Popover, Popconfirm, DatePicker, Select } from "antd";
import { GetRoom, PostRoom, GetCheckoutRoomNum, GetRoomRtcToken, DeleteRoom, GetRecord, PostRoomInfo } from '@/api/Home/Index';
import ImageUrl from '@/utils/package/imageUrl'
import { ExclamationCircleFilled, ReloadOutlined } from '@ant-design/icons';
import JoinSetting from '@/components/JoinSetting';
@ -12,6 +12,7 @@ import { useNavigate } from 'react-router-dom';
import { role } from '@/config/role';
import dayjs from 'dayjs';
import StupWizard from '@/components/StupWizard';
import { GetSubDpList } from '@/api/Home/User';
const fs = require('fs').promises;
const { exec } = require('child_process');
const { RangePicker } = DatePicker;
@ -26,15 +27,20 @@ const Index: React.FC = () => {
})
const [createRoomModal, setCreateRoomModal] = useState(false)
const [timeSelectModal, setTimeSelectModal] = useState(false)
const [createRoomFrom, setCreateRoomFrom] = useState<{ roomName: string, roomNum: string }>({
const [createRoomFrom, setCreateRoomFrom] = useState<{ id: string, roomName: string, roomNum: string, subject: string, year: string }>({
id: "",
roomName: "",
roomNum: ""
roomNum: "",
subject: "",
year: ""
})
const joinSettingRef = useRef<any>();
const stupWizardRef = useRef<any>();
const [user, setUser] = useState<any>({});
const [currentRoomInfo, setCurrentRoomInfo] = useState<any>({});
const [subjectList, setSubjectList] = useState<any>([]);
const [timeData, setTimeData] = useState<any>([]);
const [isCreateRoom, setIsCreateRoom] = useState<boolean>(false);
const userInfo = JSON.parse(storage.getItem('user') as string)
useEffect(() => {
setUser(userInfo)
@ -62,7 +68,12 @@ const Index: React.FC = () => {
setList({
...list,
total: res.data.total,
data: res.data.items,
data: res.data.items.map((item: any) => {
return {
...item,
open: false
}
}),
})
}
})
@ -80,6 +91,13 @@ const Index: React.FC = () => {
}
})
}
const getSubDpList = async (): Promise<void> => {
await GetSubDpList().then(res => {
if (res.code === 200) {
setSubjectList(res.data.map((item: any) => { return { value: item.value, label: item.name } }))
}
})
}
const getRoomRtcToken = async (roomNum: string, callBack: Function): Promise<void> => {
Promise.all([GetRoomRtcToken(roomNum), GetRoomRtcToken(roomNum + 'a')]).then(res => {
if (res[0].code === 200 && res[1].code === 200) {
@ -166,8 +184,13 @@ const Index: React.FC = () => {
onClick={() => {
setCreateRoomFrom({
roomName: "",
roomNum: ""
roomNum: "",
subject: "",
year: "",
id: "",
})
getSubDpList()
setIsCreateRoom(true)
setCreateRoomModal(true)
}}
style={{ marginRight: '22px' }}
@ -234,13 +257,26 @@ const Index: React.FC = () => {
okText="确定"
cancelText="取消"
>
<div></div>
<div className='meetingContentFooterPopoverDel'></div>
</Popconfirm> : null}
<div onClick={() => {
<div className='meetingContentFooterPopoverDefault' onClick={() => {
changeOpen(index, false)
setTimeSelectModal(true)
}}></div>
<div onClick={() => {
<div className='meetingContentFooterPopoverDefault' onClick={() => {
changeOpen(index, false)
setCreateRoomFrom({
roomName: item.roomName,
roomNum: item.roomNum,
subject: item.subject,
year: item.year,
id: item.id,
})
getSubDpList()
setIsCreateRoom(false)
setCreateRoomModal(true)
}}></div>
<div className='meetingContentFooterPopoverCancel' onClick={() => {
changeOpen(index, false)
}}></div>
</div>
@ -298,19 +334,19 @@ const Index: React.FC = () => {
</div>
}
<div className={styles.indexContentPagination}>
<Pagination size="small" total={list.total} onChange={(e) => {
<Pagination size="small" total={list.total} onChange={(e: number) => {
setList({
...list,
pageIndex: e
})
}} pageSize={list.pageSize} />
}} pageSize={list.pageSize} showSizeChanger={false} />
</div>
</div>
</div>
<Modal title="新建会议室" open={createRoomModal} footer={null} closable={false} centered width={'400px'}>
<Modal title={isCreateRoom ? '新建会议室' : '修改会议信息'} open={createRoomModal} footer={null} closable={false} centered width={'400px'}>
<div>
<div>
<Input
{isCreateRoom ? <Input
placeholder="请输入房间号"
style={{ marginBottom: '14px' }}
className={styles.letterSpacing}
@ -344,7 +380,7 @@ const Index: React.FC = () => {
>
</span>
}
/>
/> : null}
<Input.TextArea
placeholder="请输入房间名字"
style={{ marginBottom: '14px' }}
@ -358,6 +394,30 @@ const Index: React.FC = () => {
})
}}
autoSize />
<Input
placeholder="请输入届"
style={{ marginBottom: '14px' }}
value={createRoomFrom.year}
onChange={(e) => {
const regex = /^[0-9]*$/;
if (regex.test(e.target.value)) {
setCreateRoomFrom({
...createRoomFrom,
year: e.target.value
})
}
}}
/>
<Select
placeholder='请选择学科'
style={{ width: '100%', marginBottom: '14px' }}
options={subjectList}
value={createRoomFrom.subject === "" ? null : createRoomFrom.subject} onChange={(e) => {
setCreateRoomFrom({
...createRoomFrom,
subject: e
})
}} />
</div>
<div style={{
display: 'flex', justifyContent: 'center'
@ -370,6 +430,13 @@ const Index: React.FC = () => {
if (!createRoomFrom.roomNum) {
return message.error('请输入房间号!')
}
if (!createRoomFrom.year) {
return message.error('请输入届!')
}
if (createRoomFrom.subject === "") {
return message.error('请选择学科!')
}
if (isCreateRoom) {
isGetCheckoutRoomNum(createRoomFrom.roomNum, (bool: boolean) => {
if (bool) {
message.error('房间号已存在!')
@ -383,7 +450,16 @@ const Index: React.FC = () => {
})
}
})
}}></Button>
} else {
PostRoomInfo(createRoomFrom).then(res => {
if (res.code === 200) {
message.success('更新成功!')
setCreateRoomModal(false)
getRoomList()
}
})
}
}}>{isCreateRoom ? '创建' : '更新'}</Button>
</div>
</div>
</Modal>

View File

@ -3,7 +3,7 @@ import { useEffect, useState, useRef } from "react";
import Operation from '@/components/Operation';
import { Button, Input, Table, Pagination, Modal, message, Select } from "antd";
import { ExclamationCircleFilled, SearchOutlined } from '@ant-design/icons';
import { GetUserList, PostUser, PutUser, DeleteUser, PutUserPwd, GetRoleDpList, PostUserImport } from '@/api/Home/User';
import { GetUserList, PostUser, PutUser, DeleteUser, PutUserPwd, GetRoleDpList, PostUserImport, GetSubDpList, PutUserBth } from '@/api/Home/User';
import * as CryptoJS from 'crypto-js';
import ImageUrl from '@/utils/package/imageUrl';
import { storage } from '@/utils';
@ -15,7 +15,7 @@ const fs = require('fs').promises;
const User: React.FC = () => {
const stupWizardRef = useRef<any>();
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
const [isCreateUser, setIsCreateUser] = useState(false);
const [isCreateUser, setIsCreateUser] = useState<'add' | 'batch' | 'edit'>();
const [list, setList] = useState({
data: [],
searchKeywod: '',
@ -30,7 +30,9 @@ const User: React.FC = () => {
Account: "",
RoleId: null,
Pwd: "",
UserName: ""
UserName: "",
subject: null,
year: "",
})
const [changeUserPawModal, setChangeUserPawModal] = useState(false)
const [changeImportModal, setChangeImportModal] = useState(false)
@ -39,10 +41,14 @@ const User: React.FC = () => {
newPwd: '',
})
const [deleteUserPawModal, setDeleteUserPawModal] = useState(false)
const [subjectList, setSubjectList] = useState<any>([]);
useEffect(() => {
getSubDpList()
}, []);
useEffect(() => {
getUserList()
}, [list.pageIndex]);
}, [list.pageIndex, list.pageSize]);
const getUserList = async (): Promise<void> => {
await GetUserList({
@ -61,6 +67,7 @@ const User: React.FC = () => {
}
}),
})
setSelectedRowKeys([])
}
})
}
@ -118,7 +125,13 @@ const User: React.FC = () => {
}
}
}
const getSubDpList = async (): Promise<void> => {
await GetSubDpList().then(res => {
if (res.code === 200) {
setSubjectList(res.data.map((item: any) => { return { value: item.value, label: item.name } }))
}
})
}
return (
<>
<div className={styles.user}>
@ -131,13 +144,15 @@ const User: React.FC = () => {
onClick={() => {
getRoleDpList((bool: boolean) => {
if (bool) {
setIsCreateUser(true)
setIsCreateUser('add')
setAddUserFrom({
Id: "",
Account: "",
RoleId: null,
Pwd: "",
UserName: "",
subject: null,
year: "",
})
setAddUserModal(true)
}
@ -154,6 +169,31 @@ const User: React.FC = () => {
className='m-ant-btn'>
</Button>
<Button type="primary"
onClick={() => {
if (selectedRowKeys.length) {
getRoleDpList((bool: boolean) => {
if (bool) {
setIsCreateUser('batch')
setAddUserFrom({
Id: "",
Account: "",
RoleId: null,
Pwd: "",
UserName: "",
subject: null,
year: "",
})
setAddUserModal(true)
}
})
} else {
message.error('请选择需要修改的用户!')
}
}}
className='m-ant-btn'>
</Button>
<Button type="primary"
icon={<img src={ImageUrl.icon21} alt="" />}
className={styles.userBtnsDel}
@ -161,7 +201,7 @@ const User: React.FC = () => {
if (selectedRowKeys.length) {
setDeleteUserPawModal(true)
} else {
message.error('请选择要删除的用户')
message.error('请选择要删除的用户')
}
}}
>
@ -214,7 +254,13 @@ const User: React.FC = () => {
<div style={{ color: item.isOnline ? '#02B188' : 'rgb(221 11 11)' }}>{item.isOnline ? '在线' : '离线'}</div>
</>
)} />
<Column title="操作" render={(item) => (
<Column title="届" dataIndex="year" key="year" />
<Column title="学科" render={(item) => (
<>
<div>{subjectList.find((subject: any) => subject.value === item.subject)?.label}</div>
</>
)} />
<Column title="操作" width={200} render={(item) => (
<>
<Button
type="primary"
@ -223,13 +269,15 @@ const User: React.FC = () => {
onClick={() => {
getRoleDpList((bool: boolean) => {
if (bool) {
setIsCreateUser(false)
setIsCreateUser('edit')
setAddUserFrom({
...addUserFrom,
Id: item.id,
Account: item.account,
RoleId: item.roleId,
UserName: item.userName,
subject: item.subject,
year: item.year,
})
setAddUserModal(true)
}
@ -258,19 +306,20 @@ const User: React.FC = () => {
</Table>
<div className={styles.userContentPagination}>
<span>{list.total}</span>
<Pagination size="small" total={list.total} onChange={(e) => {
<Pagination size="small" total={list.total} onChange={(page, pageSize) => {
setList({
...list,
pageIndex: e
pageIndex: page,
pageSize: pageSize
})
}} pageSize={list.pageSize} current={list.pageIndex} hideOnSinglePage={true} />
}} showSizeChanger pageSizeOptions={[10, 14, 20, 30, 40, 50, 100]} pageSize={list.pageSize} current={list.pageIndex} />
</div>
</div>
</div>
<Modal title={isCreateUser ? '添加用户' : '编辑用户'} open={addUserModal} footer={null} closable={false} centered width={'500px'}>
<Modal title={isCreateUser === 'add' ? '添加用户' : isCreateUser === 'edit' ? '编辑用户' : '批量修改用户信息'} open={addUserModal} footer={null} closable={false} centered width={'500px'}>
<div>
<div className={styles.addUserModal}>
<div>
{isCreateUser !== 'batch' ? <div>
<span></span>
<Input
style={{ flexGrow: 1 }}
@ -285,7 +334,7 @@ const User: React.FC = () => {
});
}}
/>
</div>
</div> : null}
<div>
<span></span>
<Select
@ -299,7 +348,7 @@ const User: React.FC = () => {
});
}} />;
</div>
{isCreateUser ? <div>
{isCreateUser === 'add' ? <div>
<span></span>
<Input.Password
placeholder="请输入密码"
@ -313,7 +362,7 @@ const User: React.FC = () => {
}}
/>
</div> : null}
<div>
{isCreateUser !== 'batch' ? <div>
<span></span>
<Input
placeholder="请输入用户名称"
@ -326,6 +375,35 @@ const User: React.FC = () => {
});
}}
/>
</div> : null}
<div>
<span></span>
<Input
placeholder="请输入届"
value={addUserFrom.year}
onChange={(e) => {
const regex = /^[0-9]*$/;
if (regex.test(e.target.value)) {
setAddUserFrom({
...addUserFrom,
year: e.target.value
});
}
}}
/>
</div>
<div>
<span></span>
<Select
placeholder='请选择学科'
style={{ flexGrow: 1 }}
options={subjectList}
value={addUserFrom.subject} onChange={(e) => {
setAddUserFrom({
...addUserFrom,
subject: e
});
}} />
</div>
</div>
<div style={{
@ -333,43 +411,66 @@ const User: React.FC = () => {
}}>
<Button type="primary" style={{ backgroundColor: '#31353A', marginRight: '14px' }} onClick={() => setAddUserModal(false)}></Button>
<Button type="primary" className='m-ant-btn' onClick={async () => {
if (!addUserFrom.Account) {
if (!addUserFrom.Account && isCreateUser !== 'batch') {
return message.error('请输入账号!')
}
if (!addUserFrom.RoleId) {
return message.error('请选择角色!')
}
if (!addUserFrom.Pwd && isCreateUser) {
if (!addUserFrom.Pwd && isCreateUser === 'add') {
return message.error('请输入密码!')
}
if (!addUserFrom.UserName) {
if (!addUserFrom.UserName && isCreateUser !== 'batch') {
return message.error('请输入用户名称!')
}
if (isCreateUser) {
if (!addUserFrom.year) {
return message.error('请输入届!')
}
if (addUserFrom.subject === null) {
return message.error('请选择学科!')
}
if (isCreateUser === 'add') {
await PostUser({
...addUserFrom,
Pwd: CryptoJS.MD5(addUserFrom.Pwd).toString(CryptoJS.enc.Hex)
}).then(res => {
if (res.code === 200) {
setAddUserModal(false)
message.success('添加成功!')
res.data ? message.success('添加成功!') : message.error('添加失败!')
}
})
} else {
} else if (isCreateUser === 'edit') {
await PutUser({
Id: addUserFrom.Id,
Account: addUserFrom.Account,
RoleId: addUserFrom.RoleId,
UserName: addUserFrom.UserName
UserName: addUserFrom.UserName,
subject: addUserFrom.subject,
year: addUserFrom.year,
}).then(res => {
if (res.code === 200) {
setAddUserModal(false)
message.success('修改成功!')
res.data ? message.success('修改成功!') : message.error('修改失败!')
}
})
} else {
const param = selectedRowKeys.map((item: any) => {
return {
id: item,
subject: addUserFrom.subject,
year: addUserFrom.year,
RoleId: addUserFrom.RoleId,
}
})
await PutUserBth(param).then(res => {
if (res.code === 200) {
setAddUserModal(false)
res.data ? message.success('修改成功!') : message.error('修改失败!')
}
})
}
await getUserList()
}}>{isCreateUser ? '添加' : '修改'}</Button>
}}>{isCreateUser === 'add' ? '添加' : '修改'}</Button>
</div>
</div>
</Modal>
@ -442,7 +543,6 @@ const User: React.FC = () => {
DeleteUser(selectedRowKeys).then(res => {
if (res.code === 200) {
setDeleteUserPawModal(false)
setSelectedRowKeys([])
message.success('删除成功!')
getUserList()
}

View File

@ -811,7 +811,7 @@
}
}
>div:nth-child(1) {
.meetingContentFooterPopoverDel {
background-color: #FF5219;
&:hover {
@ -823,7 +823,7 @@
}
}
>div:nth-child(2) {
.meetingContentFooterPopoverDefault {
background-color: #31353A;
&:hover {
@ -835,7 +835,7 @@
}
}
>div:nth-child(3) {
.meetingContentFooterPopoverCancel {
background-color: #101418;
&:hover {

View File

@ -160,6 +160,7 @@ const Meeting: React.FC = () => {
const [noViewChatList, setNoViewChatList] = useState(0)
const [currentLookUserAccount, setCurrentLookUserAccount] = useState<any>('')
const [recorder, setRecorder] = useState<any>('')
const [_currentRequestSpeakType, setCurrentRequestSpeakType] = useState<'video' | 'audio' | ''>('')
const [_mediaStream, setMediaStream] = useState<any>('')
const [isShare, setIsShare] = useState<any>(null)
const [isSharePopConfirm, setIsSharePopConfirm] = useState<any>(false)
@ -413,13 +414,23 @@ const Meeting: React.FC = () => {
}
} else {
if (item.user.uid === userInfo.uid) {
if (!item.user.isRoomManage) {
if (!item.user.isRoomManager) {
await agora.allLeaveChannelEx()
}
message.success(`管理员${item.user.isRoomManager ? '设置' : '取消'}您为发言人`)
await agora.updateChannelMediaOptions(item.user.isRoomManager)
await postOpenMicrApi(item.user.isRoomManager, userInfo.uid, false)
await postOpenCameraApi(item.user.isRoomManager, userInfo.uid)
setCurrentRequestSpeakType(res => {
if (res === 'video') {
postOpenCameraApi(item.user.isRoomManager, userInfo.uid)
} else if (res === 'audio') {
postOpenMicrApi(item.user.isRoomManager, userInfo.uid, false)
} else {
postOpenMicrApi(item.user.isRoomManager, userInfo.uid, false)
postOpenCameraApi(item.user.isRoomManager, userInfo.uid)
}
return ''
})
await stopScreenCapture()
} else {
message.success(`管理员${item.user.isRoomManager ? '设置' : '取消'}${item.user.userName}为发言人`)
@ -602,6 +613,7 @@ const Meeting: React.FC = () => {
if (isClicked) {
timer = setTimeout(() => {
setIsClicked(false);
setCurrentRequestSpeakType('')
}, 10000);
}
@ -999,6 +1011,25 @@ const Meeting: React.FC = () => {
}
// 操作按钮
const changeStatusList = async (row: any, itemIndex: number, rowIndex: number): Promise<void> => {
function requestSpeak() {
confirm({
title: '提示',
icon: <ExclamationCircleFilled />,
content: `该操作需向管理员申请权限`,
centered: true,
okText: '申请',
cancelText: '取消',
async onOk() {
GetApplySpeak(state.channelId).then(res => {
if (res.code === 200) {
message.success('申请发言成功')
}
})
},
onCancel() {
}
})
}
const footerListTemplate = [...footerList]
setFooterListIndex({
itemIndex,
@ -1046,13 +1077,37 @@ const Meeting: React.FC = () => {
await postOpenMicr(false, user.uid)
break;
case '解除静音':
await getUserRoomInfo().then(async (res) => {
if (res) {
await postOpenMicr(true, user.uid)
} else {
if (!isClicked) {
setCurrentRequestSpeakType('audio')
setIsClicked(true);
requestSpeak()
} else {
message.error('申请太频繁了,请稍后重试!');
}
}
})
break;
case '关闭视频':
await postOpenCamera(false, user.uid)
break;
case '开启视频':
await getUserRoomInfo().then(async (res) => {
if (res) {
await postOpenCamera(true, user.uid)
} else {
if (!isClicked) {
setCurrentRequestSpeakType('video')
setIsClicked(true);
requestSpeak()
} else {
message.error('申请太频繁了,请稍后重试!');
}
}
})
break;
case '设置':
stupWizardRef.current.changeModal()
@ -1141,11 +1196,7 @@ const Meeting: React.FC = () => {
case '申请发言':
if (!isClicked) {
setIsClicked(true);
GetApplySpeak(state.channelId).then(res => {
if (res.code === 200) {
message.success('申请发言成功')
}
})
requestSpeak()
} else {
message.error('申请太频繁了,请稍后重试!');
}
@ -2177,11 +2228,11 @@ const Meeting: React.FC = () => {
okText="结束"
cancelText="取消"
>
<div></div>
<div className='meetingContentFooterPopoverDel'></div>
</Popconfirm>
: null}
<div onClick={() => leaveChannel()}></div>
<div onClick={() => { setOpen(false) }}></div>
<div className='meetingContentFooterPopoverDefault' onClick={() => leaveChannel()}></div>
<div className='meetingContentFooterPopoverCancel' onClick={() => { setOpen(false) }}></div>
</div>
}
title=""
@ -2200,12 +2251,12 @@ const Meeting: React.FC = () => {
</div>
</Popover>
case '申请发言':
if (!role.ID.includes(user.roleId)) {
return <div className='drag' onClick={() => changeStatusList(row, itemIndex, rowIndex)} key={rowIndex}>
<img src={row.active ? row.iconActive : row.icon} alt="" />
<span>{row.title}</span>
</div>
}
// if (!role.ID.includes(user.roleId)) {
// return <div className='drag' onClick={() => changeStatusList(row, itemIndex, rowIndex)} key={rowIndex}>
// <img src={row.active ? row.iconActive : row.icon} alt="" />
// <span>{row.title}</span>
// </div>
// }
return null
case '结束发言':
if (!role.ID.includes(user.roleId)) {

View File

@ -0,0 +1,7 @@
.shareScreenWindow {
background-color: red;
color: black;
height: 100%;
width: 100%;
font-size: 30px;
}

View File

@ -0,0 +1,23 @@
import styles from '@/page/ShareScreenWindow/index.module.scss'
import { useEffect } from "react";
const ShareScreenWindow: React.FC = () => {
useEffect(() => {
}, []);
// window.electron.createChildWindow({
// url: location.origin + `/#/shareScreenWindow`,
// width: 600,
// height: 40,
// key: 'shareScreenWindow',
// })
return (
<>
<div className={styles.shareScreenWindow}>
2222
</div>
</>
)
}
export default ShareScreenWindow

1
src/render.d.ts vendored
View File

@ -18,6 +18,7 @@ export interface IElectronAPI {
getVersion: () => Promise<string>;
setRegistry: (uuid: string) => any;
getRegistry: () => any;
createChildWindow: (config: any) => void;
}
declare global {

View File

@ -115,15 +115,15 @@ export const agora = {
rtcEngine.registerEventHandler({
// 监听本地用户加入频道事件
onJoinChannelSuccess: async (connection: RtcConnection, elapsed: number) => {
await onJoinChannelSuccess(connection, elapsed)
await onJoinChannelSuccess?.(connection, elapsed)
},
// 监听远端用户加入频道事件
onUserJoined: async (connection: RtcConnection, remoteUid: number, elapsed: number) => {
await onUserJoined(connection, remoteUid, elapsed)
await onUserJoined?.(connection, remoteUid, elapsed)
},
// 监听用户离开频道事件
onUserOffline: async (connection: RtcConnection, remoteUid: number, reason: UserOfflineReasonType) => {
await onUserOffline(connection, remoteUid, reason)
await onUserOffline?.(connection, remoteUid, reason)
},
// // 视频发布状态改变回调
// onVideoPublishStateChanged: (source: any, channel: any, oldState: any, newState: any, elapseSinceLastState: any) => {
@ -139,19 +139,19 @@ export const agora = {
// },
// // 用户音量提示回调。
onAudioVolumeIndication: async (_connection: RtcConnection, speakers: AudioVolumeInfo[], _speakerNumber: number, _totalVolume: number) => {
await onAudioVolumeIndication(speakers)
await onAudioVolumeIndication?.(speakers)
},
//通话中每个用户的网络上下行 last mile 质量报告回调。
onNetworkQuality: async (connection: RtcConnection, remoteUid: number, txQuality: QualityType, rxQuality: QualityType) => {
await onNetworkQuality(connection, remoteUid, txQuality, rxQuality)
await onNetworkQuality?.(connection, remoteUid, txQuality, rxQuality)
},
//当前通话相关的统计信息回调。
onRtcStats: async (_connection: RtcConnection, stats: RtcStats) => {
await onRtcStats(stats)
await onRtcStats?.(stats)
},
// 网络连接状态已改变回调。
onConnectionStateChanged: async (connection: RtcConnection, state: ConnectionStateType, reason: ConnectionChangedReasonType) => {
await onConnectionStateChanged(connection, state, reason)
await onConnectionStateChanged?.(connection, state, reason)
},
});
},

View File

@ -189,8 +189,6 @@ $pagination-hover-background-color: #5575F2;
.ant-pagination-prev,
.ant-pagination-next {
width: 30px !important;
height: 30px !important;
border-radius: 50%;
background: $pagination-background-color;
@ -200,9 +198,6 @@ $pagination-hover-background-color: #5575F2;
}
.ant-pagination-item {
width: 30px !important;
height: 30px !important;
line-height: 30px !important;
border-radius: 50%;
background: $pagination-background-color !important;
margin-right: 10px !important;

View File

@ -14,6 +14,7 @@ body {
img {
display: block;
-webkit-user-drag: none;
}