feat: 电台模式完善

This commit is contained in:
imsyy
2024-05-24 11:01:42 +08:00
parent e5f9ecd7b5
commit 4cac54c84a
23 changed files with 1111 additions and 919 deletions

View File

@@ -15,12 +15,12 @@ jobs:
steps:
# 检出 Git 仓库
- name: Check out git repository
uses: actions/checkout@v4.1.1
uses: actions/checkout@v4
# 安装 Node.js
- name: Install Node.js
uses: actions/setup-node@v4.0.0
uses: actions/setup-node@v4
with:
node-version: "18.x"
node-version: "20.x"
# 复制环境变量文件
- name: Copy .env.example
run: |
@@ -43,7 +43,20 @@ jobs:
npx rimraf "dist/!(*.exe)"
# 上传构建产物
- name: Upload artifacts
uses: actions/upload-artifact@v3.1.3
uses: actions/upload-artifact@v4
with:
name: SPlayer-dev
path: dist
# 创建 GitHub Release
- name: Release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/v')
with:
tag_name: ${{ github.ref }}
name: ${{ github.ref }}-rc
body: This version is still under development, currently only provides windows version, non-developers please do not use!
draft: false
prerelease: true
files: dist/*.exe
env:
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}

View File

@@ -16,12 +16,12 @@ jobs:
steps:
# 检出 Git 仓库
- name: Check out git repository
uses: actions/checkout@v4.1.1
uses: actions/checkout@v4
# 安装 Node.js
- name: Install Node.js
uses: actions/setup-node@v4.0.0
uses: actions/setup-node@v4
with:
node-version: "18.x"
node-version: "20.x"
# 复制环境变量文件
- name: Copy .env.example
run: |
@@ -41,14 +41,14 @@ jobs:
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
# 上传构建产物
- name: Upload Windows artifact
uses: actions/upload-artifact@v3.1.3
uses: actions/upload-artifact@v4
with:
name: SPlarer-Win
if-no-files-found: ignore
path: dist/*.*
# 创建 GitHub Release
- name: Release
uses: softprops/action-gh-release@v0.1.15
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/v')
with:
draft: true
@@ -63,12 +63,12 @@ jobs:
steps:
# 检出 Git 仓库
- name: Check out git repository
uses: actions/checkout@v4.1.1
uses: actions/checkout@v4
# 安装 Node.js
- name: Install Node.js
uses: actions/setup-node@v4.0.0
uses: actions/setup-node@v4
with:
node-version: "18.x"
node-version: "20.x"
# 复制环境变量文件
- name: Copy .env.example
run: |
@@ -88,14 +88,14 @@ jobs:
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
# 上传构建产物
- name: Upload macOS artifact
uses: actions/upload-artifact@v3.1.3
uses: actions/upload-artifact@v4
with:
name: SPlarer-Macos
if-no-files-found: ignore
path: dist/*.*
# 创建 GitHub Release
- name: Release
uses: softprops/action-gh-release@v0.1.15
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/v')
with:
draft: true
@@ -110,12 +110,12 @@ jobs:
steps:
# 检出 Git 仓库
- name: Check out git repository
uses: actions/checkout@v4.1.1
uses: actions/checkout@v4
# 安装 Node.js
- name: Install Node.js
uses: actions/setup-node@v4.0.0
uses: actions/setup-node@v4
with:
node-version: "18.x"
node-version: "20.x"
# 更新 Ubuntu 软件源
- name: Ubuntu Update with sudo
run: sudo apt-get update
@@ -138,14 +138,14 @@ jobs:
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
# 上传构建产物
- name: Upload Linux artifact
uses: actions/upload-artifact@v3.1.3
uses: actions/upload-artifact@v4
with:
name: SPlarer-Linux
if-no-files-found: ignore
path: dist/*.*
# 创建 GitHub Release
- name: Release
uses: softprops/action-gh-release@v0.1.15
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/v')
with:
draft: true

View File

@@ -1,6 +1,6 @@
{
"name": "splayer",
"version": "2.0.7",
"version": "2.0.8",
"description": "A minimalist music player",
"main": "./out/main/index.js",
"author": "imsyy",
@@ -30,8 +30,8 @@
"@electron-toolkit/preload": "^3.0.1",
"@electron-toolkit/utils": "^3.0.0",
"@material/material-color-utilities": "^0.2.7",
"NeteaseCloudMusicApi": "^4.15.8",
"axios": "^1.6.8",
"NeteaseCloudMusicApi": "^4.19.8",
"axios": "^1.7.2",
"colorthief": "^2.4.0",
"electron-dl": "^3.5.2",
"electron-store": "^8.2.0",
@@ -48,28 +48,28 @@
"pinia-plugin-persistedstate": "^3.2.1",
"plyr": "^3.7.8",
"screenfull": "^6.0.2",
"vue-router": "^4.3.0",
"vue-router": "^4.3.2",
"vue-slider-component": "4.1.0-beta.7"
},
"devDependencies": {
"@electron-toolkit/eslint-config": "^1.0.2",
"@rushstack/eslint-patch": "^1.10.2",
"@rushstack/eslint-patch": "^1.10.3",
"@vitejs/plugin-vue": "^5.0.4",
"@vue/eslint-config-prettier": "^9.0.0",
"ajv": "^8.12.0",
"electron": "^28.3.0",
"ajv": "^8.13.0",
"electron": "^28.3.2",
"electron-builder": "^24.13.3",
"electron-log": "^5.1.2",
"electron-vite": "^2.1.0",
"electron-log": "^5.1.4",
"electron-vite": "^2.2.0",
"eslint": "^8.57.0",
"eslint-plugin-vue": "^9.25.0",
"naive-ui": "^2.38.1",
"eslint-plugin-vue": "^9.26.0",
"naive-ui": "^2.38.2",
"prettier": "^3.2.5",
"sass": "^1.75.0",
"terser": "^5.30.3",
"unplugin-auto-import": "^0.17.5",
"sass": "^1.77.2",
"terser": "^5.31.0",
"unplugin-auto-import": "^0.17.6",
"unplugin-vue-components": "^0.26.0",
"vite": "^5.2.9",
"vite": "^5.2.11",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-pwa": "^0.17.5",
"vue": "3.4.8"

1670
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -95,3 +95,24 @@ export const likeComment = (id, cid, t, type = 0) => {
},
});
};
/**
* 电台节目评论
* @param {number} id - 电台节目的 id
* @param {number} limit - 取出评论数量 , 默认为 20
* @param {number} offset - 偏移数量 , 用于分页 , 如 :( 评论页数 -1)*20, 其中 20 为 limit 的值
* @param {string} before - 分页参数,取上一页最后一项的 time 获取下一页数据(获取超过 5000 条评论的时候需要用到)
*/
export const commentDj = (id, limit, offset, before) => {
return axios({
method: "GET",
url: "/comment/dj",
params: {
id,
limit,
offset,
before,
timestamp: new Date().getTime(),
},
});
};

View File

@@ -118,6 +118,20 @@ export const getDjProgram = (rid, limit = 50, offset = 0) => {
});
};
/**
* 电台 - 节目详情
* @param {string} id - 电台 的 id
*/
export const getDjProgramDetail = (id) => {
return axios({
method: "GET",
url: "/dj/program/detail",
params: {
id,
},
});
};
/**
* 电台 - 订阅
* @param {number} rid - 电台 的 id

View File

@@ -40,7 +40,7 @@
class="loading-img"
:src="
type === 'mv'
? '/images/pic/video.png?assest'
? '/images/pic/video.jpg?assest'
: type === 'artist'
? '/images/pic/artist.jpg?assest'
: '/images/pic/album.jpg?assest'

View File

@@ -77,7 +77,11 @@
</n-text>
<!-- 特权 -->
<n-tag
v-if="showPrivilege && item.fee === 1 && userData.detail?.profile?.vipType !== 11"
v-if="
showPrivilege &&
item.fee === 1 &&
(userData.detail?.profile?.vipType !== 11 || !hiddenVipTags)
"
:bordered="false"
type="error"
size="small"
@@ -281,7 +285,7 @@ const dataStore = siteData();
const status = siteStatus();
const settings = siteSettings();
const { userData } = storeToRefs(dataStore);
const { loadSize, playSearch, useMusicCache } = storeToRefs(settings);
const { loadSize, playSearch, useMusicCache, hiddenVipTags } = storeToRefs(settings);
const { playList, playSongData, playSongSource } = storeToRefs(music);
const { playIndex, playMode, playHeartbeatMode, playLoading } = storeToRefs(status);

View File

@@ -50,7 +50,7 @@
<div class="left">
<!-- 歌词模式 -->
<n-icon
v-if="isHasLrc"
v-if="isHasLrc && playMode !== 'dj'"
:class="['lrc-open', { open: pureLyricMode }]"
size="28"
@click="pureLyricMode = !pureLyricMode"
@@ -78,11 +78,17 @@
:key="`${pureLyricMode}-${playCoverType}-${isHasLrc}-${music.getPlaySongData?.id}`"
class="main-player"
>
<div v-show="!(pureLyricMode && isHasLrc)" :class="['content', { 'no-lrc': !isHasLrc }]">
<div
v-show="!(pureLyricMode && isHasLrc) || playMode === 'dj'"
:class="['content', { 'no-lrc': !isHasLrc || playMode === 'dj' }]"
>
<!-- 封面 -->
<PlayerCover />
<!-- 信息 -->
<div v-show="playCoverType === 'cover' || !isHasLrc" :class="['data', playCoverType]">
<div
v-show="playCoverType === 'cover' || !isHasLrc || playMode === 'dj'"
:class="['data', playCoverType]"
>
<div class="desc">
<div class="title">
<span class="name">{{ music.getPlaySongData.name || "未知曲目" }}</span>
@@ -115,7 +121,7 @@
<span v-if="music.getPlaySongData.alia" class="alia">
{{ music.getPlaySongData.alia }}
</span>
<div class="artist">
<div v-if="playMode !== 'dj'" class="artist">
<n-icon depth="3" size="20">
<SvgIcon icon="account-music" />
</n-icon>
@@ -139,6 +145,7 @@
</div>
</div>
<div
v-if="playMode !== 'dj'"
class="album"
@click.stop="
() => {
@@ -161,10 +168,28 @@
</span>
<span v-else class="album">未知专辑</span>
</div>
<div
v-if="playMode === 'dj'"
class="dj"
@click.stop="
() => {
if (!playSongSource) return;
showFullPlayer = false;
router.push(`/dj?id=${playSongSource}`);
}
"
>
<n-icon depth="3" size="20">
<SvgIcon icon="record" />
</n-icon>
<span class="dj-name">
{{ music.getPlaySongData.creator?.brand || "未知电台" }}
</span>
</div>
</div>
</div>
</div>
<div :class="['right', { pure: pureLyricMode && isHasLrc }]">
<div v-if="playMode !== 'dj'" :class="['right', { pure: pureLyricMode && isHasLrc }]">
<!-- 唱片模式下信息 -->
<div
v-show="(pureLyricMode && isHasLrc) || (playCoverType === 'record' && isHasLrc)"
@@ -249,7 +274,7 @@ const router = useRouter();
const music = musicData();
const status = siteStatus();
const settings = siteSettings();
const { playList, playSongLyric } = storeToRefs(music);
const { playList, playSongLyric, playSongSource } = storeToRefs(music);
const { playerBackgroundType, showYrc, playCoverType, showSpectrums } = storeToRefs(settings);
const {
playerControlShow,
@@ -259,6 +284,7 @@ const {
coverTheme,
coverBackground,
pureLyricMode,
playMode,
} = storeToRefs(status);
// 是否有歌词
@@ -388,6 +414,11 @@ onUnmounted(() => {
&.gradient {
background: var(--cover-bg);
}
&.none {
&::after {
display: none;
}
}
}
// 按钮
.menu {
@@ -547,6 +578,25 @@ onUnmounted(() => {
}
}
}
.dj {
margin-top: 12px;
font-size: 16px;
display: flex;
align-items: center;
.n-icon {
margin-right: 4px;
color: var(--cover-main-color);
}
.dj-name {
opacity: 0.7;
transition: opacity 0.3s;
-webkit-line-clamp: 2;
cursor: pointer;
&:hover {
opacity: 1;
}
}
}
}
&.record {
width: 100%;

View File

@@ -94,7 +94,7 @@
</n-icon>
<!-- 更多操作 -->
<n-dropdown
v-if="playMode !== 'dj' && !music.getPlaySongData?.path"
v-if="!music.getPlaySongData?.path"
:options="songMoreOptions"
:show-arrow="true"
placement="top-start"
@@ -415,6 +415,7 @@ const songMoreOptions = computed(() => [
{
key: "add-pl",
label: "添加到歌单",
show: playMode.value !== "dj",
props: {
onClick: () => {
addPlaylistRef.value?.openAddToPlaylist(music.getPlaySongData?.id);
@@ -431,6 +432,7 @@ const songMoreOptions = computed(() => [
path: "/comment",
query: {
id: music.getPlaySongData?.id,
type: playMode.value,
},
});
},
@@ -440,7 +442,9 @@ const songMoreOptions = computed(() => [
{
key: "mv",
label: "观看 MV",
show: music.getPlaySongData?.mv && music.getPlaySongData?.mv !== 0 ? true : false,
show:
playMode.value !== "dj" &&
(music.getPlaySongData?.mv && music.getPlaySongData?.mv !== 0 ? true : false),
props: {
onClick: () => {
router.push({
@@ -456,7 +460,7 @@ const songMoreOptions = computed(() => [
{
key: "download",
label: "下载歌曲",
show: music.getPlaySongData?.path ? false : true,
show: playMode.value !== "dj" && (music.getPlaySongData?.path ? false : true),
props: {
onClick: () => {
downloadSongRef.value?.openDownloadModal(music.getPlaySongData);
@@ -487,10 +491,10 @@ const songTimeSliderUpdate = (val) => {
// 开启播放器
const openFullPlayer = () => {
if (playMode.value === "dj") {
$message.warning("当前为电台模式,无法开启播放器");
return false;
}
// if (playMode.value === "dj") {
// $message.warning("当前为电台模式,无法开启播放器");
// return false;
// }
if (showSpectrums.value && typeof $player !== "undefined") processSpectrum($player);
showFullPlayer.value = true;
};

View File

@@ -10,7 +10,7 @@
<div class="left">
<!-- 喜欢歌曲 -->
<n-icon
v-if="!music.getPlaySongData.path"
v-if="!music.getPlaySongData.path && playMode !== 'dj'"
size="24"
@click.stop="
data.changeLikeList(
@@ -30,7 +30,7 @@
</n-icon>
<!-- 添加到歌单 -->
<n-icon
v-if="!music.getPlaySongData.path"
v-if="!music.getPlaySongData.path && playMode !== 'dj'"
class="hidden"
size="24"
@click.stop="addPlaylistRef?.openAddToPlaylist(music.getPlaySongData?.id)"
@@ -39,7 +39,7 @@
</n-icon>
<!-- 下载 -->
<n-icon
v-if="!music.getPlaySongData.path"
v-if="!music.getPlaySongData.path && playMode !== 'dj'"
class="hidden"
size="24"
@click.stop="downloadSongRef?.openDownloadModal(music.getPlaySongData)"
@@ -125,9 +125,7 @@
v-if="!music.getPlaySongData?.path"
class="hidden"
size="22"
@click.stop="
(showFullPlayer = false), router.push(`/comment?id=${music.getPlaySongData?.id}`)
"
@click.stop="jumpToComment"
>
<SvgIcon icon="comment-text" />
</n-icon>
@@ -187,7 +185,7 @@
/>
</n-icon>
<!-- 播放列表 -->
<n-icon v-if="playMode === 'normal'" size="22" @click.stop="playListShow = !playListShow">
<n-icon v-if="playMode !== 'fm'" size="22" @click.stop="playListShow = !playListShow">
<SvgIcon icon="queue-music-rounded" />
</n-icon>
</div>
@@ -311,6 +309,18 @@ const controlEnter = () => {
const controlMove = (e) => {
if (!e.target.closest(".slider")) e.stopPropagation();
};
// 跳转至评论
const jumpToComment = () => {
showFullPlayer.value = false;
router.push({
path: "/comment",
query: {
id: music.getPlaySongData?.id,
type: playMode.value,
},
});
};
</script>
<style lang="scss" scoped>

View File

@@ -1,6 +1,6 @@
<!-- 播放器 - 专辑封面 -->
<template>
<div :class="['cover', playCoverType]">
<div :class="['mian-cover', playCoverType, { playing: playState }]">
<!-- 指针 -->
<img
v-if="playCoverType === 'record'"
@@ -57,7 +57,7 @@ const { playState } = storeToRefs(status);
</script>
<style lang="scss" scoped>
.cover {
.mian-cover {
position: relative;
display: flex;
align-items: center;
@@ -66,13 +66,14 @@ const { playState } = storeToRefs(status);
max-width: 55vh;
height: auto;
aspect-ratio: 1 / 1;
transition: transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
.cover-img {
width: 100%;
height: 100%;
border-radius: 32px;
overflow: hidden;
z-index: 1;
box-shadow: 0 0 10px 6px #00000008;
box-shadow: 0 0 20px 10px rgb(0 0 0 / 10%);
transition: opacity 0.1s ease-in-out;
:deep(img) {
width: 100%;
@@ -206,6 +207,13 @@ const { playState } = storeToRefs(status);
display: none;
}
}
&.cover {
transform: scale(0.9);
&.playing {
transform: scale(1);
}
}
@media (max-width: 700px) {
&.record {
.pointer {

View File

@@ -16,6 +16,7 @@ const useSiteSettingsStore = defineStore("siteSettings", {
autoCheckUpdates: true, // 自动检查更新
systemFonts: "HarmonyOS Sans", // 全局字体
justLyricArea: false, // 仅在歌词区域生效
hiddenVipTags: false, // 隐藏 VIP 标签
// 主题部分
themeType: "dark",
themeAuto: false,

View File

@@ -32,6 +32,7 @@ const useSiteStatusStore = defineStore("siteStatus", {
pureLyricMode: false,
// 音乐频谱数据
spectrumsData: [],
spectrumsScaleData: 1,
// 当前歌曲歌词播放索引
playSongLyricIndex: -1,
// 播放时长数据

View File

@@ -23,6 +23,7 @@ let spectrumsData = {
audio: null,
analyser: null,
audioCtx: null,
scale: 1,
};
// 默认标题
let defaultTitle = document.title;
@@ -56,13 +57,15 @@ export const initPlayer = async (playNow = false) => {
if (playMode === "fm") music.playSongData = {};
// 在线歌曲
if (!isLocalSong) {
// 获取歌曲信息
const { id } = playSongData;
if (!id) return false;
// 获取歌曲 ID
let songId = playSongData?.id;
if (!songId) return false;
// 若为电台模式
if (playMode === "dj") songId = music.getPlaySongData?.djId;
// 开启加载状态
status.playLoading = true;
// 获取播放地址
const url = await getNormalSongUrl(id, status, playNow);
const url = await getNormalSongUrl(songId, status, playNow);
// 正常播放地址
if (url) {
status.playUseOtherSource = false;
@@ -90,7 +93,7 @@ export const initPlayer = async (playNow = false) => {
// 下一曲
else {
if (playIndex !== playList.length - 1) {
changePlayIndex();
// changePlayIndex();
} else {
status.playLoading = false;
status.playState = false;
@@ -235,7 +238,7 @@ export const createPlayer = async (src, autoPlay = true) => {
const audioDom = player._sounds[0]._node;
audioDom.crossOrigin = "anonymous";
// 写入播放历史
music.setPlayHistory(playSongData);
if (playMode !== "dj") music.setPlayHistory(playSongData);
// 生成音乐频谱
// 由于浏览器安全策略,无法在此处启动
if (showSpectrums && checkPlatform.electron()) processSpectrum(player);
@@ -755,8 +758,12 @@ export const processSpectrum = (sound) => {
const updateSpectrums = (analyser, dataArray) => {
// pinia
const status = siteStatus();
// 获取频率数据
analyser.getByteFrequencyData(dataArray);
status.spectrumsData = [...dataArray];
// 计算 scale
const averageAmplitude = dataArray.reduce((acc, val) => acc + val, 0) / dataArray.length;
status.spectrumsScaleData = (averageAmplitude / 512 + 1).toFixed(2);
// 递归调用,持续更新频谱数据
requestAnimationFrame(() => {
updateSpectrums(analyser, dataArray);

View File

@@ -112,7 +112,8 @@ const formatData = (data, type = "playlist", noTracks = false) => {
// dj
case "dj":
return {
id: v.mainTrackId || v.id || v.vid,
id: v.id || v.vid,
djId: v.mainTrackId || v.id,
name: v.name,
creator: v.dj,
count: v.programCount,

View File

@@ -11,7 +11,6 @@ const globalEvents = (router) => {
// 显示播放器
electron.ipcRenderer.on("showPlayer", () => {
const status = siteStatus();
if (status.playMode === "dj") return false;
status.showFullPlayer = true;
});
// 播放或暂停

View File

@@ -9,6 +9,9 @@ import { siteStatus } from "@/stores";
*/
const globalShortcut = (e, router) => {
if (!e) return false;
// 是否按下 Ctrl
if (!e.ctrlKey) return false;
e.preventDefault();
e.stopPropagation();

View File

@@ -32,7 +32,7 @@
</n-image>
<div class="content">
<div class="name">{{ songDetail?.name || "未知曲目" }}</div>
<div class="artist">
<div v-if="commentType === 'normal'" class="artist">
<n-icon depth="3" size="20">
<SvgIcon icon="account-music" />
</n-icon>
@@ -45,6 +45,14 @@
<span class="ar"> {{ songDetail?.artists || "未知艺术家" }} </span>
</div>
</div>
<div v-else-if="songDetail?.creator" class="artist dj">
<n-icon depth="3" size="20">
<SvgIcon icon="record" />
</n-icon>
<span class="all-ar dj-name">
{{ songDetail.creator?.brand || "未知电台" }}
</span>
</div>
</div>
</n-card>
</Transition>
@@ -86,7 +94,8 @@
<script setup>
import { useRouter } from "vue-router";
import { getSongDetail } from "@/api/song";
import { getComment, getHotComment } from "@/api/comment";
import { getDjProgramDetail } from "@/api/dj";
import { getComment, getHotComment, commentDj } from "@/api/comment";
import formatData from "@/utils/formatData";
const router = useRouter();
@@ -94,6 +103,9 @@ const router = useRouter();
// 歌曲 id
const songId = ref(router.currentRoute.value.query.id);
// 评论类型
const commentType = ref(router.currentRoute.value.query.type || "normal");
// 歌曲信息
const songDetail = ref(null);
@@ -105,9 +117,15 @@ const hotCommentData = ref(null);
// 获取歌曲详情
const getSongDetailData = async (id) => {
try {
const detail = await getSongDetail(id);
const data = formatData(detail?.songs?.[0], "song");
songDetail.value = data?.[0] ?? null;
if (commentType.value === "normal") {
const detail = await getSongDetail(id);
const data = formatData(detail?.songs?.[0], "song");
songDetail.value = data?.[0] ?? null;
} else if (commentType.value === "dj") {
const detail = await getDjProgramDetail(id);
const data = formatData(detail?.program, "dj");
songDetail.value = data?.[0] ?? null;
}
} catch (error) {
console.error("获取歌曲详情失败:", error);
}
@@ -120,14 +138,24 @@ const getCommentData = async (id, pageNo = 1, sortType = 3, pageSize = 20) => {
const cursor =
pageNo !== 1 && commentData.value?.cursor !== "0" ? commentData.value.cursor : null;
// 获取热门评论和普通评论
const [hotComments, comments] = await Promise.all([
pageNo === 1 ? getHotComment(id, 0, 10) : null,
getComment(id, 0, pageNo, sortType, pageSize, cursor),
]);
// 更新数据
if (comments?.data.totalCount === 0) return (commentData.value = "empty");
commentData.value = comments?.data;
hotCommentData.value = hotComments?.hotComments?.[0] ? hotComments.hotComments : "no-comment";
if (commentType.value === "normal") {
const [hotComments, comments] = await Promise.all([
pageNo === 1 ? getHotComment(id, 0, 10) : null,
getComment(id, 0, pageNo, sortType, pageSize, cursor),
]);
// 更新数据
if (comments?.data.totalCount === 0) return (commentData.value = "empty");
commentData.value = comments?.data;
hotCommentData.value = hotComments?.hotComments?.[0] ? hotComments.hotComments : "no-comment";
} else if (commentType.value === "dj") {
const offset = (pageNo - 1) * pageSize;
const { hotComments, comments, total } = await commentDj(id, pageSize, offset, cursor);
// 更新数据
if (total === 0) return (commentData.value = "empty");
commentData.value = { totalCount: comments?.length, comments };
hotCommentData.value = hotComments?.[0] ? hotComments : "no-comment";
console.log(commentData.value, hotCommentData.value);
}
} catch (error) {
console.error("获取评论数据出错:", error);
$message.error("获取评论数据出错");
@@ -149,7 +177,7 @@ const scrollToComment = () => {
}
};
// 检查是否具有视频 id
// 检查是否具有 id
const isHasCommentId = (id) => {
if (!id) {
$message.error("参数不完整");

View File

@@ -170,9 +170,9 @@
<div v-if="djData !== 'empty'" class="list">
<Transition name="fade" mode="out-in">
<div v-if="!searchValue" class="song-list">
<SongList :data="djData" type="dj" />
<SongList :data="djData" :sourceId="djId" type="dj" />
</div>
<SongList v-else-if="searchData?.length" :data="searchData" type="dj" />
<SongList v-else-if="searchData?.length" :data="searchData" :sourceId="djId" type="dj" />
<n-empty
v-else
:description="`搜不到关于 ${searchValue} 的任何节目`"

View File

@@ -122,6 +122,13 @@
class="set"
/>
</n-card>
<n-card class="set-item">
<div class="name">
隐藏 VIP 歌曲标签
<n-text class="tip">是否在歌曲列表中隐藏 VIP 歌曲标签</n-text>
</div>
<n-switch v-model:value="hiddenVipTags" :round="false" />
</n-card>
</div>
</template>
@@ -143,6 +150,7 @@ const {
showSearchHistory,
autoSignIn,
siderShowCover,
hiddenVipTags,
} = storeToRefs(settings);
// 基础数据

View File

@@ -103,6 +103,10 @@
label: '主色渐变',
value: 'gradient',
},
{
label: '无背景',
value: 'none',
},
]"
class="set"
/>

View File

@@ -5,6 +5,15 @@
<n-scrollbar style="max-height: 120px">
{{ status.spectrumsData }}
</n-scrollbar>
<n-scrollbar style="max-height: 120px">
{{ status.spectrumsScaleData }}
<div
:style="{
transform: `scale(${status.spectrumsScaleData})`,
}"
class="point"
></div>
</n-scrollbar>
</n-card>
<n-card title="频谱图">
<canvas ref="canvasRef" class="avBars" style="width: 100%" />
@@ -85,4 +94,11 @@ onMounted(() => {
hsla(0, 0%, 100%, 0)
);
}
.point {
width: 30px;
height: 30px;
margin: 20px;
border-radius: 50%;
background-color: var(--main-color);
}
</style>