Compare commits

...

8 Commits

Author SHA1 Message Date
cxc
ebdda03722 redirect 2022-11-03 17:29:43 +08:00
cxc
fde755fec8 13 2022-10-21 13:35:31 +08:00
cxc
5aeff72e9c 会议未开始时,禁止用户进入会议,可以暂存信息到本地 2022-10-19 17:11:01 +08:00
cxc
907dd65fc7 git add . 2022-10-19 14:21:58 +08:00
cxc
05cbb62aba 在预约和验证页面显示倒计时 2022-10-19 11:52:41 +08:00
cxc
b7a3446efc 全屏状态只显示共享屏幕时,共享屏幕占满全屏 2022-10-19 11:23:08 +08:00
cxc
db0baef0cf 共享窗口的大小占满背景 2022-10-19 11:09:40 +08:00
7428611830 fixed 2022-10-18 23:29:35 +08:00
10 changed files with 332 additions and 42 deletions

View File

@ -1,7 +1,8 @@
<template>
<div class="count-down" v-if="durationTime > 0">
<div class="title">会议倒计时</div>
<div class="count">{{ remainTime }}</div>
<div class="count-down">
<!-- <div class="title">会议倒计时</div> -->
<div v-if="durationTime > 0" class="count">将在{{ remainTime }}后开始</div>
<div v-else class="count">已开始</div>
</div>
</template>
<script setup name="CountDown">
@ -9,6 +10,8 @@ import dayjs from "dayjs";
import duration from "dayjs/plugin/duration";
import { onMounted, onUnmounted, ref } from "vue";
dayjs.extend(duration);
const emit = defineEmits(["timeup"]);
const props = defineProps({
startTime: {
type: String,
@ -23,13 +26,17 @@ onMounted(() => {
timer = setInterval(() => {
durationTime.value =
new Date(props.startTime).getTime() - new Date().getTime();
console.log(durationTime.value);
if (durationTime.value <= 0 && durationTime.value >= -1200) {
emit("timeup");
}
if (durationTime.value <= 0) {
clearInterval(timer);
}
const duraDayjs = dayjs.duration(durationTime.value);
remainTime.value = `${parseInt(
duraDayjs.asHours()
)}${duraDayjs.minutes()}${duraDayjs.seconds()}`;
duraDayjs.asDays()
)}${duraDayjs.hours()}${duraDayjs.minutes()}${duraDayjs.seconds()}`;
}, 500);
});
onUnmounted(() => {
@ -39,21 +46,21 @@ onUnmounted(() => {
<style scoped lang="scss">
.count-down {
position: absolute;
z-index: -1;
top: 20%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
align-items: center;
.title {
font-size: 24px;
font-weight: bold;
}
// position: absolute;
// z-index: -1;
// top: 20%;
// left: 50%;
// transform: translate(-50%, -50%);
// display: flex;
// flex-direction: column;
// align-items: center;
// .title {
// font-size: 16px;
// font-weight: bold;
// }
.count {
font-size: 36px;
margin-top: 20px;
font-size: 16px;
// margin-top: 20px;
}
}
</style>

View File

@ -14,6 +14,26 @@ import dayjs from "dayjs";
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/meeting/56',
redirect: '/meeting/90'
},
{
path: "/appointment/56",
redirect: "/appointment/90",
},
{
path: "/verify/56",
redirect: '/verify/90'
},
{
path: "/panelist-verify/56",
redirect: '/panelist-verify/90'
},
{
path: "/panelist/56",
redirect: '/panelist/90'
},
{
path: "/appointment/:meetingId",
name: "Appointment",

View File

@ -6,6 +6,9 @@ const store = createStore({
joinUser: localStorage.getItem("JOIN_USER")
? JSON.parse(localStorage.getItem("JOIN_USER"))
: {},
tempUser: localStorage.getItem("TEMP_USER")
? JSON.parse(localStorage.getItem("TEMP_USER"))
: {},
meeting: {},
meetingSetting: {},
messagesList: localStorage.getItem("MESSAGES")
@ -28,6 +31,10 @@ const store = createStore({
state.joinUser = data;
localStorage.setItem("JOIN_USER", JSON.stringify(data));
},
setTempUser(state, data) {
state.tempUser = data
localStorage.setItem("TEMP_USER", JSON.stringify(data))
},
// 设置会议信息
setMeetingInfo(state, data) {
state.meeting = data;

View File

@ -0,0 +1,30 @@
@media only screen and (max-width: 768px) {
.meeting-cover {
width: 100%;
display: block;
margin: 0 auto;
}
.meeting-title {
font-size: 7vw;
}
.meeting-time {
flex-direction: column;
align-items: center;
font-size: 5vw;
}
.meeting-time .title {
margin-right: 3vw;
}
.meeting-time :not(:last-child) {
margin-right: 0px;
}
.form-container {
padding: 0 2vw 0;
}
.form-container .joinuser-item {
width: 100%;
}
.form-container .joinuser-item :deep(.el-form-item__label) {
width: 70px;
}
}

1
src/style/appoint-mobile.min.css vendored Normal file
View File

@ -0,0 +1 @@
@media only screen and (max-width: 768px){.meeting-cover{width:100%;display:block;margin:0 auto}.meeting-title{font-size:7vw}.meeting-time{flex-direction:column;align-items:center;font-size:5vw}.meeting-time .title{margin-right:3vw}.meeting-time :not(:last-child){margin-right:0px}.form-container{padding:0 2vw 0}.form-container .joinuser-item{width:100%}.form-container .joinuser-item :deep(.el-form-item__label){width:70px}}

View File

@ -12,10 +12,15 @@
font-size: 7vw;
}
.meeting-time {
flex-direction: column;
align-items: center;
font-size: 5vw;
.title {
margin-right: 3vw;
}
:not(:last-child) {
margin-right: 0px;
}
}
.form-container {
padding: 0 2vw 0;

View File

@ -6,8 +6,9 @@
/>
<h3 class="meeting-title">{{ meeting.meetingName }}</h3>
<p class="meeting-time">
<span class="title">会议时间</span>
<span class="title">会议开始时间</span>
<span class="time">{{ meeting.startTime }}</span>
<CountDown :start-time="meeting.startTime" />
</p>
<div class="form-container" v-if="appointStatus === `pending`">
<el-form
@ -18,8 +19,11 @@
>
<div class="joinuser-wrap" style="display: flex; flex-wrap: wrap">
<div class="joinuser-item" v-if="fieldConfig.icCard">
<el-form-item label="IC卡" prop="icCard">
<el-input v-model="appointForm.icCard" placeholder="请输入IC卡号" />
<el-form-item label="IC卡编号/手机号码" prop="icCard">
<el-input
v-model="appointForm.icCard"
placeholder="请输入IC卡号或手机号码"
/>
</el-form-item>
</div>
<div class="joinuser-item" v-if="fieldConfig.nickname">
@ -258,6 +262,7 @@
</template>
<script setup>
import CountDown from "@/components/countDown.vue";
import { reactive, ref, toRefs } from "vue";
import { getMeetingDetailById, newAppointment } from "@/api/meeting";
import { ElMessage } from "element-plus";
@ -530,7 +535,12 @@ loadMeetingDetail(meetingId.value);
}
.meeting-time {
text-align: center;
// text-align: center;
display: flex;
justify-content: center;
:not(:last-child) {
margin-right: 12px;
}
}
.form-item-container {

View File

@ -1,5 +1,11 @@
<template>
<div id="app-container" ref="appContainerRef">
<div
id="app-container"
:class="{
isShare: templateId == 5 && inSharing && !isShareByme,
}"
ref="appContainerRef"
>
<!-- zoom 会议组件 -->
<div id="meeting-chat-row">
<div class="fullscreen-wrap" ref="fullscreenWrapRef">
@ -18,7 +24,7 @@
:class="`layout-template-${templateId}`"
ref="videoElementRef"
></div>
<CountDown :start-time="store.getters.startTime" />
<!-- <CountDown :start-time="store.getters.startTime" /> -->
<!-- <like
v-if="screenWidth > 900"
:meeting-id="store.getters.meetingId"
@ -50,7 +56,11 @@
/>
</div>
</div>
<div class="like-row">
<div
:class="`like-row ${
templateId == 5 && inSharing && !isShareByme ? 'isShare' : ''
}`"
>
<like
:meeting-id="store.getters.meetingId"
:like="likeCount"
@ -185,7 +195,7 @@ import {
commitQuestionnaire,
commitExam,
} from "@/api/meeting";
import CountDown from "@/components/countDown.vue";
// import CountDown from "@/components/countDown.vue";
const store = useStore();
const route = useRoute();
@ -437,6 +447,7 @@ const switchToVideoOn = () => {
};
const inSharing = ref(false); // 共享屏幕是否开启
const isShareByme = ref(false); // 是否由我共享
const attendeeslist = ref("");
setInterval(() => {
// 共享屏幕状态变化
@ -446,6 +457,13 @@ setInterval(() => {
inSharing.value = screenShareEl ? true : false;
// ------
// TODO:查找停止共享按钮元素,判断是否由自己共享,由自己共享则不应用 id 5 布局。
if (templateId.value == 5) {
const stopShareEl = document.querySelector(
`div[class*="zmwebsdk-makeStyles-isSharing-"]`
);
isShareByme.value = stopShareEl ? true : false;
}
// 检测是否是ribbon视图, 如果是, 则切换到gallery view, 当观众被设为嘉宾或嘉宾被设为观众时需要切换视图.
const isRibbon = document.querySelector(
"#suspension-view-tab-thumbnail-ribbon.zmwebsdk-MuiTab-selected"
@ -912,6 +930,128 @@ $meetingComponentHeight: $meetingComponentWitdh * 9 / 16;
$meetingBackgroundWidth: 80vw; //会议背景宽度
$meetingBackgroundHeight: 80vw * 9 / 16;
// @media screen and (max-width: 900px) {
.like-row.isShare {
margin-top: 42px;
}
// }
.isShare {
.text-label-container {
display: none !important;
}
#meeting-container {
padding-top: 0 !important;
}
#right-chat {
height: calc(80vw * 1080 / 1920) !important;
}
#video-element {
width: 80vw !important;
// height: calc(80vw * 850 / 1346) !important;
height: calc(80vw * 1080 / 1920) !important;
}
// 底部操作条
:deep(#video-element
> div
> .zmwebsdk-MuiPaper-root
> .zmwebsdk-MuiPaper-root:nth-child(2)) {
// display: none !important;
// position: absolute;
// visibility: hidden;
position: absolute;
visibility: visible;
bottom: 0;
left: 50%;
transform: translate(-50%, 100%);
}
// 视频组件宽度
:deep(#video-element
> div
> .zmwebsdk-MuiPaper-root
> .zmwebsdk-MuiPaper-root:nth-child(1)) {
width: 80vw !important;
}
// zoom 会议共享屏幕组件宽度
:deep(div[id*="suspension-view-tabpanel"]
> .zmwebsdk-MuiBox-root.zmwebsdk-MuiBox-root) {
// height: calc(80vw * 850 / 1346) !important;
height: calc(80vw * 1080 / 1920) !important;
}
.fullscreen {
#video-element {
width: 100vw !important;
height: calc(100vw * 1080 / 1920) !important;
}
// 视频组件宽度
:deep(#video-element
> div
> .zmwebsdk-MuiPaper-root
> .zmwebsdk-MuiPaper-root:nth-child(1)) {
width: 100vw !important;
}
// zoom 会议共享屏幕组件宽度
:deep(div[id*="suspension-view-tabpanel"]
> .zmwebsdk-MuiBox-root.zmwebsdk-MuiBox-root) {
// height: calc(80vw * 850 / 1346) !important;
height: calc(100vw * 1080 / 1920) !important;
}
}
@media screen and (max-width: 900px) {
#video-element {
width: 100vw !important;
height: calc(100vw * 1080 / 1920) !important;
}
// 视频组件宽度
:deep(#video-element
> div
> .zmwebsdk-MuiPaper-root
> .zmwebsdk-MuiPaper-root:nth-child(1)) {
width: 100vw !important;
}
// zoom 会议共享屏幕组件宽度
:deep(div[id*="suspension-view-tabpanel"]
> .zmwebsdk-MuiBox-root.zmwebsdk-MuiBox-root) {
// height: calc(80vw * 850 / 1346) !important;
height: calc(100vw * 1080 / 1920) !important;
}
// 底部操作条
// :deep(#video-element
// > div
// > .zmwebsdk-MuiPaper-root
// > .zmwebsdk-MuiPaper-root:nth-child(2)) {
// position: absolute;
// visibility: visible;
// bottom: 0;
// left: 50%;
// transform: translate(-50%, 100%);
// }
}
.verticalFullScreen {
// background-color: saddlebrown !important;
#video-element {
width: calc(100vw * 1920 / 1080) !important;
// height: calc(100vh * 1080 / 1920) !important;
height: 100vw !important;
}
// 视频组件宽度
:deep(#video-element
> div
> .zmwebsdk-MuiPaper-root
> .zmwebsdk-MuiPaper-root:nth-child(1)) {
width: calc(100vw * 1920 / 1080) !important;
}
// zoom 会议共享屏幕组件宽度
:deep(div[id*="suspension-view-tabpanel"]
> .zmwebsdk-MuiBox-root.zmwebsdk-MuiBox-root) {
// height: calc(100vh * 1080 / 1920) !important;
height: 100vw !important;
}
}
}
:deep(#right-chat .chat-container .message-list) {
// height: $meetingComponentWitdh * 9 / 16;
// height: 100%;

View File

@ -6,8 +6,9 @@
/>
<h3 class="meeting-title">{{ meeting.meetingName }}</h3>
<p class="meeting-time">
<span class="title">会议时间</span>
<span class="title">会议开始时间</span>
<span class="time">{{ meeting.startTime }}</span>
<CountDown :start-time="meeting.startTime" @timeup="refreshPage" />
</p>
<div class="form-container">
<el-form
@ -18,8 +19,11 @@
>
<div class="joinuser-wrap" style="display: flex; flex-wrap: wrap">
<div class="joinuser-item">
<el-form-item label="IC卡" prop="icCard">
<el-input v-model="newJoinUser.icCard" placeholder="请输入IC卡号" />
<el-form-item label="IC卡编号/手机号码" prop="icCard">
<el-input
v-model="newJoinUser.icCard"
placeholder="请输入IC卡号或手机号码"
/>
</el-form-item>
</div>
<div class="joinuser-item">
@ -49,9 +53,15 @@
</div>
<div style="display: flex; justify-content: center">
<el-button type="primary" @click="submitVerify(newJoinUserRef)"
<el-button
v-if="btnStatus"
type="primary"
@click="submitVerify(newJoinUserRef)"
>加入会议</el-button
>
<el-button v-else type="primary" @click="saveTempUser(newJoinUserRef)"
>保存信息</el-button
>
</div>
</div>
<agreement
@ -63,6 +73,7 @@
</template>
<script setup>
import CountDown from "@/components/countDown.vue";
import { reactive, ref, toRefs } from "vue";
import { useStore } from "vuex";
import { useRoute, useRouter } from "vue-router";
@ -102,6 +113,15 @@ const meetingId = ref(route.params.meetingId);
meeting.value = _.cloneDeep(store.state.meeting);
newJoinUser.value.meetingId = meetingId.value;
const btnStatus = ref(false);
btnStatus.value = meeting.value.status == 1 ? true : false;
// 从本地存储中获取临时存储的信息
if (Object.keys(store.state.tempUser).length) {
if (meeting.value.id == store.state.tempUser.meetingId) {
newJoinUser.value = _.cloneDeep(store.state.tempUser);
}
}
const showUserAgreement = ref(false); // 是否显示用户协议弹窗
const isAgreeAgreement = ref(false); // 是否同意协议
@ -115,6 +135,20 @@ const submitVerify = async (newJoinUserRef) => {
store.commit("setJoinUser", newJoinUser.value);
router.push(`/panelist/${meetingId.value}`);
};
const saveTempUser = async (newJoinUserRef) => {
await newJoinUserRef.validate();
store.commit("setTempUser", newJoinUser.value);
ElMessage.success("已将信息存储到本地");
};
const refreshPage = () => {
const state = meeting.value.status == 1 ? true : false;
if (state) {
return;
}
location.reload();
};
</script>
<style lang="scss" scoped>
@ -125,7 +159,12 @@ const submitVerify = async (newJoinUserRef) => {
text-align: center;
}
.meeting-time {
text-align: center;
// text-align: center;
display: flex;
justify-content: center;
:not(:last-child) {
margin-right: 12px;
}
}
.form-item-container {
display: flex;

View File

@ -6,8 +6,10 @@
/>
<h3 class="meeting-title">{{ meeting.meetingName }}</h3>
<p class="meeting-time">
<span class="title">会议时间</span>
<span class="title">会议开始时间</span>
<span class="time">{{ meeting.startTime }}</span>
<CountDown :start-time="meeting.startTime" @timeup="refreshPage" />
<!-- <CountDown start-time="2022-10-20 10:24:00" @timeup="refreshPage" /> -->
</p>
<div class="form-container">
<el-form
@ -21,10 +23,10 @@
class="joinuser-item"
v-if="fieldConfig.icCard && meeting.joinType !== `3`"
>
<el-form-item label="IC卡" prop="icCard">
<el-form-item label="IC卡编号/手机号码" prop="icCard">
<el-input
v-model="newJoinUser.icCard"
placeholder="请输入IC卡号若没有IC卡号可输入手机号"
placeholder="请输入IC卡号手机号"
/>
</el-form-item>
</div>
@ -378,9 +380,15 @@
</el-button>
</div>
<div style="display: flex; justify-content: center">
<el-button type="primary" @click="submitVerify(newJoinUserRef)"
<el-button
v-if="btnStatus"
type="primary"
@click="submitVerify(newJoinUserRef)"
>加入会议</el-button
>
<el-button v-else type="primary" @click="saveTempUser(newJoinUserRef)"
>保存信息</el-button
>
</div>
</div>
<agreement
@ -392,8 +400,9 @@
</template>
<script setup>
import CountDown from "@/components/countDown.vue";
import { reactive, ref, toRefs } from "vue";
import { registerJoinUser, visitorJoinUser } from "@/api/meeting";
// import { registerJoinUser, visitorJoinUser } from "@/api/meeting";
import { ElMessage } from "element-plus";
import { useStore } from "vuex";
import { useRoute, useRouter } from "vue-router";
@ -577,11 +586,19 @@ meeting.value = _.cloneDeep(store.state.meeting);
const showUserAgreement = ref(false); // 是否显示用户协议弹窗
const isAgreeAgreement = ref(false); // 是否同意协议
if (data.fieldConfig) {
fieldConfig.value = JSON.parse(meeting.value.fieldConfig);
}
const btnStatus = ref(false);
btnStatus.value = meeting.value.status == 1 ? true : false;
// 从本地存储中获取临时存储的信息
if (Object.keys(store.state.tempUser).length) {
if (meeting.value.id == store.state.tempUser.meetingId) {
newJoinUser.value = _.cloneDeep(store.state.tempUser);
}
}
// 设置gender basicLevelUnitFlag countryDoctorFlag affiliateWestFlag 默认值
const setJoinUserDefaultValue = () => {
[
@ -616,9 +633,6 @@ const submitVerify = async (newJoinUserRef) => {
store.commit("setJoinUser", newJoinUser.value);
router.push(`/meeting/${meetingId.value}`);
} else if (meeting.value.joinType === "2") {
// const { data } = await registerJoinUser(newJoinUser.value);
// store.commit("setPassword", data);
console.log(meetingId.value);
store.commit("setJoinUser", newJoinUser.value);
router.push(`/meeting/${meetingId.value}`);
} else if (meeting.value.joinType === "3") {
@ -628,6 +642,18 @@ const submitVerify = async (newJoinUserRef) => {
router.push(`/meeting/${meetingId.value}`);
}
};
const refreshPage = () => {
const state = meeting.value.status == 1 ? true : false;
if (state) {
return;
}
location.reload();
};
const saveTempUser = async (newJoinUserRef) => {
await newJoinUserRef.validate();
store.commit("setTempUser", newJoinUser.value);
ElMessage.success("已将信息存储到本地");
};
</script>
<style lang="scss" scoped>
@ -644,7 +670,12 @@ const submitVerify = async (newJoinUserRef) => {
text-align: center;
}
.meeting-time {
text-align: center;
// text-align: center;
display: flex;
justify-content: center;
:not(:last-child) {
margin-right: 12px;
}
}
.form-item-container {
display: flex;