feat: 格式化代码

This commit is contained in:
alger
2025-09-14 00:19:41 +08:00
parent 74b9d73241
commit d8734f8302
39 changed files with 208 additions and 169 deletions

View File

@@ -45,7 +45,8 @@ export default {
phoneLoginFailed: 'Phone login failed, please check if phone number and password are correct',
autoGetCookieSuccess: 'Auto get Cookie successful',
autoGetCookieFailed: 'Auto get Cookie failed',
autoGetCookieTip: 'Will open NetEase Cloud Music login page, please complete login and close the window',
autoGetCookieTip:
'Will open NetEase Cloud Music login page, please complete login and close the window',
qrCheckFailed: 'Failed to check QR code status, please refresh and try again',
qrLoading: 'Loading QR code...',
qrExpired: 'QR code has expired, please click to refresh',
@@ -58,5 +59,6 @@ export default {
qrGenerating: 'Generating QR code...'
},
qrTitle: 'NetEase Cloud Music QR Code Login',
uidWarning: 'Note: UID login is only for viewing user public information and cannot access features that require login permissions.'
uidWarning:
'Note: UID login is only for viewing user public information and cannot access features that require login permissions.'
};

View File

@@ -82,7 +82,8 @@ export default {
showStatusBarContent:
'You can display the music control function in your mac status bar (effective after a restart)',
fallbackParser: 'Fallback Parser (GD Music)',
fallbackParserDesc: 'When "GD Music" is checked and regular sources fail, this service will be used.',
fallbackParserDesc:
'When "GD Music" is checked and regular sources fail, this service will be used.',
parserGD: 'GD Music (Built-in)',
parserCustom: 'Custom API',
@@ -103,8 +104,8 @@ export default {
notImported: 'No custom source imported yet.',
importSuccess: 'Successfully imported source: {name}',
importFailed: 'Import failed: {message}',
enableHint: 'Import a JSON config file to enable',
},
enableHint: 'Import a JSON config file to enable'
}
},
application: {
closeAction: 'Close Action',

View File

@@ -35,4 +35,4 @@
- すべての翻訳キーは中国語版と英語版に対応しています
- 新しい機能が追加された場合は、対応する日本語翻訳も追加する必要があります
- 文字化けを避けるため、ファイルはUTF-8エンコーディングで保存してください
- 文字化けを避けるため、ファイルはUTF-8エンコーディングで保存してください

View File

@@ -2,4 +2,4 @@ export default {
hotSongs: '人気楽曲',
albums: 'アルバム',
description: 'アーティスト紹介'
};
};

View File

@@ -53,4 +53,4 @@ export default {
play: '再生',
favorite: 'お気に入り'
}
};
};

View File

@@ -38,10 +38,12 @@ export default {
nowUpdate: '今すぐ更新',
downloadFailed: 'ダウンロードに失敗しました。再試行するか手動でダウンロードしてください',
startFailed: 'ダウンロードの開始に失敗しました。再試行するか手動でダウンロードしてください',
noDownloadUrl: '現在のシステムに適したインストールパッケージが見つかりません。手動でダウンロードしてください',
noDownloadUrl:
'現在のシステムに適したインストールパッケージが見つかりません。手動でダウンロードしてください',
installConfirmTitle: '更新をインストール',
installConfirmContent: 'アプリを閉じて更新をインストールしますか?',
manualInstallTip: 'アプリを閉じた後にインストーラーが正常に起動しない場合は、ダウンロードフォルダでファイルを見つけて手動で開いてください。',
manualInstallTip:
'アプリを閉じた後にインストーラーが正常に起動しない場合は、ダウンロードフォルダでファイルを見つけて手動で開いてください。',
yesInstall: '今すぐインストール',
noThanks: '後でインストール',
fileLocation: 'ファイルの場所',
@@ -172,7 +174,8 @@ export default {
noTasks: 'インポートタスクがありません',
clearTasks: 'タスクをクリア',
clearTasksConfirmTitle: 'クリア確認',
clearTasksConfirmContent: 'すべてのインポートタスク記録をクリアしますか?この操作は元に戻せません。',
clearTasksConfirmContent:
'すべてのインポートタスク記録をクリアしますか?この操作は元に戻せません。',
confirm: '確認',
cancel: 'キャンセル',
clearTasksSuccess: 'タスクリストをクリアしました',
@@ -187,4 +190,4 @@ export default {
mv: 'MV',
home: 'ホーム',
search: '検索'
};
};

View File

@@ -1,8 +1,9 @@
export default {
description: 'あなたの寄付は開発・保守作業をサポートするために使用され、サーバー保守、ドメイン更新などが含まれます。',
description:
'あなたの寄付は開発・保守作業をサポートするために使用され、サーバー保守、ドメイン更新などが含まれます。',
message: 'メッセージを残す際は、メールアドレスやGitHubユーザー名を記載してください。',
refresh: 'リストを更新',
toDonateList: 'コーヒーをおごる',
noMessage: 'メッセージがありません',
title: '寄付リスト'
};
};

View File

@@ -36,7 +36,8 @@ export default {
},
clear: {
title: 'ダウンロード記録をクリア',
message: 'すべてのダウンロード記録をクリアしますか?この操作はダウンロード済みの音楽ファイルを削除しませんが、すべての記録をクリアします。',
message:
'すべてのダウンロード記録をクリアしますか?この操作はダウンロード済みの音楽ファイルを削除しませんが、すべての記録をクリアします。',
confirm: 'クリア確認',
cancel: 'キャンセル',
success: 'ダウンロード記録をクリアしました'
@@ -84,4 +85,4 @@ export default {
albumName: 'アルバム名'
}
}
};
};

View File

@@ -10,4 +10,4 @@ export default {
selectSongsFirst: 'まずダウンロードする楽曲を選択してください',
descending: '降順',
ascending: '昇順'
};
};

View File

@@ -2,4 +2,4 @@ export default {
title: '再生履歴',
playCount: '{count}',
getHistoryFailed: '履歴の取得に失敗しました'
};
};

View File

@@ -41,8 +41,10 @@ export default {
uidLoginFailed: 'UIDログインに失敗しました。ユーザーIDが正しいか確認してください',
autoGetCookieSuccess: 'Cookie自動取得成功',
autoGetCookieFailed: 'Cookie自動取得失敗',
autoGetCookieTip: 'NetEase Cloud Musicのログインページを開きます。ログイン完了後、ウィンドウを閉じてください'
autoGetCookieTip:
'NetEase Cloud Musicのログインページを開きます。ログイン完了後、ウィンドウを閉じてください'
},
qrTitle: 'NetEase Cloud Music QRコードログイン',
uidWarning: '注意UIDログインはユーザーの公開情報を表示するためのみ使用でき、ログイン権限が必要な機能にはアクセスできません。'
};
uidWarning:
'注意UIDログインはユーザーの公開情報を表示するためのみ使用でき、ログイン権限が必要な機能にはアクセスできません。'
};

View File

@@ -120,6 +120,7 @@ export default {
cleared: 'プレイリストをクリアしました',
empty: 'プレイリストが空です',
clearConfirmTitle: 'プレイリストをクリア',
clearConfirmContent: 'これによりプレイリスト内のすべての楽曲がクリアされ、現在の再生が停止されます。続行しますか?'
clearConfirmContent:
'これによりプレイリスト内のすべての楽曲がクリアされ、現在の再生が停止されます。続行しますか?'
}
};
};

View File

@@ -24,4 +24,4 @@ export default {
mv: 'MV',
bilibili: 'Bilibili'
}
};
};

View File

@@ -78,9 +78,11 @@ export default {
autoPlay: '自動再生',
autoPlayDesc: 'アプリを再起動した際に自動的に再生を継続するかどうか',
showStatusBar: 'ステータスバーコントロール機能を表示するかどうか',
showStatusBarContent: 'Macのステータスバーに音楽コントロール機能を表示できます再起動後に有効',
showStatusBarContent:
'Macのステータスバーに音楽コントロール機能を表示できます再起動後に有効',
fallbackParser: '代替解析サービス (GD音楽台)',
fallbackParserDesc: '「GD音楽台」にチェックが入っていて、通常の音源で再生できない場合、このサービスが使用されます。',
fallbackParserDesc:
'「GD音楽台」にチェックが入っていて、通常の音源で再生できない場合、このサービスが使用されます。',
parserGD: 'GD 音楽台 (内蔵)',
parserCustom: 'カスタム API',
sourceLabels: {
@@ -93,13 +95,14 @@ export default {
},
customApi: {
sectionTitle: 'カスタム API 設定',
enableHint: 'カスタム API を有効にするには、まずカスタム API をインポートする必要があります。',
enableHint:
'カスタム API を有効にするには、まずカスタム API をインポートする必要があります。',
importConfig: 'JSON設定をインポート',
currentSource: '現在の音源',
notImported: 'カスタム音源はまだインポートされていません。',
importSuccess: '音源のインポートに成功しました: {name}',
importFailed: 'インポートに失敗しました: {message}',
},
importFailed: 'インポートに失敗しました: {message}'
}
},
application: {
closeAction: '閉じる動作',
@@ -114,7 +117,8 @@ export default {
download: 'ダウンロード管理',
downloadDesc: 'ダウンロードリストボタンを常に表示するかどうか',
unlimitedDownload: '無制限ダウンロード',
unlimitedDownloadDesc: '有効にすると音楽を無制限でダウンロードしますダウンロード失敗の可能性があります。デフォルトは300曲制限',
unlimitedDownloadDesc:
'有効にすると音楽を無制限でダウンロードしますダウンロード失敗の可能性があります。デフォルトは300曲制限',
downloadPath: 'ダウンロードディレクトリ',
downloadPathDesc: '音楽ファイルのダウンロード場所を選択',
remoteControl: 'リモートコントロール',
@@ -130,7 +134,8 @@ export default {
proxyPort: 'プロキシポート',
proxyPortPlaceholder: 'プロキシポートを入力してください',
realIP: 'realIP設定',
realIPDesc: '制限により、このプロジェクトは海外での使用が制限されます。realIPパラメータを使用して国内IPを渡すことで解決できます',
realIPDesc:
'制限により、このプロジェクトは海外での使用が制限されます。realIPパラメータを使用して国内IPを渡すことで解決できます',
messages: {
proxySuccess: 'プロキシ設定を保存しました。アプリ再起動後に有効になります',
proxyError: '入力が正しいかどうか確認してください',

View File

@@ -25,4 +25,4 @@ export default {
negativeText: 'キャンセル'
}
}
};
};

View File

@@ -45,4 +45,4 @@ export default {
deleteSuccess: '削除成功',
deleteFailed: '削除失敗'
}
};
};

View File

@@ -2,4 +2,4 @@ export default {
hotSongs: '인기 곡',
albums: '앨범',
description: '아티스트 소개'
};
};

View File

@@ -53,4 +53,4 @@ export default {
play: '재생',
favorite: '즐겨찾기'
}
};
};

View File

@@ -41,7 +41,8 @@ export default {
noDownloadUrl: '현재 시스템에 적합한 설치 패키지를 찾을 수 없습니다. 수동으로 다운로드해주세요',
installConfirmTitle: '업데이트 설치',
installConfirmContent: '앱을 닫고 업데이트를 설치하시겠습니까?',
manualInstallTip: '앱을 닫은 후 설치 프로그램이 정상적으로 나타나지 않으면 다운로드 폴더에서 파일을 찾아 수동으로 열어주세요.',
manualInstallTip:
'앱을 닫은 후 설치 프로그램이 정상적으로 나타나지 않으면 다운로드 폴더에서 파일을 찾아 수동으로 열어주세요.',
yesInstall: '지금 설치',
noThanks: '나중에 설치',
fileLocation: '파일 위치',
@@ -172,7 +173,8 @@ export default {
noTasks: '가져오기 작업이 없습니다',
clearTasks: '작업 지우기',
clearTasksConfirmTitle: '지우기 확인',
clearTasksConfirmContent: '모든 가져오기 작업 기록을 지우시겠습니까? 이 작업은 되돌릴 수 없습니다.',
clearTasksConfirmContent:
'모든 가져오기 작업 기록을 지우시겠습니까? 이 작업은 되돌릴 수 없습니다.',
confirm: '확인',
cancel: '취소',
clearTasksSuccess: '작업 목록이 지워졌습니다',
@@ -187,4 +189,4 @@ export default {
mv: 'MV',
home: '홈',
search: '검색'
};
};

View File

@@ -1,8 +1,9 @@
export default {
description: '귀하의 기부는 서버 유지보수, 도메인 갱신 등을 포함한 개발 및 유지보수 작업을 지원하는 데 사용됩니다.',
description:
'귀하의 기부는 서버 유지보수, 도메인 갱신 등을 포함한 개발 및 유지보수 작업을 지원하는 데 사용됩니다.',
message: '메시지를 남길 때 이메일이나 GitHub 이름을 남겨주세요.',
refresh: '목록 새로고침',
toDonateList: '커피 한 잔 사주세요',
noMessage: '메시지가 없습니다',
title: '기부 목록'
};
};

View File

@@ -36,7 +36,8 @@ export default {
},
clear: {
title: '다운로드 기록 지우기',
message: '모든 다운로드 기록을 지우시겠습니까? 이 작업은 다운로드된 음악 파일을 삭제하지 않지만 모든 기록을 지웁니다.',
message:
'모든 다운로드 기록을 지우시겠습니까? 이 작업은 다운로드된 음악 파일을 삭제하지 않지만 모든 기록을 지웁니다.',
confirm: '지우기 확인',
cancel: '취소',
success: '다운로드 기록이 지워졌습니다'
@@ -84,4 +85,4 @@ export default {
albumName: '앨범명'
}
}
};
};

View File

@@ -10,4 +10,4 @@ export default {
selectSongsFirst: '먼저 다운로드할 곡을 선택해주세요',
descending: '내림차순',
ascending: '오름차순'
};
};

View File

@@ -2,4 +2,4 @@ export default {
title: '재생 기록',
playCount: '{count}',
getHistoryFailed: '기록 가져오기 실패'
};
};

View File

@@ -41,8 +41,10 @@ export default {
uidLoginFailed: 'UID 로그인에 실패했습니다. 사용자 ID가 올바른지 확인하세요',
autoGetCookieSuccess: 'Cookie 자동 가져오기 성공',
autoGetCookieFailed: 'Cookie 자동 가져오기 실패',
autoGetCookieTip: '넷이즈 클라우드 뮤직 로그인 페이지를 열겠습니다. 로그인 완료 후 창을 닫아주세요'
autoGetCookieTip:
'넷이즈 클라우드 뮤직 로그인 페이지를 열겠습니다. 로그인 완료 후 창을 닫아주세요'
},
qrTitle: '넷이즈 클라우드 뮤직 QR코드 로그인',
uidWarning: '주의: UID 로그인은 사용자 공개 정보를 확인하는 데만 사용할 수 있으며, 로그인 권한이 필요한 기능에 액세스할 수 없습니다.'
};
uidWarning:
'주의: UID 로그인은 사용자 공개 정보를 확인하는 데만 사용할 수 있으며, 로그인 권한이 필요한 기능에 액세스할 수 없습니다.'
};

View File

@@ -121,4 +121,4 @@ export default {
clearConfirmTitle: '재생 목록 비우기',
clearConfirmContent: '재생 목록의 모든 곡을 삭제하고 현재 재생을 중지합니다. 계속하시겠습니까?'
}
};
};

View File

@@ -24,4 +24,4 @@ export default {
mv: 'MV',
bilibili: 'B站'
}
};
};

View File

@@ -80,7 +80,8 @@ export default {
showStatusBar: '상태바 제어 기능 표시 여부',
showStatusBarContent: 'Mac 상태바에 음악 제어 기능을 표시할 수 있습니다 (재시작 후 적용)',
fallbackParser: '대체 분석 서비스 (GD Music)',
fallbackParserDesc: '"GD Music"을 선택하고 일반 음원을 사용할 수 없을 때 이 서비스를 사용합니다.',
fallbackParserDesc:
'"GD Music"을 선택하고 일반 음원을 사용할 수 없을 때 이 서비스를 사용합니다.',
parserGD: 'GD Music (내장)',
parserCustom: '사용자 지정 API',
@@ -101,8 +102,8 @@ export default {
notImported: '아직 사용자 지정 음원을 가져오지 않았습니다.',
importSuccess: '음원 가져오기 성공: {name}',
importFailed: '가져오기 실패: {message}',
enableHint: '사용하려면 먼저 JSON 구성 파일을 가져오세요',
},
enableHint: '사용하려면 먼저 JSON 구성 파일을 가져오세요'
}
},
application: {
closeAction: '닫기 동작',
@@ -117,7 +118,8 @@ export default {
download: '다운로드 관리',
downloadDesc: '다운로드 목록 버튼을 항상 표시할지 여부',
unlimitedDownload: '무제한 다운로드',
unlimitedDownloadDesc: '활성화하면 음악을 무제한으로 다운로드합니다 (다운로드 실패가 발생할 수 있음), 기본 제한 300곡',
unlimitedDownloadDesc:
'활성화하면 음악을 무제한으로 다운로드합니다 (다운로드 실패가 발생할 수 있음), 기본 제한 300곡',
downloadPath: '다운로드 디렉토리',
downloadPathDesc: '음악 파일의 다운로드 위치 선택',
remoteControl: '원격 제어',
@@ -133,7 +135,8 @@ export default {
proxyPort: '프록시 포트',
proxyPortPlaceholder: '프록시 포트를 입력하세요',
realIP: 'realIP 설정',
realIPDesc: '제한으로 인해 이 프로젝트는 해외에서 사용할 때 제한을 받을 수 있으며, realIP 매개변수를 사용하여 국내 IP를 전달하여 해결할 수 있습니다',
realIPDesc:
'제한으로 인해 이 프로젝트는 해외에서 사용할 때 제한을 받을 수 있으며, realIP 매개변수를 사용하여 국내 IP를 전달하여 해결할 수 있습니다',
messages: {
proxySuccess: '프록시 설정이 저장되었습니다. 앱을 재시작한 후 적용됩니다',
proxyError: '입력이 올바른지 확인하세요',

View File

@@ -25,4 +25,4 @@ export default {
negativeText: '취소'
}
}
};
};

View File

@@ -45,4 +45,4 @@ export default {
deleteSuccess: '삭제 성공',
deleteFailed: '삭제 실패'
}
};
};

View File

@@ -81,7 +81,8 @@ export default {
showStatusBarContent: '可以在您的mac状态栏显示音乐控制功能(重启后生效)',
fallbackParser: 'GD音乐台(music.gdstudio.xyz)设置',
fallbackParserDesc: 'GD音乐台将自动尝试多个音乐平台进行解析无需额外配置。优先级高于其他解析方式但是请求可能较慢。感谢music.gdstudio.xyz\n',
fallbackParserDesc:
'GD音乐台将自动尝试多个音乐平台进行解析无需额外配置。优先级高于其他解析方式但是请求可能较慢。感谢music.gdstudio.xyz\n',
parserGD: 'GD 音乐台 (内置)',
parserCustom: '自定义 API',
@@ -103,8 +104,8 @@ export default {
notImported: '尚未导入自定义音源。',
importSuccess: '成功导入音源: {name}',
importFailed: '导入失败: {message}',
enableHint: '请先导入 JSON 配置文件才能启用',
},
enableHint: '请先导入 JSON 配置文件才能启用'
}
},
application: {
closeAction: '关闭行为',

View File

@@ -101,8 +101,8 @@ export default {
notImported: '尚未匯入自訂音源。',
importSuccess: '成功匯入音源:{name}',
importFailed: '匯入失敗:{message}',
enableHint: '請先匯入 JSON 設定檔才能啟用',
},
enableHint: '請先匯入 JSON 設定檔才能啟用'
}
},
application: {
closeAction: '關閉行為',

View File

@@ -2,6 +2,7 @@ import axios from 'axios';
import { app, dialog, ipcMain, Notification, protocol, shell } from 'electron';
import Store from 'electron-store';
import { fileTypeFromFile } from 'file-type';
import { FlacTagMap, writeFlacTags } from 'flac-tagger';
import * as fs from 'fs';
import * as http from 'http';
import * as https from 'https';
@@ -9,8 +10,8 @@ import * as mm from 'music-metadata';
import * as NodeID3 from 'node-id3';
import * as os from 'os';
import * as path from 'path';
import { FlacTagMap, writeFlacTags } from 'flac-tagger';
import sharp from 'sharp';
import { getStore } from './config';
const MAX_CONCURRENT_DOWNLOADS = 3;
@@ -619,21 +620,20 @@ async function downloadMusic(
try {
// 使用 sharp 进行压缩
coverImageBuffer = await sharp(originalCoverBuffer)
.resize({
width: 1600,
height: 1600,
fit: 'inside',
withoutEnlargement: true
})
.jpeg({
quality: 80,
mozjpeg: true
})
.toBuffer();
.resize({
width: 1600,
height: 1600,
fit: 'inside',
withoutEnlargement: true
})
.jpeg({
quality: 80,
mozjpeg: true
})
.toBuffer();
const compressedSizeMB = (coverImageBuffer.length / (1024 * 1024)).toFixed(2);
console.log(`封面图压缩完成,新大小: ${compressedSizeMB} MB`);
} catch (compressionError) {
console.error('封面图压缩失败,将使用原图:', compressionError);
coverImageBuffer = originalCoverBuffer; // 如果压缩失败,则回退使用原始图片
@@ -708,21 +708,21 @@ async function downloadMusic(
LYRICS: lyricsContent || '',
TRACKNUMBER: songInfo?.no ? String(songInfo.no) : undefined,
DATE: songInfo?.publishTime
? new Date(songInfo.publishTime).getFullYear().toString()
: undefined
? new Date(songInfo.publishTime).getFullYear().toString()
: undefined
};
await writeFlacTags(
{
tagMap,
picture: coverImageBuffer
? {
buffer: coverImageBuffer,
mime: 'image/jpeg'
}
: undefined
},
finalFilePath
{
tagMap,
picture: coverImageBuffer
? {
buffer: coverImageBuffer,
mime: 'image/jpeg'
}
: undefined
},
finalFilePath
);
console.log('FLAC tags written successfully');
} catch (err) {

View File

@@ -57,7 +57,7 @@ const api = {
return Promise.reject(new Error(`未授权的 IPC 通道: ${channel}`));
},
// 搜索建议
getSearchSuggestions: (keyword: string) => ipcRenderer.invoke('get-search-suggestions', keyword),
getSearchSuggestions: (keyword: string) => ipcRenderer.invoke('get-search-suggestions', keyword)
};
// 创建带类型的ipcRenderer对象暴露给渲染进程

View File

@@ -18,28 +18,28 @@ export function navigateToMusicList(
canRemove?: boolean;
}
) {
const musicStore = useMusicStore();
const { id, type, name, songList, listInfo, canRemove = false } = options;
const musicStore = useMusicStore();
const { id, type, name, songList, listInfo, canRemove = false } = options;
// 如果是每日推荐,不需要设置 musicStore直接从 recommendStore 获取
if (type !== 'dailyRecommend') {
musicStore.setCurrentMusicList(songList, name, listInfo, canRemove);
} else {
// 确保 musicStore 的数据被清空,避免显示旧的列表
musicStore.clearCurrentMusicList();
}
// 如果是每日推荐,不需要设置 musicStore直接从 recommendStore 获取
if (type !== 'dailyRecommend') {
musicStore.setCurrentMusicList(songList, name, listInfo, canRemove);
} else {
// 确保 musicStore 的数据被清空,避免显示旧的列表
musicStore.clearCurrentMusicList();
}
// 路由跳转
if (id) {
// 路由跳转
if (id) {
router.push({
name: 'musicList',
params: { id },
query: { type }
});
} else {
} else {
router.push({
name: 'musicList',
query: { type: 'dailyRecommend' }
});
}
}
}

View File

@@ -7,7 +7,7 @@ import type { SongResult } from '@/types/music';
import { getImgUrl } from '@/utils';
import { getImageBackground } from '@/utils/linearColor';
import { dislikeRecommendedSong } from "../api/music";
import { dislikeRecommendedSong } from '../api/music';
import { useArtist } from './useArtist';
import { useDownload } from './useDownload';
@@ -89,11 +89,11 @@ export function useSongItem(props: { item: SongResult; canRemove?: boolean }) {
// 判断当前歌曲是否为每日推荐歌曲
const isDailyRecommendSong = computed(() => {
return recommendStore.dailyRecommendSongs.some(song => song.id === props.item.id);
return recommendStore.dailyRecommendSongs.some((song) => song.id === props.item.id);
});
// 切换不喜欢状态
const toggleDislike = async (e: Event) => {
const toggleDislike = async (e: Event) => {
e && e.stopPropagation();
if (isDislike.value) {
@@ -102,17 +102,17 @@ export function useSongItem(props: { item: SongResult; canRemove?: boolean }) {
}
playerStore.addToDislikeList(props.item.id);
// 只有当前歌曲是每日推荐歌曲时才调用接口
if (!isDailyRecommendSong.value) {
return;
}
}
try {
console.log('发送不感兴趣请求歌曲ID:', props.item.id);
const numericId = typeof props.item.id === 'string' ? parseInt(props.item.id) : props.item.id;
const response = await dislikeRecommendedSong(numericId);
if (response.data.data) {
console.log(response)
console.log(response);
const newSongData = response.data.data;
const newSong: SongResult = {
...newSongData,
@@ -126,10 +126,10 @@ export function useSongItem(props: { item: SongResult; canRemove?: boolean }) {
id: newSongData.id,
name: newSongData.name,
artists: newSongData.ar || newSongData.artists,
album: newSongData.al || newSongData.album,
album: newSongData.al || newSongData.album
},
source: 'netease',
count: 0,
count: 0
};
recommendStore.replaceSongInDailyRecommend(props.item.id, newSong);
} else {

View File

@@ -37,19 +37,19 @@
<!-- 百度统计 -->
<script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?75a7ee3d3875dfdd2fe9d134883ddcbd";
var s = document.getElementsByTagName("script")[0];
(function () {
var hm = document.createElement('script');
hm.src = 'https://hm.baidu.com/hm.js?75a7ee3d3875dfdd2fe9d134883ddcbd';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?27b3850e627d266b20b38cce19af18f7";
var s = document.getElementsByTagName("script")[0];
(function () {
var hm = document.createElement('script');
hm.src = 'https://hm.baidu.com/hm.js?27b3850e627d266b20b38cce19af18f7';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(hm, s);
})();
</script>

View File

@@ -9,7 +9,11 @@
</div>
<div class="app-menu-list">
<div v-for="(item, index) in menus" :key="item.path" class="app-menu-item">
<n-tooltip :delay="200" :disabled="settingsStore.setData.isMenuExpanded || isMobile" placement="bottom">
<n-tooltip
:delay="200"
:disabled="settingsStore.setData.isMenuExpanded || isMobile"
placement="bottom"
>
<template #trigger>
<router-link class="app-menu-item-link" :to="item.path">
<i
@@ -39,8 +43,8 @@ import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import icon from '@/assets/icon.png';
import { isMobile } from '@/utils';
import { useSettingsStore } from '@/store';
import { isMobile } from '@/utils';
const props = defineProps({
size: {

View File

@@ -78,9 +78,9 @@ export const isBilibiliIdMatch = (id1: string | number, id2: string | number): b
// 提取公共函数获取B站视频URL
export const getSongUrl = async (
id: string | number,
songData: SongResult,
isDownloaded: boolean = false
id: string | number,
songData: SongResult,
isDownloaded: boolean = false
) => {
const numericId = typeof id === 'string' ? parseInt(id, 10) : id;
const settingsStore = useSettingsStore();
@@ -96,8 +96,8 @@ export const getSongUrl = async (
if (!songData.playMusicUrl && songData.bilibiliData.bvid && songData.bilibiliData.cid) {
try {
songData.playMusicUrl = await getBilibiliAudioUrl(
songData.bilibiliData.bvid,
songData.bilibiliData.cid
songData.bilibiliData.bvid,
songData.bilibiliData.cid
);
return songData.playMusicUrl;
} catch (error) {
@@ -108,7 +108,6 @@ export const getSongUrl = async (
return songData.playMusicUrl || '';
}
// ==================== 自定义API最优先 ====================
// 检查用户是否在全局设置中启用了 'custom' 音源
const globalSources = settingsStore.setData.enabledMusicSources || [];
@@ -128,14 +127,23 @@ export const getSongUrl = async (
}
// 如果全局或歌曲专属设置中启用了自定义API则最优先尝试
if ( (useCustomApiGlobally || useCustomApiForSong) && settingsStore.setData.customApiPlugin) {
if ((useCustomApiGlobally || useCustomApiForSong) && settingsStore.setData.customApiPlugin) {
console.log(`优先级 1: 尝试使用自定义API解析歌曲 ${id}...`);
try {
// 直接从 api 目录导入 parseFromCustomApi 函数
const { parseFromCustomApi } = await import('@/api/parseFromCustomApi');
const customResult = await parseFromCustomApi(numericId, cloneDeep(songData), settingsStore.setData.musicQuality || 'higher');
const customResult = await parseFromCustomApi(
numericId,
cloneDeep(songData),
settingsStore.setData.musicQuality || 'higher'
);
if (customResult && customResult.data && customResult.data.data && customResult.data.data.url) {
if (
customResult &&
customResult.data &&
customResult.data.data &&
customResult.data.data.url
) {
console.log('自定义API解析成功');
if (isDownloaded) return customResult.data.data as any;
return customResult.data.data.url;
@@ -190,7 +198,6 @@ export const getSongUrl = async (
const res = await getParsingMusicUrl(numericId, cloneDeep(songData));
if (isDownloaded) return res?.data?.data as any;
return res?.data?.data?.url || null;
} catch (error) {
console.error('官方API请求失败进入内置备用解析流程:', error);
const res = await getParsingMusicUrl(numericId, cloneDeep(songData));
@@ -465,19 +472,19 @@ export const usePlayerStore = defineStore('player', () => {
// 通用洗牌函数 - Fisher-Yates 算法
const performShuffle = (list: SongResult[], currentSong?: SongResult): SongResult[] => {
if (list.length <= 1) return [...list];
const result: SongResult[] = [];
const remainingSongs = [...list];
// 如果指定了当前歌曲,先把它放在第一位
if (currentSong && currentSong.id) {
const currentSongIndex = remainingSongs.findIndex(song => song.id === currentSong.id);
const currentSongIndex = remainingSongs.findIndex((song) => song.id === currentSong.id);
if (currentSongIndex !== -1) {
// 把当前歌曲放在第一位
result.push(remainingSongs.splice(currentSongIndex, 1)[0]);
}
}
// 对剩余歌曲进行洗牌
if (remainingSongs.length > 0) {
// Fisher-Yates 洗牌算法
@@ -485,27 +492,27 @@ export const usePlayerStore = defineStore('player', () => {
const j = Math.floor(Math.random() * (i + 1));
[remainingSongs[i], remainingSongs[j]] = [remainingSongs[j], remainingSongs[i]];
}
// 把洗牌后的歌曲添加到结果中
result.push(...remainingSongs);
}
return result;
};
// 应用随机播放到当前播放列表
const shufflePlayList = () => {
if (playList.value.length <= 1) return;
// 保存原始播放列表(如果还没保存)
if (originalPlayList.value.length === 0) {
originalPlayList.value = [...playList.value];
localStorage.setItem('originalPlayList', JSON.stringify(originalPlayList.value));
}
const currentSong = playList.value[playListIndex.value];
const shuffledList = performShuffle(playList.value, currentSong);
// 更新播放列表和索引
playList.value = shuffledList;
playListIndex.value = 0;
@@ -516,16 +523,16 @@ export const usePlayerStore = defineStore('player', () => {
// 恢复原始播放列表顺序
const restoreOriginalOrder = () => {
if (originalPlayList.value.length === 0) return;
const currentSong = playMusic.value;
const originalIndex = originalPlayList.value.findIndex(song => song.id === currentSong.id);
const originalIndex = originalPlayList.value.findIndex((song) => song.id === currentSong.id);
playList.value = [...originalPlayList.value];
playListIndex.value = Math.max(0, originalIndex);
localStorage.setItem('playList', JSON.stringify(playList.value));
localStorage.setItem('playListIndex', playListIndex.value.toString());
// 清空原始播放列表
originalPlayList.value = [];
localStorage.removeItem('originalPlayList');
@@ -534,10 +541,10 @@ export const usePlayerStore = defineStore('player', () => {
// 智能预加载下一首歌曲
const preloadNextSongs = (currentIndex: number) => {
if (playList.value.length <= 1) return;
// 计算下一首歌曲的索引
let nextIndex: number;
if (playMode.value === 0) {
// 顺序播放模式:下一首,如果是最后一首则不预加载
if (currentIndex >= playList.value.length - 1) {
@@ -548,18 +555,20 @@ export const usePlayerStore = defineStore('player', () => {
// 循环播放模式和随机播放模式:都是循环的
nextIndex = (currentIndex + 1) % playList.value.length;
}
// 预加载下一首和下下首
const endIndex = Math.min(nextIndex + 2, playList.value.length);
// 如果需要循环到开头,分两次预加载
if (nextIndex < playList.value.length) {
fetchSongs(playList.value, nextIndex, endIndex);
// 如果是循环模式且接近列表末尾,也预加载列表开头的歌曲
if ((playMode.value === 1 || playMode.value === 2) &&
nextIndex + 1 >= playList.value.length &&
playList.value.length > 2) {
if (
(playMode.value === 1 || playMode.value === 2) &&
nextIndex + 1 >= playList.value.length &&
playList.value.length > 2
) {
// 预加载列表开头的第一首
setTimeout(() => {
fetchSongs(playList.value, 0, 1);
@@ -877,42 +886,42 @@ export const usePlayerStore = defineStore('player', () => {
if (playMode.value === 2) {
// 随机模式:保存原始顺序并洗牌
console.log('随机模式下设置新播放列表,保存原始顺序并洗牌');
// 保存原始播放列表
originalPlayList.value = [...list];
localStorage.setItem('originalPlayList', JSON.stringify(originalPlayList.value));
// 洗牌新列表,优先保持当前歌曲在第一位
const currentSong = playMusic.value;
const shuffledList = performShuffle(list, currentSong);
// 计算新的播放索引
if (currentSong && currentSong.id) {
const currentSongIndex = shuffledList.findIndex(song => song.id === currentSong.id);
playListIndex.value = currentSongIndex !== -1 ? 0 : (keepIndex ? playListIndex.value : 0);
const currentSongIndex = shuffledList.findIndex((song) => song.id === currentSong.id);
playListIndex.value = currentSongIndex !== -1 ? 0 : keepIndex ? playListIndex.value : 0;
} else {
playListIndex.value = keepIndex ? playListIndex.value : 0;
}
playList.value = shuffledList;
} else {
// 顺序模式和循环模式:直接设置播放列表
console.log('顺序/循环模式下设置新播放列表');
// 清除原始播放列表状态(如果有的话)
if (originalPlayList.value.length > 0) {
originalPlayList.value = [];
localStorage.removeItem('originalPlayList');
}
// 计算播放索引
if (!keepIndex) {
playListIndex.value = list.findIndex((item) => item.id === playMusic.value.id);
}
playList.value = list;
}
// 保存到 localStorage
localStorage.setItem('playList', JSON.stringify(playList.value));
localStorage.setItem('playListIndex', playListIndex.value.toString());
@@ -935,7 +944,7 @@ export const usePlayerStore = defineStore('player', () => {
// 插入到当前播放歌曲的下一个位置
const insertIndex = playListIndex.value + 1;
list.splice(insertIndex, 0, song);
// 更新播放列表
setPlayList(list, true); // 保持当前索引不变
};
@@ -1131,13 +1140,13 @@ export const usePlayerStore = defineStore('player', () => {
// 保存当前索引,用于错误恢复
const currentIndex = playListIndex.value;
// 计算下一首歌曲的索引(所有播放模式都使用顺序播放,因为随机模式下列表已经是随机的)
const nowPlayListIndex = (playListIndex.value + 1) % playList.value.length;
// 获取下一首歌曲
const nextSong = { ...playList.value[nowPlayListIndex] };
// 更新当前播放索引
playListIndex.value = nowPlayListIndex;
@@ -1247,16 +1256,16 @@ export const usePlayerStore = defineStore('player', () => {
const newMode = (playMode.value + 1) % 3;
const wasRandom = playMode.value === 2;
const isRandom = newMode === 2;
playMode.value = newMode;
localStorage.setItem('playMode', JSON.stringify(playMode.value));
// 当切换到随机模式时,直接洗牌播放列表
if (isRandom && !wasRandom && playList.value.length > 0) {
shufflePlayList();
console.log('切换到随机模式,洗牌播放列表');
}
// 当从随机模式切换出去时,恢复原始顺序
if (!isRandom && wasRandom) {
restoreOriginalOrder();
@@ -1333,7 +1342,7 @@ export const usePlayerStore = defineStore('player', () => {
if (savedPlayList.length > 0) {
setPlayList(savedPlayList);
// 重启后恢复随机播放状态
if (playMode.value === 2) {
// 如果当前是随机模式但没有保存的原始播放列表,说明需要重新洗牌

View File

@@ -220,6 +220,6 @@ export const useSettingsStore = defineStore('settings', () => {
initializeSettings,
initializeTheme,
initializeSystemFonts,
setCustomApiPlugin,
setCustomApiPlugin
};
});