Opt: room manage

This commit is contained in:
Lazy 2024-04-18 16:34:48 +08:00
parent 629ebf9671
commit 46787ca6dd
10 changed files with 126 additions and 80 deletions

View File

@ -5,9 +5,10 @@ import { useRouteParams } from "@vueuse/router";
import { roomStore } from "@/stores/room";
import type { EditMovieInfo, MovieInfo } from "@/types/Movie";
import { useMovieApi } from "@/hooks/useMovie";
import { useRoomApi, RoomMemberPermission, useRoomPermission } from "@/hooks/useRoom";
import { useRoomApi, useRoomPermission } from "@/hooks/useRoom";
import customHeaders from "@/components/cinema/dialogs/customHeaders.vue";
import customSubtitles from "@/components/cinema/dialogs/customSubtitles.vue";
import { RoomMemberPermission } from "@/types/Room";
const customHeadersDialog = ref<InstanceType<typeof customHeaders>>();
const customSubtitlesDialog = ref<InstanceType<typeof customSubtitles>>();

View File

@ -1,5 +1,5 @@
<script lang="ts" setup>
import { ref } from "vue";
import { computed, ref } from "vue";
import { ElNotification } from "element-plus";
import { roomSettingsApi } from "@/services/apis/room";
import { updateRoomPasswordApi, delRoomApi } from "@/services/apis/room";
@ -7,7 +7,9 @@ import { useLocalStorage } from "@vueuse/core";
import { useRouteParams } from "@vueuse/router";
import { useSettings, type settingType } from "@/hooks/useSettings";
import { useUpdateSettings } from "@/hooks/useUpdateSettings";
import { strLengthLimit } from "@/utils";
import { parsePermissions, strLengthLimit } from "@/utils";
import { useRoomApi, useRoomPermission } from "@/hooks/useRoom";
import { ROLE, RoomAdminPermission, RoomMemberPermission } from "@/types/Room";
const open = ref(false);
const roomID = useRouteParams<string>("roomId");
@ -21,28 +23,41 @@ const openDrawer = async () => {
await getRoomSettings();
};
const { myInfo } = useRoomApi(roomID.value);
const { hasAdminPermission, roomMemberPermissionKeys, roomMemberPermissionKeysTranslate } =
useRoomPermission();
const can = (p: RoomAdminPermission) => {
if (!myInfo.value) return;
const myP = myInfo.value.adminPermissions;
return hasAdminPermission(myP, p);
};
const isAdmin = computed(() => myInfo.value!.role >= ROLE.Admin);
const { state, execute, isReady } = roomSettingsApi();
const getRoomSettings = async () => {
try {
const url = isAdmin.value ? "/api/room/admin/settings" : "/api/room/settings";
await execute({
headers: {
Authorization: roomToken.value
}
},
url
});
if (!state.value) return;
userDefaultPermissions.value = parsePermissions(state.value.user_default_permissions, "member");
for (const setting in state.value) {
if (settings.value.has(setting)) {
settings.value.set(setting, {
value: (state.value as any)[setting],
name: settings.value.get(setting)!.name
});
} else {
settings.value.set(setting, {
value: (state.value as any)[setting],
name: setting
});
}
// else {
// settings.value.set(setting, {
// value: (state.value as any)[setting],
// name: setting
// });
// }
}
// state
@ -128,6 +143,11 @@ const deleteRoom = async () => {
}
};
const userDefaultPermissions = ref<number[]>([]);
const computedUserDefaultPermissions = computed(() =>
userDefaultPermissions.value.reduce((total, permission) => total | permission, 0)
);
defineExpose({
openDrawer
});
@ -154,22 +174,48 @@ defineExpose({
<el-switch
v-if="typeof setting[1].value === 'boolean'"
v-model="setting[1].value"
:disabled="!can(RoomAdminPermission.PermissionSetRoomSettings)"
@click="updateSet(setting[0], setting[1].value)"
/>
<el-input
v-else
v-model.trim.lazy="setting[1].value"
:placeholder="setting[1].placeholder"
:disabled="setting[1].disabled"
:disabled="!can(RoomAdminPermission.PermissionSetRoomSettings) && setting[1].disabled"
:type="setting[1].isTextarea ? 'textarea' : 'text'"
@change="updateSet(setting[0], setting[1].value)"
>
<template #append v-if="setting[1].append">{{ setting[1].append }}</template>
</el-input>
</el-form-item>
<el-form-item label="用户默认权限">
<div class="flex">
<el-select
v-model="userDefaultPermissions"
multiple
collapse-tags
collapse-tags-tooltip
:disabled="!isAdmin && !can(RoomAdminPermission.PermissionSetRoomSettings)"
>
<el-option
v-for="(item, i) in roomMemberPermissionKeys"
:key="i"
:label="
roomMemberPermissionKeysTranslate[item.value as unknown as RoomMemberPermission]
"
:value="item.value"
/>
</el-select>
<el-button
v-if="isAdmin && can(RoomAdminPermission.PermissionSetRoomSettings)"
@click="updateSet('user_default_permissions', computedUserDefaultPermissions)"
>更新</el-button
>
</div>
</el-form-item>
<el-form-item label="房间密码">
<el-input v-model.trim.lazy="password" show-password>
<template #append>
<template #append v-if="can(RoomAdminPermission.PermissionSetRoomSettings)">
<el-popconfirm
width="220"
confirm-button-text="是"
@ -187,7 +233,7 @@ defineExpose({
</el-form>
</div>
</template>
<template #footer>
<template #footer v-if="can(RoomAdminPermission.PermissionDeleteRoom)">
<div style="flex: auto">
<el-popconfirm
width="220"

View File

@ -12,12 +12,8 @@ import {
setAdminApi,
setMemberApi
} from "@/services/apis/room";
import {
useRoomApi,
RoomAdminPermission,
useRoomPermission,
RoomMemberPermission
} from "@/hooks/useRoom";
import { useRoomApi, useRoomPermission } from "@/hooks/useRoom";
import { RoomAdminPermission, RoomMemberPermission } from "@/types/Room";
import UserPermission from "./UserPermission.vue";
const open = ref(false);

View File

@ -1,10 +1,12 @@
<script lang="ts" setup>
import { computed, ref } from "vue";
import { ElNotification } from "element-plus";
import { RoomMemberPermission, RoomAdminPermission, useRoomPermission } from "@/hooks/useRoom";
import { useRoomPermission } from "@/hooks/useRoom";
import { RoomAdminPermission, RoomMemberPermission } from "@/types/Room";
import { setMemberPermitApi, setAdminPermitApi } from "@/services/apis/room";
import { useLocalStorage } from "@vueuse/core";
import { useRouteParams } from "@vueuse/router";
import { parsePermissions } from "@/utils";
const open = ref(false);
const mP = ref<number[]>([]);
@ -33,19 +35,6 @@ const {
} = useRoomPermission();
const tabs = ref<"default" | "admin">("default");
const parsePermissions = (permissions: number, type: "member" | "admin") => {
let result: number[] = [];
const P = type === "member" ? RoomMemberPermission : RoomAdminPermission;
for (let permission in P) {
if (!isNaN(Number(permission))) {
if ((permissions & Number(permission)) !== 0) {
result.push(Number(permission));
}
}
}
return result;
};
const memberPermissionKeys = roomMemberPermissionKeys.map((key) => ({
key: key.value,
label: roomMemberPermissionKeysTranslate[key.value as unknown as RoomMemberPermission],

View File

@ -8,45 +8,12 @@ import { userRoomListApi } from "@/services/apis/admin";
import { joinRoomApi, checkRoomApi, roomListApi, hotRoom, myInfoApi } from "@/services/apis/room";
import { strLengthLimit } from "@/utils";
import { storeToRefs } from "pinia";
import { RoomMemberPermission, RoomAdminPermission } from "@/types/Room";
// 获取用户信息
const { info, token } = userStore();
const { myInfo } = storeToRefs(roomStore());
// 房间权限(默认用户)
export enum RoomMemberPermission {
PermissionGetMovieList = 1 << 0,
PermissionAddMovie = 1 << 1,
PermissionDeleteMovie = 1 << 2,
PermissionEditMovie = 1 << 3,
PermissionSetCurrentMovie = 1 << 4,
PermissionSetCurrentStatus = 1 << 5,
PermissionSendChatMessage = 1 << 6,
// AllPermissions = (2 ^ 32) - 1,
NoPermission = 0
// DefaultPermissions = RoomMemberPermission.PermissionGetMovieList |
// RoomMemberPermission.PermissionSendChatMessage
}
// 房间权限(管理员)
export enum RoomAdminPermission {
PermissionApprovePendingMember = 1 << 0,
PermissionBanRoomMember = 1 << 1,
PermissionSetUserPermission = 1 << 2,
PermissionSetRoomSettings = 1 << 3,
PermissionSetRoomPassword = 1 << 4,
PermissionDeleteRoom = 1 << 5,
// AllAdminPermissions = (2 ^ 32) - 1,
NoAdminPermission = 0
// DefaultAdminPermissions = RoomAdminPermission.PermissionApprovePendingMember |
// RoomAdminPermission.PermissionBanRoomMember |
// RoomAdminPermission.PermissionSetUserPermission |
// RoomAdminPermission.PermissionSetRoomSettings |
// RoomAdminPermission.PermissionSetRoomPassword
}
export const useRoomApi = (roomId: string) => {
// 检查房间状态
const { state: thisRoomInfo, execute: reqCheckRoomApi } = checkRoomApi();

View File

@ -104,7 +104,7 @@ export const useSettings = () => {
["hidden", { value: false, name: "隐藏此房间" }],
["disable_join_new_user", { value: false, name: "禁止新用户加入" }],
["join_need_review", { value: false, name: "加入需要审核" }],
["user_default_permissions", { value: 0, name: "用户默认权限" }],
// ["user_default_permissions", { value: 0, name: "用户默认权限" }],
["can_get_movie_list", { value: false, name: "允许用户获取影片列表" }],
["can_add_movie", { value: false, name: "允许用户添加影片" }],
["can_edit_movie", { value: false, name: "允许用户编辑影片" }],

View File

@ -152,7 +152,6 @@ export const roomSettingsApi = useDefineApi<
can_send_chat_message: boolean;
}
>({
url: "/api/room/admin/settings",
method: "GET"
});

View File

@ -1,4 +1,4 @@
import type { RoomAdminPermission, RoomMemberPermission } from "@/hooks/useRoom";
// import type { RoomAdminPermission, RoomMemberPermission } from "@/hooks/useRoom";
export interface RoomList {
roomId: string;
@ -11,6 +11,40 @@ export interface RoomList {
status: number;
}
// 房间权限(默认用户)
export enum RoomMemberPermission {
PermissionGetMovieList = 1 << 0,
PermissionAddMovie = 1 << 1,
PermissionDeleteMovie = 1 << 2,
PermissionEditMovie = 1 << 3,
PermissionSetCurrentMovie = 1 << 4,
PermissionSetCurrentStatus = 1 << 5,
PermissionSendChatMessage = 1 << 6,
// AllPermissions = (2 ^ 32) - 1,
NoPermission = 0
// DefaultPermissions = RoomMemberPermission.PermissionGetMovieList |
// RoomMemberPermission.PermissionSendChatMessage
}
// 房间权限(管理员)
export enum RoomAdminPermission {
PermissionApprovePendingMember = 1 << 0,
PermissionBanRoomMember = 1 << 1,
PermissionSetUserPermission = 1 << 2,
PermissionSetRoomSettings = 1 << 3,
PermissionSetRoomPassword = 1 << 4,
PermissionDeleteRoom = 1 << 5,
// AllAdminPermissions = (2 ^ 32) - 1,
NoAdminPermission = 0
// DefaultAdminPermissions = RoomAdminPermission.PermissionApprovePendingMember |
// RoomAdminPermission.PermissionBanRoomMember |
// RoomAdminPermission.PermissionSetUserPermission |
// RoomAdminPermission.PermissionSetRoomSettings |
// RoomAdminPermission.PermissionSetRoomPassword
}
export interface MyInfo {
userId: string;
roomId: string;

View File

@ -1,3 +1,4 @@
import { RoomAdminPermission, RoomMemberPermission } from "@/types/Room";
import { ElMessage } from "element-plus";
export const debounces = (delay: number): Function => {
@ -55,3 +56,23 @@ export const getAppIcon = (appName: string): string => {
export const getObjValue = <T extends object, K extends keyof T>(obj: T, key: K) => {
return obj[key];
};
export const parsePermissions = (permissions: number, type: "member" | "admin") => {
let result: number[] = [];
const P = type === "member" ? RoomMemberPermission : RoomAdminPermission;
for (let permission in P) {
if (!isNaN(Number(permission))) {
if ((permissions & Number(permission)) !== 0) {
result.push(Number(permission));
}
}
}
return result;
};
export const formatTime = (date: Date) => {
const hours = `0${date.getHours()}`.slice(-2);
const minutes = `0${date.getMinutes()}`.slice(-2);
const seconds = `0${date.getSeconds()}`.slice(-2);
return `${hours}:${minutes}:${seconds}`;
};

View File

@ -15,26 +15,19 @@ import { roomStore } from "@/stores/room";
import { ElNotification, ElMessage } from "element-plus";
import router from "@/router";
import { useMovieApi } from "@/hooks/useMovie";
import { RoomMemberPermission, useRoomApi, useRoomPermission } from "@/hooks/useRoom";
import { useRoomApi, useRoomPermission } from "@/hooks/useRoom";
import artplayerPluginDanmuku from "artplayer-plugin-danmuku";
import { strLengthLimit, blobToUint8Array } from "@/utils";
import { strLengthLimit, blobToUint8Array, formatTime } from "@/utils";
import { ElementMessage, ElementMessageType } from "@/proto/message";
import type { options } from "@/components/Player.vue";
import RoomInfo from "@/components/cinema/RoomInfo.vue";
import MovieList from "@/components/cinema/MovieList.vue";
import MoviePush from "@/components/cinema/MoviePush.vue";
import type { Subtitles } from "@/types/Movie";
import { RoomMemberPermission } from "@/types/Room";
const Player = defineAsyncComponent(() => import("@/components/Player.vue"));
//
const formatTime = (date: Date) => {
const hours = `0${date.getHours()}`.slice(-2);
const minutes = `0${date.getMinutes()}`.slice(-2);
const seconds = `0${date.getSeconds()}`.slice(-2);
return `${hours}:${minutes}:${seconds}`;
};
//
const room = roomStore();
const roomID = useRouteParams<string>("roomId");