refactor: 更新 eslint 和 prettier 配置 格式化代码

This commit is contained in:
alger
2025-07-23 23:54:35 +08:00
parent d1f5c8af84
commit c08c2cbf19
134 changed files with 3887 additions and 3301 deletions
+31 -46
View File
@@ -4,31 +4,21 @@
<div class="description">
<p>{{ t('donation.description') }}</p>
<p>{{ t('donation.message') }}</p>
<n-button type="primary" @click="toDonateList">
<template #icon>
<i class="ri-cup-line"></i>
</template>
{{ t('donation.toDonateList') }}
</n-button>
<n-button type="primary" @click="toDonateList">
<template #icon>
<i class="ri-cup-line"></i>
</template>
{{ t('donation.toDonateList') }}
</n-button>
</div>
<div class="qrcode-grid">
<div class="qrcode-item">
<n-image
:src="alipay"
:alt="t('common.alipay')"
class="qrcode-image"
preview-disabled
/>
<n-image :src="alipay" :alt="t('common.alipay')" class="qrcode-image" preview-disabled />
<span class="qrcode-label">{{ t('common.alipay') }}</span>
</div>
<div class="qrcode-item">
<n-image
:src="wechat"
:alt="t('common.wechat')"
class="qrcode-image"
preview-disabled
/>
<n-image :src="wechat" :alt="t('common.wechat')" class="qrcode-image" preview-disabled />
<span class="qrcode-label">{{ t('common.wechat') }}</span>
</div>
</div>
@@ -43,7 +33,7 @@
{{ t('donation.refresh') }}
</n-button>
</div>
<div class="donation-grid" :class="{ 'grid-expanded': isExpanded }">
<div
v-for="donor in displayDonors"
@@ -53,12 +43,7 @@
>
<div class="card-content">
<div class="donor-avatar">
<n-avatar
:src="donor.avatar"
:fallback-src="defaultAvatar"
round
class="avatar-img"
/>
<n-avatar :src="donor.avatar" :fallback-src="defaultAvatar" round class="avatar-img" />
</div>
<div class="donor-info">
<div class="donor-meta">
@@ -68,7 +53,7 @@
<div class="donation-date">{{ donor.date }}</div>
</div>
</div>
<!-- 有留言的情况 -->
<n-popover
v-if="donor.message"
@@ -90,7 +75,7 @@
<i class="ri-double-quotes-r quote-icon"></i>
</div>
</n-popover>
<!-- 没有留言的情况显示占位符 -->
<div v-else class="donation-message-placeholder">
<i class="ri-emotion-line"></i>
@@ -175,7 +160,7 @@ const toDonateList = () => {
.header-container {
@apply flex justify-between items-center px-4 py-2;
.section-title {
@apply text-lg font-medium text-gray-700 dark:text-gray-200;
}
@@ -205,7 +190,7 @@ const toDonateList = () => {
@apply border border-gray-200 dark:border-gray-700/10;
@apply flex flex-col;
min-height: 100px;
.card-content {
@apply flex items-start gap-2 mb-2;
}
@@ -225,11 +210,11 @@ const toDonateList = () => {
.donor-meta {
@apply flex justify-between items-center mb-0.5;
.donor-name {
@apply text-sm font-medium truncate flex-1 mr-1;
}
.price-tag {
@apply text-xs text-gray-400/80 dark:text-gray-500/80 whitespace-nowrap;
}
@@ -245,19 +230,19 @@ const toDonateList = () => {
@apply bg-gray-100/10 dark:bg-dark-300 rounded;
@apply flex items-start;
@apply cursor-pointer transition-all duration-200;
.quote-icon {
@apply text-gray-300 dark:text-gray-600 flex-shrink-0 opacity-60;
&:first-child {
@apply mr-1 self-start;
}
&:last-child {
@apply ml-1 self-end;
}
}
.message-text {
@apply flex-1 line-clamp-2;
}
@@ -272,7 +257,7 @@ const toDonateList = () => {
@apply bg-gray-100/5 dark:bg-dark-300 rounded;
@apply flex items-center justify-center gap-1 italic;
@apply border border-transparent;
i {
@apply text-gray-300 dark:text-gray-600;
}
@@ -284,11 +269,11 @@ const toDonateList = () => {
.quote-icon {
@apply text-gray-400 dark:text-gray-500 flex-shrink-0;
&:first-child {
@apply mr-1.5 self-start;
}
&:last-child {
@apply ml-1.5 self-end;
}
@@ -305,30 +290,30 @@ const toDonateList = () => {
.qrcode-container {
@apply p-5 rounded-lg shadow-sm bg-light-100 dark:bg-gray-800/5 backdrop-blur-sm border border-gray-200 dark:border-gray-700/10;
.description {
@apply text-center text-sm text-gray-600 dark:text-gray-300 mb-4;
p {
@apply mb-2;
}
}
.qrcode-grid {
@apply flex justify-between items-center gap-4 flex-wrap;
.qrcode-item {
@apply flex flex-col items-center gap-2;
.qrcode-image {
@apply w-36 h-36 rounded-lg border border-gray-200 dark:border-gray-700/10 shadow-sm transition-transform duration-200 hover:scale-105;
}
.qrcode-label {
@apply text-sm text-gray-600 dark:text-gray-300;
}
}
.donate-button {
@apply flex flex-col items-center justify-center;
}
@@ -59,9 +59,9 @@ onMounted(() => {
// 监听下载完成
window.electron.ipcRenderer.on('music-download-complete', async (_, data) => {
if (data.success) {
downloadList.value = downloadList.value.filter(item => item.filename !== data.filename);
downloadList.value = downloadList.value.filter((item) => item.filename !== data.filename);
} else {
const existingItem = downloadList.value.find(item => item.filename === data.filename);
const existingItem = downloadList.value.find((item) => item.filename === data.filename);
if (existingItem) {
Object.assign(existingItem, {
status: 'error',
@@ -69,7 +69,7 @@ onMounted(() => {
progress: 0
});
setTimeout(() => {
downloadList.value = downloadList.value.filter(item => item.filename !== data.filename);
downloadList.value = downloadList.value.filter((item) => item.filename !== data.filename);
}, 3000);
}
}
@@ -1,4 +1,5 @@
import { Router } from 'vue-router';
import { useMusicStore } from '@/store/modules/music';
/**
@@ -35,4 +36,4 @@ export function navigateToMusicList(
name: 'musicList'
});
}
}
}
+9 -18
View File
@@ -31,13 +31,14 @@
</template>
<script setup lang="ts">
import { useRouter } from 'vue-router';
import { getAlbum, getListDetail } from '@/api/list';
import MvPlayer from '@/components/MvPlayer.vue';
import { useMusicStore } from '@/store/modules/music';
import { usePlayerStore } from '@/store/modules/player';
import { IMvItem } from '@/type/mv';
import { getImgUrl } from '@/utils';
import { useRouter } from 'vue-router';
import { useMusicStore } from '@/store/modules/music';
const props = withDefaults(
defineProps<{
@@ -88,15 +89,10 @@ const handleClick = async () => {
},
description: res.data.album.description
};
// 保存数据到store
musicStore.setCurrentMusicList(
songList.value,
props.item.name,
listInfo.value,
false
);
musicStore.setCurrentMusicList(songList.value, props.item.name, listInfo.value, false);
// 使用路由跳转
router.push({
name: 'musicList',
@@ -107,15 +103,10 @@ const handleClick = async () => {
const res = await getListDetail(props.item.id);
songList.value = res.data.playlist.tracks;
listInfo.value = res.data.playlist;
// 保存数据到store
musicStore.setCurrentMusicList(
songList.value,
props.item.name,
listInfo.value,
false
);
musicStore.setCurrentMusicList(songList.value, props.item.name, listInfo.value, false);
// 使用路由跳转
router.push({
name: 'musicList',
+5 -4
View File
@@ -1,5 +1,5 @@
<template>
<component
<component
:is="renderComponent"
:item="item"
:favorite="favorite"
@@ -16,12 +16,13 @@
<script lang="ts" setup>
import { computed } from 'vue';
import type { SongResult } from '@/type/music';
import StandardSongItem from './songItemCom/StandardSongItem.vue';
import MiniSongItem from './songItemCom/MiniSongItem.vue';
import ListSongItem from './songItemCom/ListSongItem.vue';
import CompactSongItem from './songItemCom/CompactSongItem.vue';
import ListSongItem from './songItemCom/ListSongItem.vue';
import MiniSongItem from './songItemCom/MiniSongItem.vue';
import StandardSongItem from './songItemCom/StandardSongItem.vue';
const props = withDefaults(
defineProps<{
@@ -421,7 +421,7 @@ const handleUpdate = async () => {
}
</style>
<style lang="scss">
<style lang="scss" scoped>
/* 对话框内容样式 */
.update-dialog-content {
display: flex;
@@ -11,7 +11,7 @@
<slot name="image"></slot>
<slot name="content"></slot>
<slot name="operating"></slot>
<song-item-dropdown
v-if="isElectron"
:item="item"
@@ -33,10 +33,11 @@
</template>
<script lang="ts" setup>
import SongItemDropdown from './SongItemDropdown.vue';
import { useSongItem } from '@/hooks/useSongItem';
import { isElectron } from '@/utils';
import type { SongResult } from '@/type/music';
import { isElectron } from '@/utils';
import SongItemDropdown from './SongItemDropdown.vue';
const props = defineProps<{
item: SongResult;
@@ -115,4 +116,4 @@ defineExpose({
.text-ellipsis {
width: 100%;
}
</style>
</style>
@@ -14,7 +14,11 @@
>
<!-- 索引插槽 -->
<template #index>
<div v-if="index !== undefined" class="song-item-index" :class="{ 'text-green-500': isPlaying }">
<div
v-if="index !== undefined"
class="song-item-index"
:class="{ 'text-green-500': isPlaying }"
>
{{ index + 1 }}
</div>
</template>
@@ -25,13 +29,17 @@
<n-checkbox :checked="selected" />
</div>
</template>
<!-- 内容插槽 -->
<template #content>
<div class="song-item-content-compact">
<div class="song-item-content-compact-wrapper">
<div class="song-item-content-compact-title w-60 flex-shrink-0">
<n-ellipsis class="text-ellipsis" line-clamp="1" :class="{ 'text-green-500': isPlaying }">
<n-ellipsis
class="text-ellipsis"
line-clamp="1"
:class="{ 'text-green-500': isPlaying }"
>
{{ item.name }}
</n-ellipsis>
</div>
@@ -56,11 +64,15 @@
</div>
</div>
</template>
<!-- 操作插槽 -->
<template #operating>
<div class="song-item-operating-compact">
<div v-if="favorite" class="song-item-operating-like" :class="{ 'opacity-0': !isHovering && !isFavorite }">
<div
v-if="favorite"
class="song-item-operating-like"
:class="{ 'opacity-0': !isHovering && !isFavorite }"
>
<i
class="iconfont icon-likefill"
:class="{ 'like-active': isFavorite }"
@@ -69,13 +81,21 @@
</div>
<div
class="song-item-operating-play animate__animated"
:class="{ 'bg-green-600': isPlaying, 'animate__flipInY': playLoading, 'opacity-0': !isHovering && !isPlaying }"
:class="{
'bg-green-600': isPlaying,
animate__flipInY: playLoading,
'opacity-0': !isHovering && !isPlaying
}"
@click="onPlayMusic"
>
<i v-if="isPlaying && play" class="iconfont icon-stop"></i>
<i v-else class="iconfont icon-playfill"></i>
</div>
<div class="song-item-operating-menu" @click.stop="onMenuClick" :class="{ 'opacity-0': !isHovering && !isPlaying }">
<div
class="song-item-operating-menu"
@click.stop="onMenuClick"
:class="{ 'opacity-0': !isHovering && !isPlaying }"
>
<i class="iconfont ri-more-fill"></i>
</div>
</div>
@@ -86,10 +106,12 @@
<script lang="ts" setup>
import { NCheckbox, NEllipsis } from 'naive-ui';
import { computed, ref } from 'vue';
import { usePlayerStore } from '@/store';
import BaseSongItem from './BaseSongItem.vue';
import type { SongResult } from '@/type/music';
import BaseSongItem from './BaseSongItem.vue';
const playerStore = usePlayerStore();
const props = withDefaults(
@@ -249,4 +271,4 @@ const formatDuration = (ms: number): string => {
:deep(.text-ellipsis) {
width: 100%;
}
</style>
</style>
@@ -18,7 +18,7 @@
<n-checkbox :checked="selected" />
</div>
</template>
<!-- 图片插槽 -->
<template #image>
<n-image
@@ -32,12 +32,16 @@
@load="onImageLoad"
/>
</template>
<!-- 内容插槽 -->
<template #content>
<div class="song-item-content">
<div class="song-item-content-wrapper">
<n-ellipsis class="song-item-content-title text-ellipsis" line-clamp="1" :class="{ 'text-green-500': isPlaying }">
<n-ellipsis
class="song-item-content-title text-ellipsis"
line-clamp="1"
:class="{ 'text-green-500': isPlaying }"
>
{{ item.name }}
</n-ellipsis>
<div class="song-item-content-divider">-</div>
@@ -54,7 +58,7 @@
</div>
</div>
</template>
<!-- 操作插槽 -->
<template #operating>
<div class="song-item-operating song-item-operating-list">
@@ -67,7 +71,7 @@
</div>
<div
class="song-item-operating-play bg-gray-300 dark:bg-gray-800 animate__animated"
:class="{ 'bg-green-600': isPlaying, 'animate__flipInY': playLoading }"
:class="{ 'bg-green-600': isPlaying, animate__flipInY: playLoading }"
@click="onPlayMusic"
>
<i v-if="isPlaying && play" class="iconfont icon-stop"></i>
@@ -81,11 +85,13 @@
<script lang="ts" setup>
import { NCheckbox, NEllipsis, NImage } from 'naive-ui';
import { computed, ref } from 'vue';
import { usePlayerStore } from '@/store';
import BaseSongItem from './BaseSongItem.vue';
import type { SongResult } from '@/type/music';
import { getImgUrl } from '@/utils';
import BaseSongItem from './BaseSongItem.vue';
const playerStore = usePlayerStore();
const props = withDefaults(
@@ -187,4 +193,4 @@ const onPlayMusic = () => {
}
}
}
</style>
</style>
@@ -18,7 +18,7 @@
<n-checkbox :checked="selected" />
</div>
</template>
<!-- 图片插槽 -->
<template #image>
<n-image
@@ -32,7 +32,7 @@
@load="onImageLoad"
/>
</template>
<!-- 内容插槽 -->
<template #content>
<div class="song-item-content">
@@ -55,7 +55,7 @@
</div>
</div>
</template>
<!-- 操作插槽 -->
<template #operating>
<div class="song-item-operating">
@@ -68,7 +68,7 @@
</div>
<div
class="song-item-operating-play bg-gray-300 dark:bg-gray-800 animate__animated"
:class="{ 'bg-green-600': isPlaying, 'animate__flipInY': playLoading }"
:class="{ 'bg-green-600': isPlaying, animate__flipInY: playLoading }"
@click="onPlayMusic"
>
<i v-if="isPlaying && play" class="iconfont icon-stop"></i>
@@ -82,11 +82,13 @@
<script lang="ts" setup>
import { NCheckbox, NEllipsis, NImage } from 'naive-ui';
import { computed, ref } from 'vue';
import { usePlayerStore } from '@/store';
import BaseSongItem from './BaseSongItem.vue';
import type { SongResult } from '@/type/music';
import { getImgUrl } from '@/utils';
import BaseSongItem from './BaseSongItem.vue';
const playerStore = usePlayerStore();
const props = withDefaults(
@@ -169,11 +171,11 @@ const onPlayMusic = () => {
&-like {
@apply mr-1 ml-1 cursor-pointer;
.icon-likefill {
@apply text-base transition text-gray-500 dark:text-gray-400 hover:text-red-500;
}
.like-active {
@apply text-red-500 dark:text-red-500;
}
@@ -190,4 +192,4 @@ const onPlayMusic = () => {
}
}
}
</style>
</style>
@@ -15,7 +15,7 @@
<script lang="ts" setup>
import type { MenuOption } from 'naive-ui';
import { NEllipsis, NImage, NDropdown } from 'naive-ui';
import { NDropdown, NEllipsis, NImage } from 'naive-ui';
import { computed, h, inject } from 'vue';
import { useI18n } from 'vue-i18n';
@@ -35,12 +35,12 @@ const props = defineProps<{
}>();
const emits = defineEmits([
'update:show',
'select',
'play',
'play-next',
'download',
'add-to-playlist',
'update:show',
'select',
'play',
'play-next',
'download',
'add-to-playlist',
'toggle-favorite',
'toggle-dislike',
'remove'
@@ -104,7 +104,9 @@ const renderSongPreview = () => {
},
{
default: () => {
const artistNames = (props.item.ar || props.item.song?.artists)?.map((a) => a.name).join(' / ');
const artistNames = (props.item.ar || props.item.song?.artists)
?.map((a) => a.name)
.join(' / ');
return artistNames || '未知艺术家';
}
}
@@ -164,8 +166,11 @@ const dropdownOptions = computed<MenuOption[]>(() => {
{
label: props.isDislike ? t('songItem.menu.undislike') : t('songItem.menu.dislike'),
key: 'dislike',
icon: () => h('i', { class: `iconfont ${props.isDislike ? 'ri-dislike-fill text-green-500': 'ri-dislike-line'}` })
},
icon: () =>
h('i', {
class: `iconfont ${props.isDislike ? 'ri-dislike-fill text-green-500' : 'ri-dislike-line'}`
})
}
];
if (props.canRemove) {
@@ -188,7 +193,7 @@ const dropdownOptions = computed<MenuOption[]>(() => {
// 处理选择
const handleSelect = (key: string | number) => {
emits('update:show', false);
switch (key) {
case 'download':
emits('download');
@@ -249,4 +254,4 @@ const handleSelect = (key: string | number) => {
:deep(.n-dropdown-option-body--render) {
@apply p-0;
}
</style>
</style>
@@ -18,7 +18,7 @@
<n-checkbox :checked="selected" />
</div>
</template>
<!-- 图片插槽 -->
<template #image>
<n-image
@@ -32,12 +32,17 @@
@load="onImageLoad"
/>
</template>
<!-- 内容插槽 -->
<template #content>
<div class="song-item-content">
<div class="song-item-content-title">
<n-ellipsis class="text-ellipsis" line-clamp="1" :class="{ 'text-green-500': isPlaying }">{{ item.name }}</n-ellipsis>
<n-ellipsis
class="text-ellipsis"
line-clamp="1"
:class="{ 'text-green-500': isPlaying }"
>{{ item.name }}</n-ellipsis
>
</div>
<div class="song-item-content-name">
<n-ellipsis class="text-ellipsis" line-clamp="1">
@@ -53,7 +58,7 @@
</div>
</div>
</template>
<!-- 操作插槽 -->
<template #operating>
<div class="song-item-operating">
@@ -74,7 +79,7 @@
</n-tooltip>
<div
class="song-item-operating-play bg-gray-300 dark:bg-gray-800 animate__animated"
:class="{ 'bg-green-600': isPlaying, 'animate__flipInY': playLoading }"
:class="{ 'bg-green-600': isPlaying, animate__flipInY: playLoading }"
@click="onPlayMusic"
>
<i v-if="isPlaying && play" class="iconfont icon-stop"></i>
@@ -91,10 +96,11 @@ import { computed, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { usePlayerStore } from '@/store';
import BaseSongItem from './BaseSongItem.vue';
import type { SongResult } from '@/type/music';
import { getImgUrl } from '@/utils';
import BaseSongItem from './BaseSongItem.vue';
const { t } = useI18n();
const playerStore = usePlayerStore();
@@ -185,7 +191,7 @@ const onPlayNext = () => {
&-next {
@apply mr-2 cursor-pointer transition-all;
.iconfont {
@apply text-xl transition text-gray-500 dark:text-gray-400 hover:text-green-500;
}
@@ -210,4 +216,4 @@ const onPlayNext = () => {
@apply mr-3 cursor-pointer;
}
}
</style>
</style>