mirror of
https://github.com/ZHANGTIANYAO1/teamspeak-music-bot.git
synced 2026-10-02 04:52:50 +08:00
fix(guest): add playCollection permission so guests can Play All playlist/album (#103)
- New guest flag playCollection (default OFF), gates play-playlist/play-album - Keeps playNow's non-destructive semantics intact (Play All clears the queue) - Admin-toggleable in Settings → 游客模式; default-off, backward-compatible - Frontend: gate the 播放全部 button on the flag + surface 403 as a toast instead of failing silently (the silent-failure half of the issue)
This commit is contained in:
1 parent
e2fa288f48
commit
70c0273ae7
11 files changed
+61
-22
No files matched your search
+20
-10
@@ -373,22 +373,32 @@ export const usePlayerStore = defineStore('player', {
|
||||
|
||||
async playPlaylist(playlistId: string, platform = 'netease') {
|
||||
if (!this.activeBotId) return;
|
||||
const res = await axios.post(`/api/player/${this.activeBotId}/play-playlist`, { playlistId, platform });
|
||||
if (res.data?.message) {
|
||||
this.notify(res.data.message, res.data.ok === false ? 'error' : 'info');
|
||||
try {
|
||||
const res = await axios.post(`/api/player/${this.activeBotId}/play-playlist`, { playlistId, platform });
|
||||
if (res.data?.message) {
|
||||
this.notify(res.data.message, res.data.ok === false ? 'error' : 'info');
|
||||
}
|
||||
this._setTiming(this.activeBotId, { serverElapsed: 0 });
|
||||
this._syncAfterAction();
|
||||
} catch (e: any) {
|
||||
// A 403 here means a guest lacks the "play entire collection" permission
|
||||
// (issue #103) — surface it instead of failing silently.
|
||||
this.notify(e?.response?.status === 403 ? '没有权限播放整个歌单' : '播放歌单失败', 'error');
|
||||
}
|
||||
this._setTiming(this.activeBotId, { serverElapsed: 0 });
|
||||
this._syncAfterAction();
|
||||
},
|
||||
|
||||
async playAlbum(albumId: string, platform = 'netease') {
|
||||
if (!this.activeBotId) return;
|
||||
const res = await axios.post(`/api/player/${this.activeBotId}/play-album`, { albumId, platform });
|
||||
if (res.data?.message) {
|
||||
this.notify(res.data.message, res.data.ok === false ? 'error' : 'info');
|
||||
try {
|
||||
const res = await axios.post(`/api/player/${this.activeBotId}/play-album`, { albumId, platform });
|
||||
if (res.data?.message) {
|
||||
this.notify(res.data.message, res.data.ok === false ? 'error' : 'info');
|
||||
}
|
||||
this._setTiming(this.activeBotId, { serverElapsed: 0 });
|
||||
this._syncAfterAction();
|
||||
} catch (e: any) {
|
||||
this.notify(e?.response?.status === 403 ? '没有权限播放整个专辑' : '播放专辑失败', 'error');
|
||||
}
|
||||
this._setTiming(this.activeBotId, { serverElapsed: 0 });
|
||||
this._syncAfterAction();
|
||||
},
|
||||
|
||||
async pause() {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
{{ songs.length }} 首歌曲
|
||||
</div>
|
||||
<div class="playlist-actions">
|
||||
<button class="play-all-btn" @click="playAll">
|
||||
<button v-if="canPlayAll" class="play-all-btn" @click="playAll">
|
||||
<Icon icon="mdi:play" />
|
||||
播放全部
|
||||
</button>
|
||||
@@ -54,16 +54,22 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { ref, computed, onMounted } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { Icon } from '@iconify/vue';
|
||||
import axios from 'axios';
|
||||
import { usePlayerStore } from '../stores/player.js';
|
||||
import { useSession } from '../composables/useSession.js';
|
||||
import CoverArt from '../components/CoverArt.vue';
|
||||
import SongCard from '../components/SongCard.vue';
|
||||
|
||||
const store = usePlayerStore();
|
||||
const route = useRoute();
|
||||
const { can, guestCan } = useSession();
|
||||
|
||||
// "Play all" loads + plays the whole collection (clears the queue). Members
|
||||
// need player.control; guests need the playCollection flag (issue #103).
|
||||
const canPlayAll = computed(() => can('player.control') || guestCan('playCollection'));
|
||||
|
||||
import { Song } from '../stores/player.js';
|
||||
|
||||
|
||||
@@ -1069,12 +1069,13 @@ const GUEST_FLAGS: { token: string; label: string }[] = [
|
||||
{ token: 'transport', label: '暂停/继续/进度/音量' },
|
||||
{ token: 'removeClear', label: '移除/清空队列' },
|
||||
{ token: 'playMode', label: '切换播放模式 / FM' },
|
||||
{ token: 'playCollection', label: '播放整个歌单/专辑' },
|
||||
];
|
||||
const guestMode = reactive<{ enabled: boolean; botsAll: boolean; selectedBotIds: string[]; permissions: Record<string, boolean> }>({
|
||||
enabled: false,
|
||||
botsAll: true,
|
||||
selectedBotIds: [],
|
||||
permissions: { addToQueue: true, playNext: false, playNow: false, skip: false, transport: false, removeClear: false, playMode: false },
|
||||
permissions: { addToQueue: true, playNext: false, playNow: false, skip: false, transport: false, removeClear: false, playMode: false, playCollection: false },
|
||||
});
|
||||
const guestSaving = ref(false);
|
||||
|
||||
|
||||
Reference in new issue
Block a user