↩ revert: 回退部分修改
1
.gitattributes
vendored
@@ -1 +0,0 @@
|
||||
* text eol=lf
|
||||
23
.github/workflows/build.yml
vendored
@@ -15,12 +15,12 @@ jobs:
|
||||
steps:
|
||||
# 检出 Git 仓库
|
||||
- name: Check out git repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v4.1.1
|
||||
# 安装 Node.js
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v4.0.0
|
||||
with:
|
||||
node-version: "20.x"
|
||||
node-version: "18.x"
|
||||
# 复制环境变量文件
|
||||
- name: Copy .env.example
|
||||
run: |
|
||||
@@ -43,22 +43,7 @@ jobs:
|
||||
npx rimraf "dist/!(*.exe)"
|
||||
# 上传构建产物
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3.1.3
|
||||
with:
|
||||
name: SPlayer-dev
|
||||
path: dist
|
||||
# 自动生成标签
|
||||
- name: Autotag
|
||||
run: |
|
||||
$tag = "v$(date +'%Y%m%d%H%M%S')"
|
||||
git tag $tag
|
||||
git push origin $tag
|
||||
# 创建 GitHub Release
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
draft: false
|
||||
prerelease: true
|
||||
files: dist/*.exe
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
|
||||
|
||||
30
.github/workflows/release.yml
vendored
@@ -16,12 +16,12 @@ jobs:
|
||||
steps:
|
||||
# 检出 Git 仓库
|
||||
- name: Check out git repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v4.1.1
|
||||
# 安装 Node.js
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v4.0.0
|
||||
with:
|
||||
node-version: "20.x"
|
||||
node-version: "18.x"
|
||||
# 复制环境变量文件
|
||||
- name: Copy .env.example
|
||||
run: |
|
||||
@@ -41,14 +41,14 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
|
||||
# 上传构建产物
|
||||
- name: Upload Windows artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3.1.3
|
||||
with:
|
||||
name: SPlarer-Win
|
||||
if-no-files-found: ignore
|
||||
path: dist/*.*
|
||||
# 创建 GitHub Release
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
uses: softprops/action-gh-release@v0.1.15
|
||||
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
|
||||
uses: actions/checkout@v4.1.1
|
||||
# 安装 Node.js
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v4.0.0
|
||||
with:
|
||||
node-version: "20.x"
|
||||
node-version: "18.x"
|
||||
# 复制环境变量文件
|
||||
- name: Copy .env.example
|
||||
run: |
|
||||
@@ -88,14 +88,14 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
|
||||
# 上传构建产物
|
||||
- name: Upload macOS artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3.1.3
|
||||
with:
|
||||
name: SPlarer-Macos
|
||||
if-no-files-found: ignore
|
||||
path: dist/*.*
|
||||
# 创建 GitHub Release
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
uses: softprops/action-gh-release@v0.1.15
|
||||
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
|
||||
uses: actions/checkout@v4.1.1
|
||||
# 安装 Node.js
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v4.0.0
|
||||
with:
|
||||
node-version: "20.x"
|
||||
node-version: "18.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@v4
|
||||
uses: actions/upload-artifact@v3.1.3
|
||||
with:
|
||||
name: SPlarer-Linux
|
||||
if-no-files-found: ignore
|
||||
path: dist/*.*
|
||||
# 创建 GitHub Release
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
uses: softprops/action-gh-release@v0.1.15
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
with:
|
||||
draft: true
|
||||
|
||||
2
.gitignore
vendored
@@ -15,8 +15,6 @@ coverage
|
||||
*.local
|
||||
out
|
||||
.env
|
||||
components.d.ts
|
||||
auto-imports.d.ts
|
||||
|
||||
/cypress/videos/
|
||||
/cypress/screenshots/
|
||||
|
||||
70
auto-imports.d.ts
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
// @ts-nocheck
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
// Generated by unplugin-auto-import
|
||||
export {}
|
||||
declare global {
|
||||
const EffectScope: typeof import('vue')['EffectScope']
|
||||
const computed: typeof import('vue')['computed']
|
||||
const createApp: typeof import('vue')['createApp']
|
||||
const customRef: typeof import('vue')['customRef']
|
||||
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
|
||||
const defineComponent: typeof import('vue')['defineComponent']
|
||||
const effectScope: typeof import('vue')['effectScope']
|
||||
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
|
||||
const getCurrentScope: typeof import('vue')['getCurrentScope']
|
||||
const h: typeof import('vue')['h']
|
||||
const inject: typeof import('vue')['inject']
|
||||
const isProxy: typeof import('vue')['isProxy']
|
||||
const isReactive: typeof import('vue')['isReactive']
|
||||
const isReadonly: typeof import('vue')['isReadonly']
|
||||
const isRef: typeof import('vue')['isRef']
|
||||
const markRaw: typeof import('vue')['markRaw']
|
||||
const nextTick: typeof import('vue')['nextTick']
|
||||
const onActivated: typeof import('vue')['onActivated']
|
||||
const onBeforeMount: typeof import('vue')['onBeforeMount']
|
||||
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
|
||||
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
|
||||
const onDeactivated: typeof import('vue')['onDeactivated']
|
||||
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
|
||||
const onMounted: typeof import('vue')['onMounted']
|
||||
const onRenderTracked: typeof import('vue')['onRenderTracked']
|
||||
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
|
||||
const onScopeDispose: typeof import('vue')['onScopeDispose']
|
||||
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
|
||||
const onUnmounted: typeof import('vue')['onUnmounted']
|
||||
const onUpdated: typeof import('vue')['onUpdated']
|
||||
const provide: typeof import('vue')['provide']
|
||||
const reactive: typeof import('vue')['reactive']
|
||||
const readonly: typeof import('vue')['readonly']
|
||||
const ref: typeof import('vue')['ref']
|
||||
const resolveComponent: typeof import('vue')['resolveComponent']
|
||||
const shallowReactive: typeof import('vue')['shallowReactive']
|
||||
const shallowReadonly: typeof import('vue')['shallowReadonly']
|
||||
const shallowRef: typeof import('vue')['shallowRef']
|
||||
const toRaw: typeof import('vue')['toRaw']
|
||||
const toRef: typeof import('vue')['toRef']
|
||||
const toRefs: typeof import('vue')['toRefs']
|
||||
const toValue: typeof import('vue')['toValue']
|
||||
const triggerRef: typeof import('vue')['triggerRef']
|
||||
const unref: typeof import('vue')['unref']
|
||||
const useAttrs: typeof import('vue')['useAttrs']
|
||||
const useCssModule: typeof import('vue')['useCssModule']
|
||||
const useCssVars: typeof import('vue')['useCssVars']
|
||||
const useDialog: typeof import('naive-ui')['useDialog']
|
||||
const useLoadingBar: typeof import('naive-ui')['useLoadingBar']
|
||||
const useMessage: typeof import('naive-ui')['useMessage']
|
||||
const useNotification: typeof import('naive-ui')['useNotification']
|
||||
const useSlots: typeof import('vue')['useSlots']
|
||||
const watch: typeof import('vue')['watch']
|
||||
const watchEffect: typeof import('vue')['watchEffect']
|
||||
const watchPostEffect: typeof import('vue')['watchPostEffect']
|
||||
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
|
||||
}
|
||||
// for type re-export
|
||||
declare global {
|
||||
// @ts-ignore
|
||||
export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue'
|
||||
import('vue')
|
||||
}
|
||||
112
components.d.ts
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
// @ts-nocheck
|
||||
// Generated by unplugin-vue-components
|
||||
// Read more: https://github.com/vuejs/core/pull/3399
|
||||
export {}
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
AddPlaylist: typeof import('./src/components/Modal/AddPlaylist.vue')['default']
|
||||
CloudSongMatch: typeof import('./src/components/Modal/CloudSongMatch.vue')['default']
|
||||
CommentList: typeof import('./src/components/List/CommentList.vue')['default']
|
||||
CountDown: typeof import('./src/components/Player/CountDown.vue')['default']
|
||||
CoverDropdown: typeof import('./src/components/Cover/CoverDropdown.vue')['default']
|
||||
CoverPlayBtn: typeof import('./src/components/Cover/CoverPlayBtn.vue')['default']
|
||||
CreatePlaylist: typeof import('./src/components/Modal/CreatePlaylist.vue')['default']
|
||||
DownloadSong: typeof import('./src/components/Modal/DownloadSong.vue')['default']
|
||||
FullPlayer: typeof import('./src/components/Player/FullPlayer.vue')['default']
|
||||
Login: typeof import('./src/components/Modal/Login.vue')['default']
|
||||
LoginPhone: typeof import('./src/components/Modal/LoginPhone.vue')['default']
|
||||
LoginQRCode: typeof import('./src/components/Modal/LoginQRCode.vue')['default']
|
||||
Lyric: typeof import('./src/components/Player/Lyric.vue')['default']
|
||||
MainControl: typeof import('./src/components/Player/MainControl.vue')['default']
|
||||
MainCover: typeof import('./src/components/Cover/MainCover.vue')['default']
|
||||
MainLayout: typeof import('./src/components/Global/MainLayout.vue')['default']
|
||||
MainNav: typeof import('./src/components/Nav/MainNav.vue')['default']
|
||||
Menu: typeof import('./src/components/Global/Menu.vue')['default']
|
||||
NAlert: typeof import('naive-ui')['NAlert']
|
||||
NAvatar: typeof import('naive-ui')['NAvatar']
|
||||
NBackTop: typeof import('naive-ui')['NBackTop']
|
||||
NBadge: typeof import('naive-ui')['NBadge']
|
||||
NButton: typeof import('naive-ui')['NButton']
|
||||
NCard: typeof import('naive-ui')['NCard']
|
||||
NCheckbox: typeof import('naive-ui')['NCheckbox']
|
||||
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
|
||||
NDialogProvider: typeof import('naive-ui')['NDialogProvider']
|
||||
NDivider: typeof import('naive-ui')['NDivider']
|
||||
NDrawer: typeof import('naive-ui')['NDrawer']
|
||||
NDrawerContent: typeof import('naive-ui')['NDrawerContent']
|
||||
NDropdown: typeof import('naive-ui')['NDropdown']
|
||||
NEllipsis: typeof import('naive-ui')['NEllipsis']
|
||||
NEmpty: typeof import('naive-ui')['NEmpty']
|
||||
NFlex: typeof import('naive-ui')['NFlex']
|
||||
NForm: typeof import('naive-ui')['NForm']
|
||||
NFormItem: typeof import('naive-ui')['NFormItem']
|
||||
NGi: typeof import('naive-ui')['NGi']
|
||||
NGlobalStyle: typeof import('naive-ui')['NGlobalStyle']
|
||||
NGrid: typeof import('naive-ui')['NGrid']
|
||||
NH1: typeof import('naive-ui')['NH1']
|
||||
NH3: typeof import('naive-ui')['NH3']
|
||||
NH4: typeof import('naive-ui')['NH4']
|
||||
NH6: typeof import('naive-ui')['NH6']
|
||||
NIcon: typeof import('naive-ui')['NIcon']
|
||||
NImage: typeof import('naive-ui')['NImage']
|
||||
NInput: typeof import('naive-ui')['NInput']
|
||||
NInputNumber: typeof import('naive-ui')['NInputNumber']
|
||||
NLayout: typeof import('naive-ui')['NLayout']
|
||||
NLayoutContent: typeof import('naive-ui')['NLayoutContent']
|
||||
NLayoutHeader: typeof import('naive-ui')['NLayoutHeader']
|
||||
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
|
||||
NList: typeof import('naive-ui')['NList']
|
||||
NListItem: typeof import('naive-ui')['NListItem']
|
||||
NLoadingBarProvider: typeof import('naive-ui')['NLoadingBarProvider']
|
||||
NMenu: typeof import('naive-ui')['NMenu']
|
||||
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
|
||||
NModal: typeof import('naive-ui')['NModal']
|
||||
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
|
||||
NNumberAnimation: typeof import('naive-ui')['NNumberAnimation']
|
||||
NPagination: typeof import('naive-ui')['NPagination']
|
||||
NPopover: typeof import('naive-ui')['NPopover']
|
||||
NProgress: typeof import('naive-ui')['NProgress']
|
||||
NQrCode: typeof import('naive-ui')['NQrCode']
|
||||
NRadio: typeof import('naive-ui')['NRadio']
|
||||
NRadioGroup: typeof import('naive-ui')['NRadioGroup']
|
||||
NResult: typeof import('naive-ui')['NResult']
|
||||
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
||||
NSelect: typeof import('naive-ui')['NSelect']
|
||||
NSkeleton: typeof import('naive-ui')['NSkeleton']
|
||||
NSlider: typeof import('naive-ui')['NSlider']
|
||||
NSpin: typeof import('naive-ui')['NSpin']
|
||||
NSwitch: typeof import('naive-ui')['NSwitch']
|
||||
NTab: typeof import('naive-ui')['NTab']
|
||||
NTabPane: typeof import('naive-ui')['NTabPane']
|
||||
NTabs: typeof import('naive-ui')['NTabs']
|
||||
NTag: typeof import('naive-ui')['NTag']
|
||||
NText: typeof import('naive-ui')['NText']
|
||||
NThing: typeof import('naive-ui')['NThing']
|
||||
NVirtualList: typeof import('naive-ui')['NVirtualList']
|
||||
Pagination: typeof import('./src/components/Global/Pagination.vue')['default']
|
||||
PlayerControl: typeof import('./src/components/Player/PlayerControl.vue')['default']
|
||||
PlayerCover: typeof import('./src/components/Player/PlayerCover.vue')['default']
|
||||
Playlist: typeof import('./src/components/Global/Playlist.vue')['default']
|
||||
PlaylistUpdate: typeof import('./src/components/Modal/PlaylistUpdate.vue')['default']
|
||||
PrivateFm: typeof import('./src/components/Player/PrivateFm.vue')['default']
|
||||
Provider: typeof import('./src/components/Global/Provider.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
SearchHot: typeof import('./src/components/Search/SearchHot.vue')['default']
|
||||
SearchInp: typeof import('./src/components/Search/SearchInp.vue')['default']
|
||||
SearchSuggestions: typeof import('./src/components/Search/SearchSuggestions.vue')['default']
|
||||
SongList: typeof import('./src/components/List/SongList.vue')['default']
|
||||
SongListDrawer: typeof import('./src/components/List/SongListDrawer.vue')['default']
|
||||
SongListDropdown: typeof import('./src/components/List/SongListDropdown.vue')['default']
|
||||
SpecialCover: typeof import('./src/components/Cover/SpecialCover.vue')['default']
|
||||
SpecialCoverCard: typeof import('./src/components/Cover/SpecialCoverCard.vue')['default']
|
||||
Spectrum: typeof import('./src/components/Player/Spectrum.vue')['default']
|
||||
SvgIcon: typeof import('./src/components/Global/SvgIcon.vue')['default']
|
||||
TitleBar: typeof import('./src/components/WinDom/TitleBar.vue')['default']
|
||||
UpCloudSong: typeof import('./src/components/Modal/UpCloudSong.vue')['default']
|
||||
UserData: typeof import('./src/components/Nav/UserData.vue')['default']
|
||||
}
|
||||
}
|
||||
24
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "splayer",
|
||||
"version": "2.0.8",
|
||||
"version": "2.0.7",
|
||||
"description": "A minimalist music player",
|
||||
"main": "./out/main/index.js",
|
||||
"author": "imsyy",
|
||||
@@ -30,7 +30,7 @@
|
||||
"@electron-toolkit/preload": "^3.0.1",
|
||||
"@electron-toolkit/utils": "^3.0.0",
|
||||
"@material/material-color-utilities": "^0.2.7",
|
||||
"NeteaseCloudMusicApi": "^4.19.5",
|
||||
"NeteaseCloudMusicApi": "^4.15.8",
|
||||
"axios": "^1.6.8",
|
||||
"colorthief": "^2.4.0",
|
||||
"electron-dl": "^3.5.2",
|
||||
@@ -48,7 +48,7 @@
|
||||
"pinia-plugin-persistedstate": "^3.2.1",
|
||||
"plyr": "^3.7.8",
|
||||
"screenfull": "^6.0.2",
|
||||
"vue-router": "^4.3.2",
|
||||
"vue-router": "^4.3.0",
|
||||
"vue-slider-component": "4.1.0-beta.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -56,20 +56,20 @@
|
||||
"@rushstack/eslint-patch": "^1.10.2",
|
||||
"@vitejs/plugin-vue": "^5.0.4",
|
||||
"@vue/eslint-config-prettier": "^9.0.0",
|
||||
"ajv": "^8.13.0",
|
||||
"electron": "^28.3.1",
|
||||
"ajv": "^8.12.0",
|
||||
"electron": "^28.3.0",
|
||||
"electron-builder": "^24.13.3",
|
||||
"electron-log": "^5.1.4",
|
||||
"electron-vite": "^2.2.0",
|
||||
"electron-log": "^5.1.2",
|
||||
"electron-vite": "^2.1.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-vue": "^9.26.0",
|
||||
"naive-ui": "^2.38.2",
|
||||
"eslint-plugin-vue": "^9.25.0",
|
||||
"naive-ui": "^2.38.1",
|
||||
"prettier": "^3.2.5",
|
||||
"sass": "^1.77.0",
|
||||
"terser": "^5.31.0",
|
||||
"sass": "^1.75.0",
|
||||
"terser": "^5.30.3",
|
||||
"unplugin-auto-import": "^0.17.5",
|
||||
"unplugin-vue-components": "^0.26.0",
|
||||
"vite": "^5.2.11",
|
||||
"vite": "^5.2.9",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-pwa": "^0.17.5",
|
||||
"vue": "3.4.8"
|
||||
|
||||
1556
pnpm-lock.yaml
generated
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 17 KiB |
BIN
public/images/pic/album.png
Normal file
|
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 51 KiB |
BIN
public/images/pic/avatar.jpg
Normal file
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 158 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
BIN
public/images/pic/video.png
Normal file
|
Before Width: | Height: | Size: 164 KiB After Width: | Height: | Size: 243 KiB |
|
Before Width: | Height: | Size: 176 KiB After Width: | Height: | Size: 261 KiB |
|
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 241 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 126 KiB |
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 171 KiB |
|
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 208 KiB |
@@ -95,24 +95,3 @@ 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(),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -118,20 +118,6 @@ 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
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
class="loading-img"
|
||||
:src="
|
||||
type === 'mv'
|
||||
? '/images/pic/video.jpg?assest'
|
||||
? '/images/pic/video.png?assest'
|
||||
: type === 'artist'
|
||||
? '/images/pic/artist.jpg?assest'
|
||||
: '/images/pic/album.jpg?assest'
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
>
|
||||
<template #placeholder>
|
||||
<div class="cover-loading">
|
||||
<img class="loading-img" src="/images/pic/avatar.png?assest" alt="avatar" />
|
||||
<img class="loading-img" src="/images/pic/avatar.jpg?assest" alt="avatar" />
|
||||
</div>
|
||||
</template>
|
||||
</n-image>
|
||||
|
||||
@@ -77,11 +77,7 @@
|
||||
</n-text>
|
||||
<!-- 特权 -->
|
||||
<n-tag
|
||||
v-if="
|
||||
showPrivilege &&
|
||||
item.fee === 1 &&
|
||||
(userData.detail?.profile?.vipType !== 11 || !hiddenVipTags)
|
||||
"
|
||||
v-if="showPrivilege && item.fee === 1 && userData.detail?.profile?.vipType !== 11"
|
||||
:bordered="false"
|
||||
type="error"
|
||||
size="small"
|
||||
@@ -285,7 +281,7 @@ const dataStore = siteData();
|
||||
const status = siteStatus();
|
||||
const settings = siteSettings();
|
||||
const { userData } = storeToRefs(dataStore);
|
||||
const { loadSize, playSearch, useMusicCache, hiddenVipTags } = storeToRefs(settings);
|
||||
const { loadSize, playSearch, useMusicCache } = storeToRefs(settings);
|
||||
const { playList, playSongData, playSongSource } = storeToRefs(music);
|
||||
const { playIndex, playMode, playHeartbeatMode, playLoading } = storeToRefs(status);
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
<div class="left">
|
||||
<!-- 歌词模式 -->
|
||||
<n-icon
|
||||
v-if="isHasLrc && playMode !== 'dj'"
|
||||
v-if="isHasLrc"
|
||||
:class="['lrc-open', { open: pureLyricMode }]"
|
||||
size="28"
|
||||
@click="pureLyricMode = !pureLyricMode"
|
||||
@@ -78,17 +78,11 @@
|
||||
:key="`${pureLyricMode}-${playCoverType}-${isHasLrc}-${music.getPlaySongData?.id}`"
|
||||
class="main-player"
|
||||
>
|
||||
<div
|
||||
v-show="!(pureLyricMode && isHasLrc) || playMode === 'dj'"
|
||||
:class="['content', { 'no-lrc': !isHasLrc || playMode === 'dj' }]"
|
||||
>
|
||||
<div v-show="!(pureLyricMode && isHasLrc)" :class="['content', { 'no-lrc': !isHasLrc }]">
|
||||
<!-- 封面 -->
|
||||
<PlayerCover />
|
||||
<!-- 信息 -->
|
||||
<div
|
||||
v-show="playCoverType === 'cover' || !isHasLrc || playMode === 'dj'"
|
||||
:class="['data', playCoverType]"
|
||||
>
|
||||
<div v-show="playCoverType === 'cover' || !isHasLrc" :class="['data', playCoverType]">
|
||||
<div class="desc">
|
||||
<div class="title">
|
||||
<span class="name">{{ music.getPlaySongData.name || "未知曲目" }}</span>
|
||||
@@ -121,7 +115,7 @@
|
||||
<span v-if="music.getPlaySongData.alia" class="alia">
|
||||
{{ music.getPlaySongData.alia }}
|
||||
</span>
|
||||
<div v-if="playMode !== 'dj'" class="artist">
|
||||
<div class="artist">
|
||||
<n-icon depth="3" size="20">
|
||||
<SvgIcon icon="account-music" />
|
||||
</n-icon>
|
||||
@@ -145,7 +139,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="playMode !== 'dj'"
|
||||
class="album"
|
||||
@click.stop="
|
||||
() => {
|
||||
@@ -168,28 +161,10 @@
|
||||
</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 v-if="playMode !== 'dj'" :class="['right', { pure: pureLyricMode && isHasLrc }]">
|
||||
<div :class="['right', { pure: pureLyricMode && isHasLrc }]">
|
||||
<!-- 唱片模式下信息 -->
|
||||
<div
|
||||
v-show="(pureLyricMode && isHasLrc) || (playCoverType === 'record' && isHasLrc)"
|
||||
@@ -274,7 +249,7 @@ const router = useRouter();
|
||||
const music = musicData();
|
||||
const status = siteStatus();
|
||||
const settings = siteSettings();
|
||||
const { playList, playSongLyric, playSongSource } = storeToRefs(music);
|
||||
const { playList, playSongLyric } = storeToRefs(music);
|
||||
const { playerBackgroundType, showYrc, playCoverType, showSpectrums } = storeToRefs(settings);
|
||||
const {
|
||||
playerControlShow,
|
||||
@@ -284,7 +259,6 @@ const {
|
||||
coverTheme,
|
||||
coverBackground,
|
||||
pureLyricMode,
|
||||
playMode,
|
||||
} = storeToRefs(status);
|
||||
|
||||
// 是否有歌词
|
||||
@@ -414,11 +388,6 @@ onUnmounted(() => {
|
||||
&.gradient {
|
||||
background: var(--cover-bg);
|
||||
}
|
||||
&.none {
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 按钮
|
||||
.menu {
|
||||
@@ -578,25 +547,6 @@ 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%;
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
</n-icon>
|
||||
<!-- 更多操作 -->
|
||||
<n-dropdown
|
||||
v-if="!music.getPlaySongData?.path"
|
||||
v-if="playMode !== 'dj' && !music.getPlaySongData?.path"
|
||||
:options="songMoreOptions"
|
||||
:show-arrow="true"
|
||||
placement="top-start"
|
||||
@@ -415,7 +415,6 @@ const songMoreOptions = computed(() => [
|
||||
{
|
||||
key: "add-pl",
|
||||
label: "添加到歌单",
|
||||
show: playMode.value !== "dj",
|
||||
props: {
|
||||
onClick: () => {
|
||||
addPlaylistRef.value?.openAddToPlaylist(music.getPlaySongData?.id);
|
||||
@@ -432,7 +431,6 @@ const songMoreOptions = computed(() => [
|
||||
path: "/comment",
|
||||
query: {
|
||||
id: music.getPlaySongData?.id,
|
||||
type: playMode.value,
|
||||
},
|
||||
});
|
||||
},
|
||||
@@ -442,9 +440,7 @@ const songMoreOptions = computed(() => [
|
||||
{
|
||||
key: "mv",
|
||||
label: "观看 MV",
|
||||
show:
|
||||
playMode.value !== "dj" &&
|
||||
(music.getPlaySongData?.mv && music.getPlaySongData?.mv !== 0 ? true : false),
|
||||
show: music.getPlaySongData?.mv && music.getPlaySongData?.mv !== 0 ? true : false,
|
||||
props: {
|
||||
onClick: () => {
|
||||
router.push({
|
||||
@@ -460,7 +456,7 @@ const songMoreOptions = computed(() => [
|
||||
{
|
||||
key: "download",
|
||||
label: "下载歌曲",
|
||||
show: playMode.value !== "dj" && (music.getPlaySongData?.path ? false : true),
|
||||
show: music.getPlaySongData?.path ? false : true,
|
||||
props: {
|
||||
onClick: () => {
|
||||
downloadSongRef.value?.openDownloadModal(music.getPlaySongData);
|
||||
@@ -491,10 +487,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;
|
||||
};
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<div class="left">
|
||||
<!-- 喜欢歌曲 -->
|
||||
<n-icon
|
||||
v-if="!music.getPlaySongData.path && playMode !== 'dj'"
|
||||
v-if="!music.getPlaySongData.path"
|
||||
size="24"
|
||||
@click.stop="
|
||||
data.changeLikeList(
|
||||
@@ -30,7 +30,7 @@
|
||||
</n-icon>
|
||||
<!-- 添加到歌单 -->
|
||||
<n-icon
|
||||
v-if="!music.getPlaySongData.path && playMode !== 'dj'"
|
||||
v-if="!music.getPlaySongData.path"
|
||||
class="hidden"
|
||||
size="24"
|
||||
@click.stop="addPlaylistRef?.openAddToPlaylist(music.getPlaySongData?.id)"
|
||||
@@ -39,7 +39,7 @@
|
||||
</n-icon>
|
||||
<!-- 下载 -->
|
||||
<n-icon
|
||||
v-if="!music.getPlaySongData.path && playMode !== 'dj'"
|
||||
v-if="!music.getPlaySongData.path"
|
||||
class="hidden"
|
||||
size="24"
|
||||
@click.stop="downloadSongRef?.openDownloadModal(music.getPlaySongData)"
|
||||
@@ -125,7 +125,9 @@
|
||||
v-if="!music.getPlaySongData?.path"
|
||||
class="hidden"
|
||||
size="22"
|
||||
@click.stop="jumpToComment"
|
||||
@click.stop="
|
||||
(showFullPlayer = false), router.push(`/comment?id=${music.getPlaySongData?.id}`)
|
||||
"
|
||||
>
|
||||
<SvgIcon icon="comment-text" />
|
||||
</n-icon>
|
||||
@@ -185,7 +187,7 @@
|
||||
/>
|
||||
</n-icon>
|
||||
<!-- 播放列表 -->
|
||||
<n-icon v-if="playMode !== 'fm'" size="22" @click.stop="playListShow = !playListShow">
|
||||
<n-icon v-if="playMode === 'normal'" size="22" @click.stop="playListShow = !playListShow">
|
||||
<SvgIcon icon="queue-music-rounded" />
|
||||
</n-icon>
|
||||
</div>
|
||||
@@ -309,18 +311,6 @@ 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>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<!-- 播放器 - 专辑封面 -->
|
||||
<template>
|
||||
<div :class="['mian-cover', playCoverType, { playing: playState }]">
|
||||
<div :class="['cover', playCoverType]">
|
||||
<!-- 指针 -->
|
||||
<img
|
||||
v-if="playCoverType === 'record'"
|
||||
@@ -57,7 +57,7 @@ const { playState } = storeToRefs(status);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mian-cover {
|
||||
.cover {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -66,14 +66,13 @@ 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 20px 10px rgb(0 0 0 / 10%);
|
||||
box-shadow: 0 0 10px 6px #00000008;
|
||||
transition: opacity 0.1s ease-in-out;
|
||||
:deep(img) {
|
||||
width: 100%;
|
||||
@@ -207,13 +206,6 @@ const { playState } = storeToRefs(status);
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&.cover {
|
||||
transform: scale(0.9);
|
||||
&.playing {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
&.record {
|
||||
.pointer {
|
||||
|
||||
@@ -16,7 +16,6 @@ const useSiteSettingsStore = defineStore("siteSettings", {
|
||||
autoCheckUpdates: true, // 自动检查更新
|
||||
systemFonts: "HarmonyOS Sans", // 全局字体
|
||||
justLyricArea: false, // 仅在歌词区域生效
|
||||
hiddenVipTags: false, // 隐藏 VIP 标签
|
||||
// 主题部分
|
||||
themeType: "dark",
|
||||
themeAuto: false,
|
||||
|
||||
@@ -32,7 +32,6 @@ const useSiteStatusStore = defineStore("siteStatus", {
|
||||
pureLyricMode: false,
|
||||
// 音乐频谱数据
|
||||
spectrumsData: [],
|
||||
spectrumsScaleData: 1,
|
||||
// 当前歌曲歌词播放索引
|
||||
playSongLyricIndex: -1,
|
||||
// 播放时长数据
|
||||
|
||||
@@ -23,7 +23,6 @@ let spectrumsData = {
|
||||
audio: null,
|
||||
analyser: null,
|
||||
audioCtx: null,
|
||||
scale: 1,
|
||||
};
|
||||
// 默认标题
|
||||
let defaultTitle = document.title;
|
||||
@@ -57,15 +56,13 @@ export const initPlayer = async (playNow = false) => {
|
||||
if (playMode === "fm") music.playSongData = {};
|
||||
// 在线歌曲
|
||||
if (!isLocalSong) {
|
||||
// 获取歌曲 ID
|
||||
let songId = playSongData?.id;
|
||||
if (!songId) return false;
|
||||
// 若为电台模式
|
||||
if (playMode === "dj") songId = music.getPlaySongData?.djId;
|
||||
// 获取歌曲信息
|
||||
const { id } = playSongData;
|
||||
if (!id) return false;
|
||||
// 开启加载状态
|
||||
status.playLoading = true;
|
||||
// 获取播放地址
|
||||
const url = await getNormalSongUrl(songId, status, playNow);
|
||||
const url = await getNormalSongUrl(id, status, playNow);
|
||||
// 正常播放地址
|
||||
if (url) {
|
||||
status.playUseOtherSource = false;
|
||||
@@ -93,7 +90,7 @@ export const initPlayer = async (playNow = false) => {
|
||||
// 下一曲
|
||||
else {
|
||||
if (playIndex !== playList.length - 1) {
|
||||
// changePlayIndex();
|
||||
changePlayIndex();
|
||||
} else {
|
||||
status.playLoading = false;
|
||||
status.playState = false;
|
||||
@@ -238,7 +235,7 @@ export const createPlayer = async (src, autoPlay = true) => {
|
||||
const audioDom = player._sounds[0]._node;
|
||||
audioDom.crossOrigin = "anonymous";
|
||||
// 写入播放历史
|
||||
if (playMode !== "dj") music.setPlayHistory(playSongData);
|
||||
music.setPlayHistory(playSongData);
|
||||
// 生成音乐频谱
|
||||
// 由于浏览器安全策略,无法在此处启动
|
||||
if (showSpectrums && checkPlatform.electron()) processSpectrum(player);
|
||||
@@ -758,12 +755,8 @@ 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);
|
||||
|
||||
@@ -112,8 +112,7 @@ const formatData = (data, type = "playlist", noTracks = false) => {
|
||||
// dj
|
||||
case "dj":
|
||||
return {
|
||||
id: v.id || v.vid,
|
||||
djId: v.mainTrackId || v.id,
|
||||
id: v.mainTrackId || v.id || v.vid,
|
||||
name: v.name,
|
||||
creator: v.dj,
|
||||
count: v.programCount,
|
||||
|
||||
@@ -11,6 +11,7 @@ const globalEvents = (router) => {
|
||||
// 显示播放器
|
||||
electron.ipcRenderer.on("showPlayer", () => {
|
||||
const status = siteStatus();
|
||||
if (status.playMode === "dj") return false;
|
||||
status.showFullPlayer = true;
|
||||
});
|
||||
// 播放或暂停
|
||||
|
||||
@@ -9,9 +9,6 @@ import { siteStatus } from "@/stores";
|
||||
*/
|
||||
const globalShortcut = (e, router) => {
|
||||
if (!e) return false;
|
||||
|
||||
// 是否按下 Ctrl
|
||||
if (!e.ctrlKey) return false;
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
>
|
||||
<template #placeholder>
|
||||
<div class="cover-loading">
|
||||
<img class="loading-img" src="/images/pic/avatar.png?assest" alt="avatar" />
|
||||
<img class="loading-img" src="/images/pic/avatar.jpg?assest" alt="avatar" />
|
||||
</div>
|
||||
</template>
|
||||
</n-image>
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
</n-image>
|
||||
<div class="content">
|
||||
<div class="name">{{ songDetail?.name || "未知曲目" }}</div>
|
||||
<div v-if="commentType === 'normal'" class="artist">
|
||||
<div class="artist">
|
||||
<n-icon depth="3" size="20">
|
||||
<SvgIcon icon="account-music" />
|
||||
</n-icon>
|
||||
@@ -45,14 +45,6 @@
|
||||
<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>
|
||||
@@ -94,8 +86,7 @@
|
||||
<script setup>
|
||||
import { useRouter } from "vue-router";
|
||||
import { getSongDetail } from "@/api/song";
|
||||
import { getDjProgramDetail } from "@/api/dj";
|
||||
import { getComment, getHotComment, commentDj } from "@/api/comment";
|
||||
import { getComment, getHotComment } from "@/api/comment";
|
||||
import formatData from "@/utils/formatData";
|
||||
|
||||
const router = useRouter();
|
||||
@@ -103,9 +94,6 @@ 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);
|
||||
|
||||
@@ -117,15 +105,9 @@ const hotCommentData = ref(null);
|
||||
// 获取歌曲详情
|
||||
const getSongDetailData = async (id) => {
|
||||
try {
|
||||
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;
|
||||
}
|
||||
const detail = await getSongDetail(id);
|
||||
const data = formatData(detail?.songs?.[0], "song");
|
||||
songDetail.value = data?.[0] ?? null;
|
||||
} catch (error) {
|
||||
console.error("获取歌曲详情失败:", error);
|
||||
}
|
||||
@@ -138,24 +120,14 @@ const getCommentData = async (id, pageNo = 1, sortType = 3, pageSize = 20) => {
|
||||
const cursor =
|
||||
pageNo !== 1 && commentData.value?.cursor !== "0" ? commentData.value.cursor : null;
|
||||
// 获取热门评论和普通评论
|
||||
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);
|
||||
}
|
||||
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";
|
||||
} catch (error) {
|
||||
console.error("获取评论数据出错:", error);
|
||||
$message.error("获取评论数据出错");
|
||||
@@ -177,7 +149,7 @@ const scrollToComment = () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 检查是否具有 id
|
||||
// 检查是否具有视频 id
|
||||
const isHasCommentId = (id) => {
|
||||
if (!id) {
|
||||
$message.error("参数不完整");
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<div class="creator">
|
||||
<n-avatar
|
||||
:src="(djDetail.creator?.avatarUrl + '?param=300y$300').replace(/^http:/, 'https:')"
|
||||
fallback-src="/images/pic/avatar.png?assest"
|
||||
fallback-src="/images/pic/avatar.jpg?assest"
|
||||
round
|
||||
/>
|
||||
<n-text class="nickname">{{ djDetail.creator?.nickname || "未知创建者" }}</n-text>
|
||||
@@ -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" :sourceId="djId" type="dj" />
|
||||
<SongList :data="djData" type="dj" />
|
||||
</div>
|
||||
<SongList v-else-if="searchData?.length" :data="searchData" :sourceId="djId" type="dj" />
|
||||
<SongList v-else-if="searchData?.length" :data="searchData" type="dj" />
|
||||
<n-empty
|
||||
v-else
|
||||
:description="`搜不到关于 ${searchValue} 的任何节目`"
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
:src="
|
||||
(playListDetail.creator?.avatarUrl + '?param=300y$300').replace(/^http:/, 'https:')
|
||||
"
|
||||
fallback-src="/images/pic/avatar.png?assest"
|
||||
fallback-src="/images/pic/avatar.jpg?assest"
|
||||
round
|
||||
/>
|
||||
<n-text class="nickname">{{ playListDetail.creator?.nickname || "未知创建者" }}</n-text>
|
||||
|
||||
@@ -174,7 +174,7 @@
|
||||
>
|
||||
<template #placeholder>
|
||||
<div class="cover-loading">
|
||||
<img class="loading-img" src="/images/pic/avatar.png?assest" alt="song" />
|
||||
<img class="loading-img" src="/images/pic/avatar.jpg?assest" alt="song" />
|
||||
</div>
|
||||
</template>
|
||||
</n-image>
|
||||
|
||||
@@ -122,13 +122,6 @@
|
||||
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>
|
||||
|
||||
@@ -150,7 +143,6 @@ const {
|
||||
showSearchHistory,
|
||||
autoSignIn,
|
||||
siderShowCover,
|
||||
hiddenVipTags,
|
||||
} = storeToRefs(settings);
|
||||
|
||||
// 基础数据
|
||||
|
||||
@@ -103,10 +103,6 @@
|
||||
label: '主色渐变',
|
||||
value: 'gradient',
|
||||
},
|
||||
{
|
||||
label: '无背景',
|
||||
value: 'none',
|
||||
},
|
||||
]"
|
||||
class="set"
|
||||
/>
|
||||
|
||||
@@ -5,15 +5,6 @@
|
||||
<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%" />
|
||||
@@ -94,11 +85,4 @@ onMounted(() => {
|
||||
hsla(0, 0%, 100%, 0)
|
||||
);
|
||||
}
|
||||
.point {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin: 20px;
|
||||
border-radius: 50%;
|
||||
background-color: var(--main-color);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
{
|
||||
"cleanUrls": true,
|
||||
"rewrites": [{ "source": "/:path*", "destination": "/index.html" }]
|
||||
}
|
||||
|
||||