Feat: guest user join room
This commit is contained in:
parent
83979276fd
commit
063db6c7de
|
@ -41,6 +41,19 @@ const menuLinks = computed(() => {
|
|||
to: "/auth/register"
|
||||
});
|
||||
|
||||
if (!isLogin.value && settings?.guestEnable) {
|
||||
basicLinks.push({
|
||||
name: "加入房间",
|
||||
to: "/joinRoom"
|
||||
});
|
||||
|
||||
route.path.startsWith("/cinema") &&
|
||||
basicLinks.push({
|
||||
name: "影厅",
|
||||
to: "/cinema/" + route.params.roomId
|
||||
});
|
||||
}
|
||||
|
||||
if (isLogin.value) {
|
||||
const loginLinks = route.path.startsWith("/cinema")
|
||||
? [
|
||||
|
|
|
@ -3,12 +3,14 @@ import { onMounted, ref } from "vue";
|
|||
import { ElNotification } from "element-plus";
|
||||
import { roomStatus, type RoomList } from "@/types/Room";
|
||||
import JoinRoom from "@/views/JoinRoom.vue";
|
||||
import { indexStore } from "@/stores";
|
||||
import { userStore } from "@/stores/user";
|
||||
import { Search } from "@element-plus/icons-vue";
|
||||
import { useTimeAgo } from "@vueuse/core";
|
||||
import { useRouter } from "vue-router";
|
||||
import { useRoomApi } from "@/hooks/useRoom";
|
||||
import { getObjValue } from "@/utils";
|
||||
import { guestJoinRoomApi } from "@/services/apis/room";
|
||||
|
||||
const router = useRouter();
|
||||
const props = defineProps<{
|
||||
|
@ -17,6 +19,7 @@ const props = defineProps<{
|
|||
userId?: string;
|
||||
}>();
|
||||
|
||||
const { settings } = indexStore();
|
||||
const { isLogin, info } = userStore();
|
||||
const thisRoomList = ref<RoomList[]>([]);
|
||||
const formData = ref<{
|
||||
|
@ -45,7 +48,8 @@ const {
|
|||
getHotRoomList,
|
||||
hotRoomList,
|
||||
|
||||
joinRoom
|
||||
joinRoom,
|
||||
guestJoinRoom
|
||||
} = useRoomApi(formData.value.roomId);
|
||||
|
||||
const getRoomList = async (showMsg = false) => {
|
||||
|
@ -63,7 +67,7 @@ const getRoomList = async (showMsg = false) => {
|
|||
|
||||
const JoinRoomDialog = ref(false);
|
||||
const joinThisRoom = async (item: RoomList) => {
|
||||
if (!isLogin.value) {
|
||||
if (!settings?.guestEnable && isLogin.value) {
|
||||
ElNotification({
|
||||
title: "错误",
|
||||
message: "请先登录",
|
||||
|
@ -79,9 +83,13 @@ const joinThisRoom = async (item: RoomList) => {
|
|||
}
|
||||
formData.value.roomId = item.roomId;
|
||||
|
||||
info.value?.username === item.creator || !item.needPassword
|
||||
? await joinRoom(formData.value)
|
||||
: (JoinRoomDialog.value = true);
|
||||
return isLogin.value
|
||||
? info.value?.username === item.creator || !item.needPassword
|
||||
? await joinRoom(formData.value)
|
||||
: (JoinRoomDialog.value = true)
|
||||
: settings?.guestEnable && !item.needPassword
|
||||
? await guestJoinRoom(formData.value)
|
||||
: (JoinRoomDialog.value = true);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
|
|
|
@ -5,7 +5,14 @@ import { roomStore } from "@/stores/room";
|
|||
import router from "@/router";
|
||||
import { myRoomListApi } from "@/services/apis/user";
|
||||
import { userRoomListApi } from "@/services/apis/admin";
|
||||
import { joinRoomApi, checkRoomApi, roomListApi, hotRoom, myInfoApi } from "@/services/apis/room";
|
||||
import {
|
||||
joinRoomApi,
|
||||
checkRoomApi,
|
||||
roomListApi,
|
||||
hotRoom,
|
||||
myInfoApi,
|
||||
guestJoinRoomApi
|
||||
} from "@/services/apis/room";
|
||||
import { strLengthLimit } from "@/utils";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { RoomMemberPermission, RoomAdminPermission } from "@/types/Room";
|
||||
|
@ -92,6 +99,54 @@ export const useRoomApi = (roomId: string) => {
|
|||
}
|
||||
};
|
||||
|
||||
// 加入房间(访客)
|
||||
const { state: guestJoinRoomInfo, execute: reqGuestJoinRoomApi } = guestJoinRoomApi();
|
||||
const guestJoinRoom = async (formData: { roomId: string; password: string }) => {
|
||||
if (!formData.roomId) {
|
||||
ElNotification({
|
||||
title: "错误",
|
||||
message: "请填写表单完整",
|
||||
type: "error"
|
||||
});
|
||||
return;
|
||||
}
|
||||
for (const key in formData) {
|
||||
strLengthLimit(key, 32);
|
||||
}
|
||||
try {
|
||||
await reqGuestJoinRoomApi({
|
||||
data: formData
|
||||
});
|
||||
if (!guestJoinRoomInfo.value)
|
||||
return ElNotification({
|
||||
title: "错误",
|
||||
message: "服务器并未返回token",
|
||||
type: "error"
|
||||
});
|
||||
localStorage.setItem(
|
||||
`room-${guestJoinRoomInfo.value.roomId}-token`,
|
||||
guestJoinRoomInfo.value?.token
|
||||
);
|
||||
if (formData.password)
|
||||
localStorage.setItem(`room-${guestJoinRoomInfo.value.roomId}-pwd`, formData.password);
|
||||
|
||||
await getMyInfo(guestJoinRoomInfo.value.token);
|
||||
ElNotification({
|
||||
title: "加入成功",
|
||||
type: "success"
|
||||
});
|
||||
|
||||
router.replace(`/cinema/${guestJoinRoomInfo.value.roomId}`);
|
||||
} catch (err: any) {
|
||||
console.error(err);
|
||||
ElNotification({
|
||||
title: "错误",
|
||||
message: err.response.data.error || err.message,
|
||||
type: "error"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 房间列表
|
||||
const totalItems = ref(0);
|
||||
const currentPage = ref(1);
|
||||
|
@ -297,7 +352,10 @@ export const useRoomApi = (roomId: string) => {
|
|||
hotRoomList,
|
||||
|
||||
getMyInfo,
|
||||
myInfo
|
||||
myInfo,
|
||||
|
||||
guestJoinRoom,
|
||||
guestJoinRoomInfo
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import { createRouter, createWebHistory } from "vue-router";
|
||||
import { start, close } from "@/utils/nprogress";
|
||||
import { ROLE } from "@/types/User";
|
||||
|
||||
import { userStore } from "@/stores/user";
|
||||
// import { indexStore } from "@/stores";
|
||||
|
||||
const Base_Title = "SyncTV";
|
||||
|
||||
|
@ -100,8 +102,10 @@ const router = createRouter({
|
|||
}
|
||||
});
|
||||
|
||||
router.beforeEach((to: any, from: any, next) => {
|
||||
router.beforeEach(async (to: any, from: any, next) => {
|
||||
start();
|
||||
const { indexStore } = await import("@/stores");
|
||||
const { settings } = indexStore();
|
||||
const { info } = userStore();
|
||||
const permission = info.value?.role ?? -1;
|
||||
if (to.meta.permission <= permission) {
|
||||
|
@ -109,12 +113,19 @@ router.beforeEach((to: any, from: any, next) => {
|
|||
next();
|
||||
} else {
|
||||
if (permission === ROLE.Visitor) {
|
||||
router.replace({
|
||||
name: "login",
|
||||
query: {
|
||||
redirect: to.fullPath
|
||||
}
|
||||
});
|
||||
if (
|
||||
(settings?.guestEnable && to.path.startsWith("/cinema")) ||
|
||||
to.path.startsWith("/joinRoom")
|
||||
) {
|
||||
next();
|
||||
} else {
|
||||
router.replace({
|
||||
name: "login",
|
||||
query: {
|
||||
redirect: to.fullPath
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
next("/403");
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { useDefineApi } from "@/stores/useDefineApi";
|
||||
import type { RegForm, EmailRegForm } from "@/types";
|
||||
import type { RegForm, EmailRegForm, PublicSettings } from "@/types";
|
||||
|
||||
// 注册
|
||||
export const RegisterApi = useDefineApi<
|
||||
|
@ -88,15 +88,7 @@ export const oAuth2Callback = useDefineApi<
|
|||
});
|
||||
|
||||
// 获取站点配置信息
|
||||
export const getPublicSettings = useDefineApi<
|
||||
any,
|
||||
{
|
||||
emailEnable: boolean;
|
||||
emailDisableUserSignup: boolean;
|
||||
emailWhitelistEnabled: boolean;
|
||||
emailWhitelist: string[];
|
||||
}
|
||||
>({
|
||||
export const getPublicSettings = useDefineApi<any, PublicSettings>({
|
||||
url: "/api/public/settings",
|
||||
method: "GET"
|
||||
});
|
||||
|
|
|
@ -84,6 +84,25 @@ export const joinRoomApi = useDefineApi<
|
|||
method: "POST"
|
||||
});
|
||||
|
||||
// 加入房间(访客)
|
||||
export const guestJoinRoomApi = useDefineApi<
|
||||
// request
|
||||
{
|
||||
data: {
|
||||
roomId: string;
|
||||
password: string;
|
||||
};
|
||||
},
|
||||
// response
|
||||
{
|
||||
roomId: string;
|
||||
token: string;
|
||||
}
|
||||
>({
|
||||
url: "/api/room/guest",
|
||||
method: "POST"
|
||||
});
|
||||
|
||||
// 删除房间
|
||||
export const delRoomApi = useDefineApi<
|
||||
{
|
||||
|
|
|
@ -2,16 +2,12 @@ import { ref } from "vue";
|
|||
import { ElNotification } from "element-plus";
|
||||
import { getPublicSettings } from "@/services/apis/auth";
|
||||
import { defineStore } from "pinia";
|
||||
import type { PublicSettings } from "@/types";
|
||||
|
||||
export const indexStore = defineStore("indexStore", () => {
|
||||
const { execute, state } = getPublicSettings();
|
||||
|
||||
const settings = ref<{
|
||||
emailEnable: boolean;
|
||||
emailDisableUserSignup: boolean;
|
||||
emailWhitelistEnabled: boolean;
|
||||
emailWhitelist: string[];
|
||||
}>();
|
||||
const settings = ref<PublicSettings>();
|
||||
|
||||
const getSiteOptions = async () => {
|
||||
try {
|
||||
|
|
|
@ -6,3 +6,11 @@ export interface RegForm {
|
|||
export interface EmailRegForm extends RegForm {
|
||||
captcha: string;
|
||||
}
|
||||
|
||||
export interface PublicSettings {
|
||||
emailEnable: boolean;
|
||||
emailDisableUserSignup: boolean;
|
||||
emailWhitelistEnabled: boolean;
|
||||
emailWhitelist: string[];
|
||||
guestEnable: boolean;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,11 @@ import { ref, computed, onMounted } from "vue";
|
|||
import { useRoute } from "vue-router";
|
||||
import { useRouteParams, useRouteQuery } from "@vueuse/router";
|
||||
import { useRoomApi } from "@/hooks/useRoom";
|
||||
import { indexStore } from "@/stores";
|
||||
import { userStore } from "@/stores/user";
|
||||
|
||||
const { settings } = indexStore();
|
||||
const { isLogin } = userStore();
|
||||
const route = useRoute();
|
||||
const roomID = useRouteParams("roomId");
|
||||
const pwd = useRouteQuery("pwd");
|
||||
|
@ -28,7 +33,7 @@ const formData = ref<{
|
|||
});
|
||||
if (props.item) formData.value = props.item;
|
||||
|
||||
const { checkRoom, joinRoom } = useRoomApi(formData.value.roomId);
|
||||
const { checkRoom, joinRoom, guestJoinRoom } = useRoomApi(formData.value.roomId);
|
||||
|
||||
onMounted(() => {
|
||||
if (formData.value.roomId) checkRoom(pwd.value as string);
|
||||
|
@ -55,7 +60,15 @@ onMounted(() => {
|
|||
autocomplete="new-password"
|
||||
/>
|
||||
<br />
|
||||
<button class="btn m-[10px]" @click="joinRoom(formData)">加入</button>
|
||||
|
||||
<button
|
||||
v-if="settings?.guestEnable && !isLogin"
|
||||
class="btn btn-success my-[10px]"
|
||||
@click="guestJoinRoom(formData)"
|
||||
>
|
||||
以访客身份加入
|
||||
</button>
|
||||
<button v-else class="btn my-[10px]" @click="joinRoom(formData)">加入</button>
|
||||
<div class="text-sm">
|
||||
<b>注意:</b>所有输入框最大只可输入32个字符
|
||||
<br />
|
||||
|
|
|
@ -3,6 +3,7 @@ import { ref, onUnmounted } from "vue";
|
|||
import { ElNotification } from "element-plus";
|
||||
import type { RoomList } from "@/types/Room";
|
||||
import JoinRoom from "./JoinRoom.vue";
|
||||
import { indexStore } from "@/stores";
|
||||
import { userStore } from "@/stores/user";
|
||||
import { useTimeAgo } from "@vueuse/core";
|
||||
import { useRouter } from "vue-router";
|
||||
|
@ -21,9 +22,10 @@ const formData = ref<{
|
|||
const { totalItems, currentPage, pageSize, keyword, search, getRoomList, roomList, joinRoom } =
|
||||
useRoomApi(formData.value.roomId);
|
||||
|
||||
const { settings } = indexStore();
|
||||
const JoinRoomDialog = ref(false);
|
||||
const openJoinRoomDialog = async (item: RoomList) => {
|
||||
if (!isLogin.value) {
|
||||
if (!settings?.guestEnable && isLogin.value) {
|
||||
ElNotification({
|
||||
title: "错误",
|
||||
message: "请先登录",
|
||||
|
|
Loading…
Reference in New Issue