Compare commits

...

7 Commits

Author SHA1 Message Date
imsyy
d46c4c4285 🐞 fix: 修复标题栏异常消失 #142 2024-03-14 13:41:31 +08:00
imsyy
0b871175b2 🐞 fix: 修复标题栏异常消失 #142 2024-03-14 11:57:29 +08:00
imsyy
c34c4fd880 📃 docs: update Docs 2024-03-05 18:00:26 +08:00
imsyy
ff00f0c283 🐞 fix: 修复标题栏无法正常显示 #142 2024-02-22 15:18:26 +08:00
imsyy
847c2e5810 📃 docs: 更新说明 2024-01-25 09:22:11 +08:00
imsyy
e62c81bb33 🐞 fix: 修复电台未加载全部节目 2024-01-18 16:25:03 +08:00
imsyy
984fdb3459 📃 docs: 更新说明 2024-01-18 11:45:46 +08:00
13 changed files with 1426 additions and 1164 deletions

View File

@@ -31,4 +31,5 @@ body:
id: other
attributes:
label: "具体信息"
description: "有需要补充的信息吗?比如控制台的报错什么的( Ctrl + Shift + i 打开控制台 "
description: "请填写完整的复现步骤和遇到的问题,包括但不限于报错信息、控制台输出、网络请求等"
placeholder: "请填写具体的复现步骤和遇到的问题"

View File

@@ -1,10 +1,8 @@
<div align="center">
<img alt="logo" height="80" src="./public/images/icons/favicon.png" />
<h2>SPlayer</h2>
<p>一个简约的音乐播放器</p>
<img alt="main" src="./screenshots/main.png" />
</div>
<br />
# SPlayer
> 一个简约的音乐播放器
![main](/screenshots/SPlayer.jpg)
## 说明

View File

@@ -1,6 +1,6 @@
{
"name": "splayer",
"version": "2.0.2",
"version": "2.0.5",
"description": "A minimalist music player",
"main": "./out/main/index.js",
"author": "imsyy",
@@ -30,13 +30,13 @@
"@electron-toolkit/preload": "^3.0.0",
"@electron-toolkit/utils": "^3.0.0",
"@material/material-color-utilities": "^0.2.7",
"NeteaseCloudMusicApi": "^4.14.0",
"axios": "^1.6.5",
"NeteaseCloudMusicApi": "^4.15.6",
"axios": "^1.6.7",
"colorthief": "^2.4.0",
"electron-dl": "^3.5.1",
"electron-store": "^8.1.0",
"electron-updater": "^6.1.7",
"express": "^4.18.2",
"electron-dl": "^3.5.2",
"electron-store": "^8.2.0",
"electron-updater": "^6.1.8",
"express": "^4.18.3",
"express-http-proxy": "^2.0.0",
"howler": "^2.2.4",
"js-cookie": "^3.0.5",
@@ -47,30 +47,30 @@
"pinia-plugin-persistedstate": "^3.2.1",
"plyr": "^3.7.8",
"screenfull": "^6.0.2",
"vue-router": "^4.2.5",
"vue-router": "^4.3.0",
"vue-slider-component": "4.1.0-beta.7"
},
"devDependencies": {
"@electron-toolkit/eslint-config": "^1.0.2",
"@rushstack/eslint-patch": "^1.6.1",
"@vitejs/plugin-vue": "^5.0.2",
"@rushstack/eslint-patch": "^1.7.2",
"@vitejs/plugin-vue": "^5.0.4",
"@vue/eslint-config-prettier": "^9.0.0",
"ajv": "^8.12.0",
"electron": "^28.1.2",
"electron-builder": "^24.9.1",
"electron-log": "^5.0.3",
"electron-vite": "^2.0.0",
"eslint": "^8.56.0",
"eslint-plugin-vue": "^9.19.2",
"naive-ui": "^2.37.3",
"prettier": "^3.1.1",
"sass": "^1.69.7",
"terser": "^5.26.0",
"unplugin-auto-import": "^0.17.3",
"electron": "^28.2.7",
"electron-builder": "^24.13.3",
"electron-log": "^5.1.2",
"electron-vite": "^2.1.0",
"eslint": "^8.57.0",
"eslint-plugin-vue": "^9.23.0",
"naive-ui": "^2.38.1",
"prettier": "^3.2.5",
"sass": "^1.72.0",
"terser": "^5.29.1",
"unplugin-auto-import": "^0.17.5",
"unplugin-vue-components": "^0.26.0",
"vite": "^5.0.11",
"vite": "^5.1.6",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-pwa": "^0.17.4",
"vite-plugin-pwa": "^0.17.5",
"vue": "3.4.8"
}
}

2405
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

BIN
screenshots/SPlayer.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 524 KiB

View File

@@ -32,7 +32,7 @@
alignItems: 'center',
justifyContent: 'space-between',
}"
:class="music.getPlaySongData?.id === item?.id ? 'songs play' : 'songs'"
:class="Number(music.getPlaySongData?.id) === Number(item?.id) ? 'songs play' : 'songs'"
hoverable
@click="checkCanClick(data, item, songsIndex + index)"
@dblclick.stop="playSong(data, item, songsIndex + index)"
@@ -190,7 +190,7 @@
</div>
<!-- 更新日期 -->
<n-text v-if="type === 'dj' && item.updateTime" class="update hidden" depth="3">
{{ getTimestampTime(item.updateTime, false) }}
{{ djFormatDate(item.updateTime) }}
</n-text>
<!-- 播放量 -->
<n-text v-if="type === 'dj' && item.playCount" class="count hidden" depth="3">
@@ -273,7 +273,7 @@ import { setCloudDel } from "@/api/cloud";
import { addSongToPlayList } from "@/api/playlist";
import { siteData, siteSettings, musicData, siteStatus } from "@/stores";
import { initPlayer, fadePlayOrPause, addSongToNext } from "@/utils/Player";
import { getTimestampTime } from "@/utils/timeTools";
import { djFormatDate } from "@/utils/timeTools";
const router = useRouter();
const music = musicData();

View File

@@ -133,6 +133,8 @@ onBeforeUnmount(() => {
min-width: 180px;
height: 180px;
width: 180px;
min-height: 180px;
min-width: 180px;
box-sizing: border-box;
transition: opacity 0.3s;
&.hidden {

View File

@@ -93,7 +93,7 @@
<!-- 用户信息 -->
<userData />
<!-- TitleBar -->
<TitleBar v-if="checkPlatform.electron()" />
<TitleBar v-if="titleBarShow" />
</div>
</nav>
</template>
@@ -122,6 +122,9 @@ const openGithub = () => {
window.open(packageJson.github);
};
// TitleBar
const titleBarShow = ref(false);
// 主菜单渲染
const mainMenuShow = ref(false);
const mainMenuOptions = computed(() => [
@@ -138,6 +141,13 @@ const mainMenuOptions = computed(() => [
},
},
]);
onMounted(() => {
nextTick().then(() => {
// 是否显示 TitleBar
titleBarShow.value = checkPlatform.electron() || typeof electron !== "undefined";
});
});
</script>
<style lang="scss" scoped>

View File

@@ -42,8 +42,6 @@ export const initPlayer = async (playNow = false) => {
const { playList } = music;
// 当前播放歌曲数据
const playSongData = music.getPlaySongData;
// 若为电台则更改 id
playSongData.id = playMode === "dj" ? playSongData.mainTrackId : playSongData.id;
// 是否为本地歌曲
const isLocalSong = playSongData?.path ? true : false;
console.log("当前为本地歌曲");

View File

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

View File

@@ -106,3 +106,31 @@ export const getCommentTime = (t) => {
}${userDate.getDate()}${UH}:${Um}`;
}
};
/**
* 电台时间戳格式化
* @param {number} timestamp - 要格式化的时间戳(毫秒)
* @returns {string} - 格式化后的日期描述
*/
export const djFormatDate = (timestamp) => {
const now = new Date();
const targetDate = new Date(timestamp);
const timeDiff = now - targetDate;
const oneDay = 24 * 60 * 60 * 1000; // 一天的毫秒数
const daysDiff = Math.floor(timeDiff / oneDay);
// 数字补零
const formatNumber = (num) => {
return num < 10 ? `0${num}` : num;
};
if (daysDiff === 0) {
return "今日";
} else if (daysDiff === 1) {
return "昨日";
} else if (daysDiff <= 7) {
return `${daysDiff}天前`;
} else if (targetDate.getFullYear() === now.getFullYear() - 1) {
return `${targetDate.getFullYear()}-${formatNumber(targetDate.getMonth() + 1)}`;
} else {
return `${formatNumber(targetDate.getMonth() + 1)}-${formatNumber(targetDate.getDate())}`;
}
};

View File

@@ -171,13 +171,6 @@
<Transition name="fade" mode="out-in">
<div v-if="!searchValue" class="song-list">
<SongList :data="djData" type="dj" />
<!-- 分页 -->
<Pagination
v-if="djData?.length"
:totalCount="totalCount"
:pageNumber="pageNumber"
@pageNumberChange="pageNumberChange"
/>
</div>
<SongList v-else-if="searchData?.length" :data="searchData" type="dj" />
<n-empty
@@ -209,7 +202,7 @@
import { NIcon } from "naive-ui";
import { useRouter } from "vue-router";
import { storeToRefs } from "pinia";
import { siteData, siteSettings } from "@/stores";
import { siteData } from "@/stores";
import { getDjDetail, getDjProgram, likeDj } from "@/api/dj";
import { fuzzySearch } from "@/utils/helper";
import { isLogin } from "@/utils/auth";
@@ -221,20 +214,17 @@ import SvgIcon from "@/components/Global/SvgIcon";
const router = useRouter();
const data = siteData();
const settings = siteSettings();
const { userLikeData } = storeToRefs(data);
const { loadSize } = storeToRefs(settings);
// 电台数据
const djId = ref(router.currentRoute.value.query.id);
const pageNumber = ref(Number(router.currentRoute.value.query?.page) || 1);
const djDetail = ref(null);
const djData = ref(null);
// 模糊搜索数据
const loadingMsg = ref(null);
const searchValue = ref(null);
const searchData = ref([]);
const totalCount = ref(0);
// 图标渲染
const renderIcon = (icon) => {
@@ -267,6 +257,8 @@ const getDjDetailData = async (id) => {
const detail = await getDjDetail(id);
// 基础信息
djDetail.value = formatData(detail.data, "dj")[0];
// 获取节目
await getDjProgramData(djId.value, djDetail.value?.count);
} catch (error) {
console.error("获取电台信息出错:", error);
$message.error("获取电台信息出现错误");
@@ -274,16 +266,27 @@ const getDjDetailData = async (id) => {
};
// 获取电台全部节目
const getDjProgramData = async (id, limit = loadSize.value, offset = 0) => {
const getDjProgramData = async (id, count) => {
try {
if (count === 0) return (djData.value = "empty");
// 是否为超大歌单
if (count >= 500) {
loadingMsg.value = $message.loading("该电台节目数量过多,请稍等", {
duration: 0,
});
}
// 循环获取
let offset = 0;
djData.value = [];
const result = await getDjProgram(id, limit, offset);
console.log(result);
// 数据总数
totalCount.value = result.count;
if (totalCount.value === 0) return (djData.value = "empty");
// 处理数据
djData.value = formatData(result.programs, "dj");
while (count === null || offset < count) {
const result = await getDjProgram(id, 500, offset);
const djDetail = formatData(result.programs, "dj");
djData.value = djData.value.concat(djDetail);
offset += 500;
}
// 关闭加载提示
loadingMsg.value?.destroy();
loadingMsg.value = null;
} catch (error) {
console.error("获取电台节目错误:", error);
$message.error("获取电台节目出现错误");
@@ -330,36 +333,8 @@ const likeOrDislike = debounce(async (id) => {
}
}, 300);
// 页数变化
const pageNumberChange = (page) => {
router.push({
path: "/dj",
query: { id: djId.value, page },
});
};
// 监听路由变化
watch(
() => router.currentRoute.value,
async (val) => {
if (val.name === "dj") {
// 更改参数
pageNumber.value = Number(val.query?.page) || 1;
djId.value = val.query?.id;
// 调用接口
await getDjDetailData(djId.value);
await getDjProgramData(
djId.value,
loadSize.value,
(pageNumber.value - 1) * settings.loadSize,
);
}
},
);
onMounted(async () => {
await getDjDetailData(djId.value);
await getDjProgramData(djId.value, loadSize.value, (pageNumber.value - 1) * settings.loadSize);
});
</script>