feat:会议可分享 - 60%

This commit is contained in:
weifashi 2023-08-29 17:09:32 +08:00
parent 288e265aaa
commit 3a2c40a43e
7 changed files with 95 additions and 20 deletions

View File

@ -1120,6 +1120,8 @@ class UsersController extends AbstractController
* - join: 加入会议有效参数meetingid (必填) * - join: 加入会议有效参数meetingid (必填)
* @apiParam {String} [meetingid] 频道ID不是数字 * @apiParam {String} [meetingid] 频道ID不是数字
* @apiParam {String} [name] 会话ID * @apiParam {String} [name] 会话ID
* @apiParam {String} [meetingsign] 签名
* @apiParam {String} [username] 用户名称
* @apiParam {Array} [userids] 邀请成员 * @apiParam {Array} [userids] 邀请成员
* *
* @apiSuccess {Number} ret 返回状态码1正确、0错误 * @apiSuccess {Number} ret 返回状态码1正确、0错误
@ -1128,13 +1130,15 @@ class UsersController extends AbstractController
*/ */
public function meeting__open() public function meeting__open()
{ {
$user = User::auth();
//
$type = trim(Request::input('type')); $type = trim(Request::input('type'));
$meetingid = trim(Request::input('meetingid')); $meetingid = trim(Request::input('meetingid'));
$name = trim(Request::input('name')); $name = trim(Request::input('name'));
$userids = Request::input('userids'); $userids = Request::input('userids');
$meetingsign = trim(Request::input('meetingsign'));
$username = trim(Request::input('username'));
$user = empty($meetingsign) ? User::auth() : null;
$isCreate = false; $isCreate = false;
// 创建、加入 // 创建、加入
if ($type === 'join') { if ($type === 'join') {
$meeting = Meeting::whereMeetingid($meetingid)->first(); $meeting = Meeting::whereMeetingid($meetingid)->first();
@ -1143,13 +1147,13 @@ class UsersController extends AbstractController
} }
} elseif ($type === 'create') { } elseif ($type === 'create') {
$meetingid = strtoupper(Base::generatePassword(11, 1)); $meetingid = strtoupper(Base::generatePassword(11, 1));
$name = $name ?: "{$user->nickname} 发起的会议"; $name = $name ?: "{$user?->nickname} 发起的会议";
$channel = "DooTask:" . substr(md5($meetingid . env("APP_KEY")), 16); $channel = "DooTask:" . substr(md5($meetingid . env("APP_KEY")), 16);
$meeting = Meeting::createInstance([ $meeting = Meeting::createInstance([
'meetingid' => $meetingid, 'meetingid' => $meetingid,
'name' => $name, 'name' => $name,
'channel' => $channel, 'channel' => $channel,
'userid' => $user->userid 'userid' => $user?->userid
]); ]);
$meeting->save(); $meeting->save();
$isCreate = true; $isCreate = true;
@ -1165,7 +1169,7 @@ class UsersController extends AbstractController
if (empty($meetingSetting['appid']) || empty($meetingSetting['app_certificate'])) { if (empty($meetingSetting['appid']) || empty($meetingSetting['app_certificate'])) {
return Base::retError('会议功能配置错误,请联系管理员'); return Base::retError('会议功能配置错误,请联系管理员');
} }
$uid = intval(str_pad( Request::header('fd'), 6, 9, STR_PAD_LEFT) . $user->userid); $uid = intval(str_pad( Request::header('fd'), 6, 9, STR_PAD_LEFT) . $user?->userid);
try { try {
$service = new AgoraTokenGenerator($meetingSetting['appid'], $meetingSetting['app_certificate'], $meeting->channel, $uid); $service = new AgoraTokenGenerator($meetingSetting['appid'], $meetingSetting['app_certificate'], $meeting->channel, $uid);
} catch (\Exception $e) { } catch (\Exception $e) {
@ -1194,8 +1198,8 @@ class UsersController extends AbstractController
// //
$data['appid'] = $meetingSetting['appid']; $data['appid'] = $meetingSetting['appid'];
$data['uid'] = $uid; $data['uid'] = $uid;
$data['userimg'] = $user->userimg; $data['userimg'] = $meetingsign ? 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png' : $user?->userimg;
$data['nickname'] = $user->nickname; $data['nickname'] = $meetingsign ? $username : $user?->nickname;
$data['token'] = $token; $data['token'] = $token;
$data['msgs'] = $msgs; $data['msgs'] = $msgs;
return Base::retSuccess('success', $data); return Base::retSuccess('success', $data);

View File

@ -438,4 +438,16 @@ class IndexController extends InvokeController
} }
return implode("\n", array_values($array)); return implode("\n", array_values($array));
} }
/**
* 提取所有中文
* @return array|string
*/
public function meeting__share()
{
return response()->view('meeting.share', [
'version' => Base::getVersion(),
])->header('Link', "<" . url('manifest.txt') . ">; rel=\"prefetch\"");
}
} }

View File

@ -4,13 +4,17 @@
<Modal <Modal
v-model="addShow" v-model="addShow"
:title="$L(addData.type === 'join' ? '加入会议' : '新会议')" :title="$L(addData.type === 'join' ? '加入会议' : '新会议')"
:mask-closable="false"> :mask-closable="false"
:closable="!addData.meetingsign">
<Form ref="addForm" :model="addData" label-width="auto" @submit.native.prevent> <Form ref="addForm" :model="addData" label-width="auto" @submit.native.prevent>
<template v-if="addData.type === 'join'"> <template v-if="addData.type === 'join'">
<!-- 加入会议 --> <!-- 加入会议 -->
<FormItem v-if="addData.name" prop="userids" :label="$L('会议主题')"> <FormItem v-if="addData.name" prop="userids" :label="$L('会议主题')">
<Input v-model="addData.name" disabled/> <Input v-model="addData.name" disabled/>
</FormItem> </FormItem>
<FormItem v-if="addData.meetingsign" prop="username" :label="$L('你的姓名')">
<Input v-model="addData.username" :placeholder="$L('请输入你的姓名')"/>
</FormItem>
<FormItem prop="meetingid" :label="$L('会议频道ID')"> <FormItem prop="meetingid" :label="$L('会议频道ID')">
<Input v-model="addData.meetingid" :disabled="addData.meetingdisabled === true" :placeholder="$L('请输入会议频道ID')"/> <Input v-model="addData.meetingid" :disabled="addData.meetingdisabled === true" :placeholder="$L('请输入会议频道ID')"/>
</FormItem> </FormItem>
@ -36,7 +40,7 @@
</FormItem> </FormItem>
</Form> </Form>
<div slot="footer" class="adaption"> <div slot="footer" class="adaption">
<Button type="default" @click="addShow=false">{{$L('取消')}}</Button> <Button type="default" @click="addShow=false" v-if="!addData.meetingsign">{{$L('取消')}}</Button>
<Button type="primary" :loading="loadIng > 0" @click="onSubmit">{{$L(addData.type === 'join' ? '加入会议' : '开始会议')}}</Button> <Button type="primary" :loading="loadIng > 0" @click="onSubmit">{{$L(addData.type === 'join' ? '加入会议' : '开始会议')}}</Button>
</div> </div>
</Modal> </Modal>
@ -56,7 +60,8 @@
<ul> <ul>
<li v-if="localUser.uid"> <li v-if="localUser.uid">
<MeetingPlayer :player="localUser" isLocal/> <MeetingPlayer :player="localUser" isLocal/>
</li><li v-for="user in remoteUsers"> </li>
<li v-for="user in remoteUsers">
<MeetingPlayer :player="user"/> <MeetingPlayer :player="user"/>
</li> </li>
</ul> </ul>
@ -71,17 +76,17 @@
<Button type="primary" @click="onInvitation('open')"> <Button type="primary" @click="onInvitation('open')">
<i class="taskfont">&#xe646;</i> <i class="taskfont">&#xe646;</i>
</Button> </Button>
<Button type="primary" @click="meetingMini = true"> <Button type="primary" v-if="!addData.meetingsign" @click="meetingMini = true">
<i class="taskfont">&#xe656;</i> <i class="taskfont">&#xe656;</i>
</Button> </Button>
<Button type="warning" :loading="loadIng > 0" @click="onClose"> <Button type="warning" v-if="!addData.meetingsign" :loading="loadIng > 0" @click="onClose">
<i class="taskfont">&#xe612;</i> <i class="taskfont">&#xe612;</i>
</Button> </Button>
</template> </template>
<template v-else> <template v-else>
<Button type="primary" @click="onInvitation('open')">{{$L('邀请')}}</Button> <Button type="primary" @click="onInvitation('open')">{{$L('邀请')}}</Button>
<Button type="primary" @click="meetingMini = true">{{$L('最小化')}}</Button> <Button type="primary" v-if="!addData.meetingsign" @click="meetingMini = true">{{$L('最小化')}}</Button>
<Button type="warning" :loading="loadIng > 0" @click="onClose">{{$L('离开会议')}}</Button> <Button type="warning" v-if="!addData.meetingsign" :loading="loadIng > 0" @click="onClose">{{$L('离开会议')}}</Button>
</template> </template>
</div> </div>
</Modal> </Modal>
@ -118,13 +123,21 @@
<script> <script>
import {Store} from "le5le-store"; import {Store} from "le5le-store";
import {mapState} from 'vuex' import {mapState} from 'vuex'
import MeetingPlayer from "./MeetingPlayer"; import MeetingPlayer from "./MeetingPlayer.vue";
import DragBallComponent from "../../../components/DragBallComponent"; import DragBallComponent from "../../../components/DragBallComponent";
import UserSelect from "../../../components/UserSelect.vue"; import UserSelect from "../../../components/UserSelect.vue";
export default { export default {
name: "MeetingManager", name: "MeetingManager",
components: {UserSelect, DragBallComponent, MeetingPlayer}, components: {UserSelect, DragBallComponent, MeetingPlayer},
props: {
id: {
type: String,
default: () => {
return "meeting-player-" + Math.round(Math.random() * 10000);
}
}
},
data() { data() {
return { return {
loadIng: 0, loadIng: 0,
@ -180,11 +193,22 @@ export default {
}, },
meetingWindow: { meetingWindow: {
handler(val) { handler(val) {
console.log(val)
switch (val.type) { switch (val.type) {
case 'add': case 'add':
this.addShow = val.show; this.addShow = val.show;
this.loadIng = 0; this.loadIng = 0;
break; break;
case 'join':
this.addShow = val.show;
this.loadIng = 0;
this.addData.type = 'join';
if(val.meetingsign){
this.addData.meetingid = val.meetingid || '';
this.addData.meetingdisabled = val.meetingsign ? true : false;
this.addData.meetingsign = val.meetingsign;
}
break;
case 'invitation': case 'invitation':
this.invitationShow = val.show; this.invitationShow = val.show;
this.invitationLoad = false; this.invitationLoad = false;
@ -352,6 +376,7 @@ export default {
}, },
async join(options) { async join(options) {
console.log(options)
this.loadIng++; this.loadIng++;
// //
AgoraRTC.onMicrophoneChanged = async (changedDevice) => { AgoraRTC.onMicrophoneChanged = async (changedDevice) => {

View File

@ -1,5 +1,5 @@
<template> <template>
<div v-if="userid" class="meeting-player"> <div class="meeting-player">
<div :id="id" class="player" :style="playerStyle"></div> <div :id="id" class="player" :style="playerStyle"></div>
<UserAvatar :userid="userid" :size="36" :borderWitdh="2"/> <UserAvatar :userid="userid" :size="36" :borderWitdh="2"/>
<div class="player-state"> <div class="player-state">
@ -52,6 +52,7 @@ export default {
...mapState(['cacheUserBasic']), ...mapState(['cacheUserBasic']),
userid() { userid() {
if (this.player.uid) { if (this.player.uid) {
console.log(parseInt( (this.player.uid+"").substring(6) ));
return parseInt( (this.player.uid+"").substring(6) ) return parseInt( (this.player.uid+"").substring(6) )
} }
return 0 return 0
@ -62,8 +63,11 @@ export default {
return { return {
backgroundImage: `url("${user.userimg}")` backgroundImage: `url("${user.userimg}")`
} }
}else{
return {
backgroundColor: '#000000'
}
} }
return null;
}, },
audio() { audio() {
return !!this.player.audioTrack return !!this.player.audioTrack

View File

@ -0,0 +1,23 @@
<template>
<div>
<MeetingManager/>
</div>
</template>
<script>
import MeetingManager from "./manage/components/MeetingManager.vue";
export default {
components: {
MeetingManager,
},
mounted() {
this.$store.dispatch("showMeetingWindow",{
type: "join",
meetingsign: 'sign',
meetingid: 10812486455,
meetingdisabled: true,
})
},
}
</script>

View File

@ -9,6 +9,11 @@ export default [
path: '/pro', path: '/pro',
component: () => import('./pages/pro.vue'), component: () => import('./pages/pro.vue'),
}, },
{
name: 'meeting',
path: '/meeting',
component: () => import('./pages/meeting.vue'),
},
{ {
name: 'manage', name: 'manage',
path: '/manage', path: '/manage',

View File

@ -3608,11 +3608,13 @@ export default {
* @param type * @param type
* @param meetingid * @param meetingid
*/ */
showMeetingWindow({state}, {type, meetingid}) { showMeetingWindow({state}, {type, meetingid, meetingdisabled, meetingsign}) {
state.meetingWindow = { state.meetingWindow = {
show: true, show: true,
type: type, type: type,
meetingid: meetingid meetingid: meetingid,
meetingdisabled: meetingdisabled,
meetingsign: meetingsign
}; };
}, },