@@ -95,6 +95,8 @@ const LinkCardImpl: FC<LinkCardProps> = (props) => {
95
95
[ LinkCardSource . GHPr ] : fetchGitHubPRData ,
96
96
[ LinkCardSource . Self ] : fetchMxSpaceData ,
97
97
[ LinkCardSource . LEETCODE ] : fetchLeetCodeQuestionData ,
98
+ [ LinkCardSource . QQMusicSong ] : fetchQQMusicSongData ,
99
+ [ LinkCardSource . NeteaseMusicSong ] : fetchNeteaseMusicSongData ,
98
100
} as Record < LinkCardSource , FetchObject >
99
101
if ( tmdbEnabled )
100
102
fetchDataFunctions [ LinkCardSource . TMDB ] = fetchTheMovieDBData
@@ -615,3 +617,114 @@ const fetchLeetCodeQuestionData: FetchObject = {
615
617
}
616
618
} ,
617
619
}
620
+
621
+ const fetchQQMusicSongData : FetchObject = {
622
+ isValid : ( id ) => {
623
+ return typeof id === 'string' && id . length > 0
624
+ } ,
625
+ fetch : async ( id , setCardInfo , _setFullUrl ) => {
626
+ try {
627
+ const songData = await fetch ( `/api/music/tencent` , {
628
+ method : 'POST' ,
629
+ headers : {
630
+ 'Content-Type' : 'application/json' ,
631
+ } ,
632
+ body : JSON . stringify ( { songId : id } ) ,
633
+ } ) . then ( async ( res ) => {
634
+ if ( ! res . ok ) {
635
+ throw new Error ( 'Failed to fetch QQMusic song title' )
636
+ }
637
+ return res . json ( )
638
+ } )
639
+ const songInfo = songData . data [ 0 ]
640
+ const albumId = songInfo . album . mid
641
+ setCardInfo ( {
642
+ title : (
643
+ < >
644
+ < span > { songInfo . title } </ span >
645
+ { songInfo . subtitle && (
646
+ < span className = "ml-2 text-sm text-gray-400" >
647
+ { songInfo . subtitle }
648
+ </ span >
649
+ ) }
650
+ </ >
651
+ ) ,
652
+ desc : (
653
+ < >
654
+ < span className = "block" >
655
+ < span className = "font-bold" > 歌手:</ span >
656
+ < span >
657
+ { songInfo . singer . map ( ( person : any ) => person . name ) . join ( ' / ' ) }
658
+ </ span >
659
+ </ span >
660
+ < span className = "block" >
661
+ < span className = "font-bold" > 专辑:</ span >
662
+ < span > { songInfo . album . name } </ span >
663
+ </ span >
664
+ </ >
665
+ ) ,
666
+ image : `https://y.gtimg.cn/music/photo_new/T002R300x300M000${ albumId } .jpg?max_age=2592000` ,
667
+ color : '#31c27c' ,
668
+ } )
669
+ } catch ( err ) {
670
+ console . error ( 'Error fetching QQMusic song data:' , err )
671
+ throw err
672
+ }
673
+ } ,
674
+ }
675
+
676
+ const fetchNeteaseMusicSongData : FetchObject = {
677
+ isValid : ( id ) => {
678
+ return id . length > 0
679
+ } ,
680
+ fetch : async ( id , setCardInfo , _setFullUrl ) => {
681
+ try {
682
+ const songData = await fetch ( `/api/music/netease` , {
683
+ method : 'POST' ,
684
+ headers : {
685
+ 'Content-Type' : 'application/json' ,
686
+ } ,
687
+ body : JSON . stringify ( { songId : id } ) ,
688
+ } ) . then ( async ( res ) => {
689
+ if ( ! res . ok ) {
690
+ throw new Error ( 'Failed to fetch NeteaseMusic song title' )
691
+ }
692
+ return res . json ( )
693
+ } )
694
+ const songInfo = songData . songs [ 0 ]
695
+ const albumInfo = songInfo . al
696
+ const singerInfo = songInfo . ar
697
+ setCardInfo ( {
698
+ title : (
699
+ < >
700
+ < span > { songInfo . name } </ span >
701
+ { songInfo . tns && (
702
+ < span className = "ml-2 text-sm text-gray-400" >
703
+ { songInfo . tns [ 0 ] }
704
+ </ span >
705
+ ) }
706
+ </ >
707
+ ) ,
708
+ desc : (
709
+ < >
710
+ < span className = "block" >
711
+ < span className = "font-bold" > 歌手:</ span >
712
+ < span >
713
+ { singerInfo . map ( ( person : any ) => person . name ) . join ( ' / ' ) }
714
+ </ span >
715
+ </ span >
716
+ < span className = "block" >
717
+ < span className = "font-bold" > 专辑:</ span >
718
+ < span > { albumInfo . name } </ span >
719
+ </ span >
720
+ </ >
721
+ ) ,
722
+ image : albumInfo . picUrl ,
723
+ color : '#e72d2c' ,
724
+ } )
725
+ } catch ( err ) {
726
+ console . error ( 'Error fetching NeteaseMusic song data:' , err )
727
+ throw err
728
+ }
729
+ } ,
730
+ }
0 commit comments