diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php
index ae9cde3f7..307e758c4 100755
--- a/app/Http/Controllers/Api/UsersController.php
+++ b/app/Http/Controllers/Api/UsersController.php
@@ -1175,6 +1175,7 @@ class UsersController extends AbstractController
* @apiParam {String} [name] 会话ID
* @apiParam {String} [sharekey] 分享的key
* @apiParam {String} [username] 用户名称
+ * @apiParam {String} [userimg] 用户头像
* @apiParam {Array} [userids] 邀请成员
*
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
@@ -1189,6 +1190,7 @@ class UsersController extends AbstractController
$userids = Request::input('userids');
$sharekey = trim(Request::input('sharekey'));
$username = trim(Request::input('username'));
+ $userimg = trim(Request::input('userimg')) ?: Base::fillUrl('avatar/' . $username . '.png');
$user = null;
if (!empty($sharekey) && $type === 'join') {
if (!Meeting::getShareInfo($sharekey)) {
@@ -1266,7 +1268,7 @@ class UsersController extends AbstractController
//
$data['appid'] = $meetingSetting['appid'];
$data['uid'] = $uid;
- $data['userimg'] = $sharekey ? Base::fillUrl('avatar/' . $username . '.png') : $user?->userimg;
+ $data['userimg'] = $sharekey ? $userimg : $user?->userimg;
$data['nickname'] = $sharekey ? $username : $user?->nickname;
$data['token'] = $token;
$data['msgs'] = $msgs;
diff --git a/resources/assets/js/App.vue b/resources/assets/js/App.vue
index 3b79c11f4..684b243e1 100755
--- a/resources/assets/js/App.vue
+++ b/resources/assets/js/App.vue
@@ -7,6 +7,9 @@
+
+
+
@@ -43,11 +46,13 @@ import PreviewImageState from "./components/PreviewImage/state";
import NetworkException from "./components/NetworkException";
import GuidePage from "./components/GuidePage";
import TaskOperation from "./pages/manage/components/TaskOperation";
+import MeetingManager from "./pages/manage/components/MeetingManager";
import DropdownMenu from "./components/DropdownMenu";
import {mapState} from "vuex";
export default {
components: {
+ MeetingManager,
DropdownMenu,
TaskOperation,
NetworkException,
diff --git a/resources/assets/js/pages/manage.vue b/resources/assets/js/pages/manage.vue
index 571aa0a5d..10ba122a4 100644
--- a/resources/assets/js/pages/manage.vue
+++ b/resources/assets/js/pages/manage.vue
@@ -326,9 +326,6 @@
-
-
-
@@ -357,7 +354,6 @@ import TaskAdd from "./manage/components/TaskAdd";
import Report from "./manage/components/Report";
import MobileBack from "../components/Mobile/Back";
import MobileNotification from "../components/Mobile/Notification";
-import MeetingManager from "./manage/components/MeetingManager";
import longpress from "../directives/longpress";
import DialogModal from "./manage/components/DialogModal";
import TaskModal from "./manage/components/TaskModal";
@@ -366,12 +362,11 @@ import TaskExport from "./manage/components/TaskExport";
import ApproveExport from "./manage/components/ApproveExport";
import ComplaintManagement from "./manage/components/ComplaintManagement";
import MicroApps from "../components/MicroApps.vue";
-import notificationKoro from "notification-koro1";
-import {Store} from "le5le-store";
-import {MarkdownPreview} from "../store/markdown";
import UserSelect from "../components/UserSelect.vue";
import ImgUpload from "../components/ImgUpload.vue";
import ApproveDetails from "./manage/approve/details.vue";
+import notificationKoro from "notification-koro1";
+import {Store} from "le5le-store";
export default {
components: {
@@ -383,7 +378,6 @@ export default {
ApproveExport,
TaskModal,
DialogModal,
- MeetingManager,
MobileNotification,
MobileBack,
MobileTabbar,
diff --git a/resources/assets/js/pages/manage/components/MeetingManager.vue b/resources/assets/js/pages/manage/components/MeetingManager.vue
index 2acfd173b..f5f7b6f1d 100644
--- a/resources/assets/js/pages/manage/components/MeetingManager.vue
+++ b/resources/assets/js/pages/manage/components/MeetingManager.vue
@@ -179,7 +179,7 @@ export default {
},
computed: {
- ...mapState(['meetingWindow', 'formOptions']),
+ ...mapState(['meetingWindow', 'formOptions', 'userToken']),
},
mounted() {
@@ -200,31 +200,54 @@ export default {
}
},
meetingWindow: {
- handler(val) {
- switch (val.type) {
+ handler(data) {
+ switch (data.type) {
+ // 创建会议
case 'add':
- this.addShow = val.show;
+ this.addShow = data.show;
this.loadIng = 0;
break;
+
+ // 加入会议(直接加入)
case 'join':
- this.addShow = val.show;
+ case 'direct':
+ this.addShow = data.show;
this.loadIng = 0;
this.addData.type = 'join';
- if(val.meetingSharekey){
- this.addData.sharekey = val.meetingSharekey;
- this.addData.meetingid = val.meetingid || '';
- this.addData.meetingdisabled = val.meetingSharekey ? true : false;
+ if (data.meetingNickname) {
+ this.addData.username = data.meetingNickname;
+ }
+ if (data.meetingAvatar) {
+ this.addData.userimg = data.meetingAvatar;
+ }
+ if ($A.runNum(data.meetingAudio) && !this.addData.tracks.includes('audio')) {
+ this.addData.tracks.push('audio')
+ }
+ if ($A.runNum(data.meetingVideo) && !this.addData.tracks.includes('video')) {
+ this.addData.tracks.push('video')
+ }
+ if (data.meetingSharekey) {
+ this.addData.sharekey = data.meetingSharekey;
+ this.addData.meetingid = data.meetingid || '';
+ this.addData.meetingdisabled = !!data.meetingSharekey;
+ }
+ if (data.type === 'direct') {
+ this.onOpen(true);
}
break;
+
+ // 邀请加入
case 'invitation':
- this.invitationShow = val.show;
+ this.invitationShow = data.show;
this.invitationLoad = false;
- this.invitationData.meetingid = val.meetingid;
+ this.invitationData.meetingid = data.meetingid;
break;
+
+ // 加入失败
case 'error':
- this.addShow = val.show;
+ this.addShow = data.show;
this.loadIng = 0;
- this.invitationShow = val.show;
+ this.invitationShow = data.show;
this.invitationLoad = false;
$A.modalError('加入会议失败');
break;
@@ -254,8 +277,9 @@ export default {
}
// 加上自己
if (!$A.isArray(data.userids)) {
- data.userids = [this.userId]
- } else if (!data.userids.includes(this.userId)) {
+ data.userids = []
+ }
+ if (this.userId && !data.userids.includes(this.userId)) {
data.userids.push(this.userId)
}
// 加上音频
@@ -269,64 +293,125 @@ export default {
},
onSubmit() {
+ this.$refs.addForm.validate((valid) => {
+ if (valid) {
+ this.onOpen()
+ }
+ });
+ },
+
+ onOpen(isDirect = false) {
if (this.meetingShow) {
$A.modalWarning("正在会议中,无法进入其他会议室");
return;
}
- this.$refs.addForm.validate((valid) => {
- if (valid) {
- this.loadIng++;
- this.$store.dispatch("call", {
- url: 'users/meeting/open',
- data: this.addData
- }).then(({data}) => {
- this.$set(this.addData, 'name', data.name);
- this.$set(this.addData, 'meetingid', data.meetingid);
- this.$set(this.localUser, 'nickname', data.nickname);
- this.$set(this.localUser, 'userimg', data.userimg);
- this.$store.dispatch("saveDialogMsg", data.msgs);
- this.$store.dispatch("updateDialogLastMsg", data.msgs);
- delete data.name;
- delete data.msgs;
- //
- if ($A.isEEUiApp) {
- $A.eeuiAppSendMessage({
- action: 'startMeeting',
- meetingParams: {
- name: this.addData.name,
- token: data.token,
- channel: data.channel,
- uuid: data.uid,
- appid: data.appid,
- avatar: data.userimg,
- username: data.nickname,
- video: this.addData.tracks.includes("video"),
- audio: this.addData.tracks.includes("audio"),
- meetingid: data.meetingid,
- sharelink: data.sharelink,
- alert: {
- title: this.$L('温馨提示'),
- message: this.$L('确定要离开会议吗?'),
- cancel: this.$L('继续'),
- confirm: this.$L('退出'),
- }
- }
- });
- } else {
- $A.loadScript('js/AgoraRTC_N-4.17.0.js').then(_ => {
- this.join(data)
- }).catch(_ => {
- $A.modalError("会议组件加载失败!");
- }).finally(_ => {
- this.loadIng--;
- })
- }
- }).catch(({msg}) => {
+ const loader = (add) => {
+ if (isDirect) {
+ if (add) {
+ this.$store.dispatch('showSpinner');
+ } else {
+ this.$store.dispatch('hiddenSpinner', 600);
+ }
+ } else {
+ if (add) {
+ this.loadIng++;
+ } else {
this.loadIng--;
- $A.modalError(msg);
- });
+ }
}
-
+ }
+ loader(true);
+ this.$store.dispatch("call", {
+ url: 'users/meeting/open',
+ data: this.addData
+ }).then(({data}) => {
+ this.$set(this.addData, 'name', data.name);
+ this.$set(this.addData, 'meetingid', data.meetingid);
+ this.$set(this.localUser, 'nickname', data.nickname);
+ this.$set(this.localUser, 'userimg', data.userimg);
+ this.$store.dispatch("saveDialogMsg", data.msgs);
+ this.$store.dispatch("updateDialogLastMsg", data.msgs);
+ delete data.name;
+ delete data.msgs;
+ // App 直接使用新窗口打开会议
+ if ($A.isEEUiApp) {
+ $A.eeuiAppSendMessage({
+ action: 'startMeeting',
+ meetingParams: {
+ name: this.addData.name,
+ token: data.token,
+ channel: data.channel,
+ uuid: data.uid,
+ appid: data.appid,
+ avatar: data.userimg,
+ username: data.nickname,
+ video: this.addData.tracks.includes("video"),
+ audio: this.addData.tracks.includes("audio"),
+ meetingid: data.meetingid,
+ sharelink: data.sharelink,
+ alert: {
+ title: this.$L('温馨提示'),
+ message: this.$L('确定要离开会议吗?'),
+ cancel: this.$L('继续'),
+ confirm: this.$L('退出'),
+ }
+ }
+ });
+ return
+ }
+ // 客户端且未获得邀请链接 获取会议链接之后使用子窗口打开会议
+ if ($A.Electron && !this.addData.sharekey) {
+ loader(true);
+ this.$store.dispatch("call", {
+ url: 'users/meeting/link',
+ data: {
+ meetingid: data.meetingid,
+ },
+ }).then(linkRes => {
+ // 使用子窗口打开会议
+ const config = {
+ title: this.addData.name,
+ titleFixed: true,
+ parent: null,
+ width: Math.min(window.screen.availWidth, 1440),
+ height: Math.min(window.screen.availHeight, 900),
+ }
+ const meetingPath = $A.urlAddParams(linkRes.data, {
+ type: 'direct',
+ nickname: encodeURIComponent(data.nickname),
+ avatar: encodeURIComponent(data.userimg),
+ audio: this.addData.tracks.includes("audio") ? 1 : 0,
+ video: this.addData.tracks.includes("video") ? 1 : 0,
+ token: this.userToken,
+ });
+ this.$store.dispatch('openChildWindow', {
+ name: `meeting-window`,
+ path: meetingPath,
+ force: false,
+ config
+ });
+ // 关闭弹窗
+ this.addShow = false;
+ }).catch(({ msg }) => {
+ $A.modalError(msg);
+ }).finally(_ => {
+ loader(false);
+ });
+ return;
+ }
+ // Web 加载会议组件
+ loader(true);
+ $A.loadScript('js/AgoraRTC_N-4.17.0.js').then(_ => {
+ this.join(data)
+ }).catch(_ => {
+ $A.modalError("会议组件加载失败!");
+ }).finally(_ => {
+ loader(false);
+ })
+ }).catch(({msg}) => {
+ $A.modalError(msg);
+ }).finally(_ => {
+ loader(false);
});
},
@@ -348,7 +433,7 @@ export default {
onInvitation(type) {
if (type === 'open') {
- if(this.addData.sharekey){
+ if (this.addData.sharekey && !this.userId) {
this.linkCopy();
return;
}
@@ -358,6 +443,10 @@ export default {
};
this.invitationShow = true;
} else if (type === 'submit') {
+ if (this.invitationData.userids.length === 0) {
+ $A.modalWarning("请选择邀请成员");
+ return;
+ }
this.invitationLoad = true;
this.$store.dispatch("call", {
url: 'users/meeting/invitation',
@@ -383,9 +472,10 @@ export default {
okText: '退出',
onOk: async _ => {
await this.leave()
- if(this.addData.sharekey){
+ if ($A.isSubElectron) {
+ this.$Electron.sendMessage('windowDestroy');
+ } else if (this.addData.sharekey) {
this.addShow = true;
- this.loadIng = 0;
}
resolve()
}
@@ -393,6 +483,28 @@ export default {
})
},
+ linkCopy() {
+ this.linkCopyLoad = true;
+ this.$store.dispatch("call", {
+ url: 'users/meeting/link',
+ data: {
+ meetingid: this.addData.meetingid || this.invitationData.meetingid,
+ sharekey: this.addData.sharekey
+ },
+ }).then(({ data }) => {
+ this.copyText({
+ text: data,
+ success: '已复制会议邀请链接',
+ error: "复制失败"
+ });
+ this.invitationShow = false;
+ }).catch(({ msg }) => {
+ $A.modalError(msg);
+ }).finally(_ => {
+ this.linkCopyLoad = false;
+ });
+ },
+
async join(options) {
this.loadIng++;
// 音频采集设备状态变化回调
@@ -451,8 +563,8 @@ export default {
console.error(error)
$A.modalError("会议组件加载失败!");
}
- this.loadIng--;
this.addShow = false;
+ this.loadIng--;
},
async leave() {
@@ -472,8 +584,8 @@ export default {
// 离开频道
await this.agoraClient.leave();
//
- this.loadIng--;
this.meetingShow = false;
+ this.loadIng--;
},
async openAudio() {
@@ -513,6 +625,9 @@ export default {
},
async handleUserJoined(user) {
+ if (user.uid == this.localUser.uid) {
+ return;
+ }
const index = this.remoteUsers.findIndex(item => item.uid == user.uid)
if (index > -1) {
this.remoteUsers.splice(index, 1, user)
@@ -541,28 +656,6 @@ export default {
await this.agoraClient.unsubscribe(user, mediaType);
}
},
-
- linkCopy() {
- this.linkCopyLoad = true;
- this.$store.dispatch("call", {
- url: 'users/meeting/link',
- data: {
- meetingid: this.addData.meetingid || this.invitationData.meetingid,
- sharekey: this.addData.sharekey
- },
- }).then(({ data }) => {
- this.copyText({
- text: data,
- success: '已复制会议邀请链接',
- error: "复制失败"
- });
- this.invitationShow = false;
- }).catch(({ msg }) => {
- $A.modalError(msg);
- }).finally(_ => {
- this.linkCopyLoad = false;
- });
- },
}
}
diff --git a/resources/assets/js/pages/manage/components/MeetingPlayer.vue b/resources/assets/js/pages/manage/components/MeetingPlayer.vue
index 913e48f53..3995055c8 100644
--- a/resources/assets/js/pages/manage/components/MeetingPlayer.vue
+++ b/resources/assets/js/pages/manage/components/MeetingPlayer.vue
@@ -90,7 +90,7 @@ export default {
},
playerStyle() {
const user = this.cacheUserBasic.find(({userid}) => userid == this.userid);
- if (user) {
+ if (user && user.userimg) {
return {
backgroundImage: `url("${user.userimg}")`
}
diff --git a/resources/assets/js/pages/meeting.vue b/resources/assets/js/pages/meeting.vue
index 5000a7153..3e8d2f0ba 100644
--- a/resources/assets/js/pages/meeting.vue
+++ b/resources/assets/js/pages/meeting.vue
@@ -12,10 +12,16 @@ export default {
MeetingManager,
},
mounted() {
+ const {meetingId, sharekey} = this.$route.params;
+ const {nickname, avatar, audio, video, type} = this.$route.query;
this.$store.dispatch("showMeetingWindow",{
- type: "join",
- meetingid: this.$route.params.meetingId,
- meetingSharekey: this.$route.params.sharekey,
+ type: ['direct', 'join'].includes(type) ? type : 'join',
+ meetingid: meetingId,
+ meetingSharekey: sharekey,
+ meetingNickname: nickname,
+ meetingAvatar: avatar,
+ meetingAudio: audio,
+ meetingVideo: video,
meetingdisabled: true,
})
},
diff --git a/resources/assets/js/store/actions.js b/resources/assets/js/store/actions.js
index 64faf72b8..7d8571b8b 100644
--- a/resources/assets/js/store/actions.js
+++ b/resources/assets/js/store/actions.js
@@ -3515,8 +3515,16 @@ export default {
/**
* 隐藏全局浮窗加载器
* @param state
+ * @param dispatch
+ * @param delay
*/
- hiddenSpinner({state}) {
+ hiddenSpinner({state, dispatch}, delay) {
+ if (typeof delay === "number") {
+ setTimeout(_ => {
+ dispatch("hiddenSpinner")
+ }, delay)
+ return
+ }
const item = state.floatSpinnerTimer.shift()
if (item) {
clearTimeout(item.timer)
@@ -4193,19 +4201,12 @@ export default {
/**
* 显示会议窗口
* @param state
- * @param type
- * @param meetingid
- * @param meetingdisabled
- * @param meetingSharekey
+ * @param data
*/
- showMeetingWindow({state}, {type, meetingid, meetingdisabled, meetingSharekey}) {
- state.meetingWindow = {
- show: true,
- type: type,
- meetingid: meetingid,
- meetingdisabled: meetingdisabled,
- meetingSharekey: meetingSharekey
- };
+ showMeetingWindow({state}, data) {
+ state.meetingWindow = Object.assign(data, {
+ show: data.type !== 'direct',
+ });
},
/** *****************************************************************************************/
diff --git a/resources/assets/sass/pages/components/meeting-manager.scss b/resources/assets/sass/pages/components/meeting-manager.scss
index 44f550e4e..d514e52e2 100644
--- a/resources/assets/sass/pages/components/meeting-manager.scss
+++ b/resources/assets/sass/pages/components/meeting-manager.scss
@@ -9,7 +9,7 @@ body {
> ul {
display: grid;
justify-content: space-between;
- grid-template-columns: repeat(auto-fill, 220px);
+ grid-template-columns: repeat(auto-fill, 210px);
grid-gap: 24px;
> li {
list-style: none;
@@ -17,8 +17,8 @@ body {
.meeting-player {
position: relative;
.player {
- width: 220px;
- height: 220px;;
+ width: 210px;
+ height: 210px;;
border-radius: 12px;
position: relative;
z-index: 1;