@sansenjian/qq-music-api 2.1.1 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/.babelrc +4 -0
  2. package/.eslintrc.json +20 -19
  3. package/AGENTS.md +153 -0
  4. package/README.md +162 -136
  5. package/{app.js → app.ts} +24 -31
  6. package/config/user-info.ts +71 -0
  7. package/index.ts +1 -0
  8. package/{jest.config.js → jest.config.ts} +19 -7
  9. package/middlewares/koa-cors.ts +81 -0
  10. package/module/apis/UCommon/UCommon.ts +13 -0
  11. package/module/apis/album/getAlbumInfo.ts +22 -0
  12. package/module/apis/comments/getComments.ts +23 -0
  13. package/module/apis/digitalAlbum/getDigitalAlbumLists.ts +23 -0
  14. package/module/apis/downloadQQMusic.ts +51 -0
  15. package/module/apis/music/getLyric.ts +34 -0
  16. package/module/apis/mv/getMvByTag.ts +24 -0
  17. package/module/apis/radio/getRadioLists.ts +27 -0
  18. package/module/apis/rank/getTopLists.ts +37 -0
  19. package/module/apis/search/getHotKey.ts +24 -0
  20. package/module/apis/search/getSearchByKey.ts +31 -0
  21. package/module/apis/search/getSmartbox.ts +43 -0
  22. package/module/apis/singers/getSimilarSinger.ts +25 -0
  23. package/module/apis/singers/getSingerDesc.ts +25 -0
  24. package/module/apis/singers/getSingerMv.ts +24 -0
  25. package/module/apis/singers/getSingerStarNum.ts +24 -0
  26. package/module/apis/songLists/songListCategories.ts +22 -0
  27. package/module/apis/songLists/songListDetail.ts +27 -0
  28. package/module/apis/songLists/songLists.ts +35 -0
  29. package/module/apis/u_common.ts +29 -0
  30. package/module/apis/user/checkQQLoginQr.ts +230 -0
  31. package/module/apis/user/getQQLoginQr.ts +28 -0
  32. package/module/apis/user/getUserAvatar.ts +32 -0
  33. package/module/apis/user/getUserLikedSongs.ts +145 -0
  34. package/module/apis/user/getUserPlaylists.ts +163 -0
  35. package/module/apis/y_common.ts +44 -0
  36. package/module/config.ts +24 -0
  37. package/module/index.ts +95 -0
  38. package/package.json +25 -6
  39. package/pnpm-workspace.yaml +2 -0
  40. package/public/index.html +411 -29
  41. package/routers/context/batchGetSongInfo.ts +60 -0
  42. package/routers/context/batchGetSongLists.ts +46 -0
  43. package/routers/context/checkQQLoginQr.ts +19 -0
  44. package/routers/context/{cookies.js → cookies.ts} +14 -12
  45. package/routers/context/getAlbumInfo.ts +31 -0
  46. package/routers/context/getComments.ts +51 -0
  47. package/routers/context/getDigitalAlbumLists.ts +18 -0
  48. package/routers/context/getDownloadQQMusic.ts +17 -0
  49. package/routers/context/getHotkey.ts +25 -0
  50. package/routers/context/getImageUrl.ts +29 -0
  51. package/routers/context/getLyric.ts +32 -0
  52. package/routers/context/getMusicPlay.ts +102 -0
  53. package/routers/context/getMv.ts +61 -0
  54. package/routers/context/getMvByTag.ts +18 -0
  55. package/routers/context/getMvPlay.ts +114 -0
  56. package/routers/context/getNewDisks.ts +58 -0
  57. package/routers/context/getQQLoginQr.ts +16 -0
  58. package/routers/context/getRadioLists.ts +18 -0
  59. package/routers/context/getRanks.ts +67 -0
  60. package/routers/context/getRecommend.ts +92 -0
  61. package/routers/context/getSearchByKey.ts +34 -0
  62. package/routers/context/getSimilarSinger.ts +29 -0
  63. package/routers/context/getSingerAlbum.ts +58 -0
  64. package/routers/context/getSingerDesc.ts +30 -0
  65. package/routers/context/getSingerHotsong.ts +58 -0
  66. package/routers/context/getSingerList.ts +56 -0
  67. package/routers/context/getSingerMv.ts +41 -0
  68. package/routers/context/getSingerStarNum.ts +29 -0
  69. package/routers/context/getSmartbox.ts +27 -0
  70. package/routers/context/getSongInfo.ts +51 -0
  71. package/routers/context/{getSongListCategories.js → getSongListCategories.ts} +5 -4
  72. package/routers/context/getSongListDetail.ts +22 -0
  73. package/routers/context/getSongLists.ts +30 -0
  74. package/routers/context/getTicketInfo.ts +51 -0
  75. package/routers/context/getTopLists.ts +18 -0
  76. package/routers/context/getUserAvatar.ts +53 -0
  77. package/routers/context/getUserLikedSongs.ts +28 -0
  78. package/routers/context/getUserPlaylists.ts +29 -0
  79. package/routers/context/index.ts +87 -0
  80. package/routers/{router.js → router.ts} +7 -55
  81. package/routers/types.ts +18 -0
  82. package/routers/util.ts +231 -0
  83. package/tests/integration/api/api.test.ts +852 -0
  84. package/tests/integration/middleware/{cors.test.js → cors.test.ts} +7 -3
  85. package/tests/setup/jest.setup.ts +15 -0
  86. package/tests/setup/testUtils.ts +35 -0
  87. package/tests/unit/util/request.test.ts +177 -0
  88. package/tsconfig.json +20 -0
  89. package/tsconfig.test.json +8 -0
  90. package/types/api.ts +105 -0
  91. package/types/global.d.ts +26 -0
  92. package/types/index.d.ts +97 -0
  93. package/util/apiResponse.ts +97 -0
  94. package/util/colors.ts +31 -0
  95. package/util/cookie.ts +40 -0
  96. package/util/{loginUtils.js → loginUtils.ts} +3 -5
  97. package/util/lyricParse.ts +86 -0
  98. package/util/request.ts +141 -0
  99. package/.github/FUNDING.yml +0 -12
  100. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -38
  101. package/.github/ISSUE_TEMPLATE/custom.md +0 -24
  102. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  103. package/config/user-info.js +0 -42
  104. package/index.js +0 -1
  105. package/middlewares/koa-cors.js +0 -97
  106. package/module/apis/UCommon/UCommon.js +0 -6
  107. package/module/apis/album/getAlbumInfo.js +0 -33
  108. package/module/apis/comments/getComments.js +0 -35
  109. package/module/apis/digitalAlbum/getDigitalAlbumLists.js +0 -34
  110. package/module/apis/downloadQQMusic.js +0 -41
  111. package/module/apis/music/getLyric.js +0 -41
  112. package/module/apis/mv/getMvByTag.js +0 -35
  113. package/module/apis/radio/getRadioLists.js +0 -38
  114. package/module/apis/rank/getTopLists.js +0 -44
  115. package/module/apis/search/getHotKey.js +0 -35
  116. package/module/apis/search/getSearchByKey.js +0 -45
  117. package/module/apis/search/getSmartbox.js +0 -34
  118. package/module/apis/singers/getSimilarSinger.js +0 -36
  119. package/module/apis/singers/getSingerDesc.js +0 -37
  120. package/module/apis/singers/getSingerMv.js +0 -35
  121. package/module/apis/singers/getSingerStarNum.js +0 -35
  122. package/module/apis/songLists/songListCategories.js +0 -33
  123. package/module/apis/songLists/songListDetail.js +0 -38
  124. package/module/apis/songLists/songLists.js +0 -41
  125. package/module/apis/u_common.js +0 -17
  126. package/module/apis/user/checkQQLoginQr.js +0 -125
  127. package/module/apis/user/getQQLoginQr.js +0 -17
  128. package/module/apis/y_common.js +0 -27
  129. package/module/config.js +0 -31
  130. package/module/index.js +0 -82
  131. package/routers/context/batchGetSongInfo.js +0 -59
  132. package/routers/context/batchGetSongLists.js +0 -50
  133. package/routers/context/checkQQLoginQr.js +0 -17
  134. package/routers/context/getAlbumInfo.js +0 -27
  135. package/routers/context/getComments.js +0 -51
  136. package/routers/context/getDigitalAlbumLists.js +0 -14
  137. package/routers/context/getDownloadQQMusic.js +0 -14
  138. package/routers/context/getHotkey.js +0 -14
  139. package/routers/context/getImageUrl.js +0 -34
  140. package/routers/context/getLyric.js +0 -26
  141. package/routers/context/getMusicPlay.js +0 -116
  142. package/routers/context/getMv.js +0 -56
  143. package/routers/context/getMvByTag.js +0 -15
  144. package/routers/context/getMvPlay.js +0 -128
  145. package/routers/context/getNewDisks.js +0 -50
  146. package/routers/context/getQQLoginQr.js +0 -12
  147. package/routers/context/getRadioLists.js +0 -14
  148. package/routers/context/getRanks.js +0 -103
  149. package/routers/context/getRecommend.js +0 -86
  150. package/routers/context/getSearchByKey.js +0 -33
  151. package/routers/context/getSimilarSinger.js +0 -25
  152. package/routers/context/getSingerAlbum.js +0 -52
  153. package/routers/context/getSingerDesc.js +0 -25
  154. package/routers/context/getSingerHotsong.js +0 -52
  155. package/routers/context/getSingerList.js +0 -51
  156. package/routers/context/getSingerMv.js +0 -32
  157. package/routers/context/getSingerStarNum.js +0 -24
  158. package/routers/context/getSmartbox.js +0 -24
  159. package/routers/context/getSongInfo.js +0 -49
  160. package/routers/context/getSongListDetail.js +0 -25
  161. package/routers/context/getSongLists.js +0 -32
  162. package/routers/context/getTicketInfo.js +0 -45
  163. package/routers/context/getTopLists.js +0 -15
  164. package/routers/context/index.js +0 -74
  165. package/tests/integration/api/api.test.js +0 -116
  166. package/tests/setup/jest.setup.js +0 -46
  167. package/tests/setup/testUtils.js +0 -106
  168. package/tests/unit/util/lyricParse.test.js +0 -97
  169. package/tests/unit/util/request.test.js +0 -66
  170. package/util/colors.js +0 -16
  171. package/util/cookie.js +0 -22
  172. package/util/lyricParse.js +0 -67
  173. package/util/request.js +0 -57
@@ -0,0 +1,51 @@
1
+ import { KoaContext, Controller } from '../types';
2
+ import { getComments } from '../../module';
3
+
4
+ const controller: Controller = async (ctx, next) => {
5
+ const {
6
+ id,
7
+ pagesize = 25,
8
+ pagenum = 0,
9
+ cid = 205360772,
10
+ cmd = 8,
11
+ reqtype = 2,
12
+ biztype = 1,
13
+ rootcommentid = !pagenum && ''
14
+ } = ctx.query;
15
+
16
+ const checkrootcommentid = !pagenum ? true : !!rootcommentid;
17
+
18
+ const params = Object.assign({
19
+ cid,
20
+ reqtype,
21
+ biztype,
22
+ topid: id,
23
+ cmd,
24
+ pagenum,
25
+ pagesize,
26
+ lasthotcommentid: rootcommentid
27
+ });
28
+
29
+ const props = {
30
+ method: 'get',
31
+ params,
32
+ option: {}
33
+ };
34
+
35
+ if (id && checkrootcommentid) {
36
+ const { status, body } = await getComments(props);
37
+ Object.assign(ctx, {
38
+ status,
39
+ body
40
+ });
41
+ } else {
42
+ ctx.status = 400;
43
+ ctx.body = {
44
+ data: {
45
+ message: 'Don\'t have id or rootcommentid'
46
+ }
47
+ };
48
+ }
49
+ };
50
+
51
+ export default controller;
@@ -0,0 +1,18 @@
1
+ import { KoaContext, Controller } from '../types';
2
+ import { getDigitalAlbumLists } from '../../module';
3
+
4
+ const controller: Controller = async (ctx, next) => {
5
+ const props = {
6
+ method: 'get',
7
+ params: {},
8
+ option: {}
9
+ };
10
+
11
+ const { status, body } = await getDigitalAlbumLists(props);
12
+ Object.assign(ctx, {
13
+ status,
14
+ body
15
+ });
16
+ };
17
+
18
+ export default controller;
@@ -0,0 +1,17 @@
1
+ import { Context, Next } from 'koa';
2
+ import { downloadQQMusic } from '../../module';
3
+ import type { ApiResponse } from '../../types/api';
4
+
5
+ export default async (ctx: Context, next: Next) => {
6
+ const props = {
7
+ method: 'get',
8
+ params: {},
9
+ option: {}
10
+ };
11
+ const result = await downloadQQMusic(props) as ApiResponse;
12
+ const { status, body } = result;
13
+ Object.assign(ctx, {
14
+ status,
15
+ body
16
+ });
17
+ };
@@ -0,0 +1,25 @@
1
+ import { Context, Next } from 'koa';
2
+ import { getHotKey } from '../../module';
3
+
4
+ export default async (ctx: Context, next: Next) => {
5
+ const props = {
6
+ method: 'get',
7
+ params: {},
8
+ option: {}
9
+ };
10
+
11
+ if (process.env.DEBUG === 'true') {
12
+ console.log('[getHotkey] controller props:', props);
13
+ }
14
+
15
+ const { status, body } = await getHotKey(props);
16
+
17
+ if (process.env.DEBUG === 'true') {
18
+ console.log('[getHotkey] controller response status:', status);
19
+ }
20
+
21
+ Object.assign(ctx, {
22
+ status,
23
+ body
24
+ });
25
+ };
@@ -0,0 +1,29 @@
1
+ import { KoaContext, Controller } from '../types';
2
+
3
+ const controller: Controller = async (ctx, next) => {
4
+ const { id, size = '300x300', maxAge = 2592000 } = ctx.query;
5
+
6
+ if (!id) {
7
+ ctx.status = 400;
8
+ ctx.body = {
9
+ response: 'no id~~'
10
+ };
11
+ return;
12
+ }
13
+
14
+ const body = {
15
+ response: {
16
+ code: 0,
17
+ data: {
18
+ imageUrl: `https://y.gtimg.cn/music/photo_new/T002R${size}M000${id}.jpg?max_age=${maxAge}`
19
+ }
20
+ }
21
+ };
22
+
23
+ Object.assign(ctx, {
24
+ status: 200,
25
+ body
26
+ });
27
+ };
28
+
29
+ export default controller;
@@ -0,0 +1,32 @@
1
+ import { KoaContext, Controller } from '../types';
2
+ import { getLyric } from '../../module';
3
+
4
+ const controller: Controller = async (ctx, next) => {
5
+ const songmid = Array.isArray(ctx.query.songmid) ? ctx.query.songmid[0] : ctx.query.songmid;
6
+ const rawIsFormat = Array.isArray(ctx.query.isFormat) ? ctx.query.isFormat[0] : ctx.query.isFormat;
7
+
8
+ const props = {
9
+ method: 'get',
10
+ params: {
11
+ songmid
12
+ },
13
+ option: {},
14
+ isFormat: rawIsFormat
15
+ };
16
+
17
+ if (songmid) {
18
+ const { status, body } = await getLyric(props);
19
+ Object.assign(ctx, {
20
+ status,
21
+ body
22
+ });
23
+ } else {
24
+ ctx.status = 400;
25
+ ctx.body = {
26
+ response: 'no songmid'
27
+ };
28
+ }
29
+ };
30
+
31
+ export default controller;
32
+
@@ -0,0 +1,102 @@
1
+ import { KoaContext, Controller } from '../types';
2
+ import { UCommon } from '../../module';
3
+ import { _guid } from '../../module/config';
4
+
5
+ const ALLOWED_QUALITIES = ['m4a', 128, 320, 'ape', 'flac'];
6
+ const DEFAULT_QUALITY = 128;
7
+
8
+ const parseQuality = (quality: any): string | number => {
9
+ const parsed = parseInt(quality) || quality;
10
+ return ALLOWED_QUALITIES.includes(parsed) ? parsed : DEFAULT_QUALITY;
11
+ };
12
+
13
+ const controller: Controller = async (ctx, next) => {
14
+ const uin = (global as any).userInfo?.uin || '0';
15
+ const songmid = ctx.query.songmid + '';
16
+ const justPlayUrl = (ctx.query.resType || 'play') === 'play';
17
+ const guid = _guid || '1429839143';
18
+ const { mediaId } = ctx.query;
19
+ const quality = parseQuality(ctx.query.quality);
20
+
21
+ const fileType: Record<string, { s: string; e: string }> = {
22
+ m4a: { s: 'C400', e: '.m4a' },
23
+ 128: { s: 'M500', e: '.mp3' },
24
+ 320: { s: 'M800', e: '.mp3' },
25
+ ape: { s: 'A000', e: '.ape' },
26
+ flac: { s: 'F000', e: '.flac' }
27
+ };
28
+
29
+ const songmidList = songmid.split(',');
30
+ const fileInfo = fileType[quality as string];
31
+ const file = songmidList.map(_ => `${fileInfo.s}${_}${mediaId || _}${fileInfo.e}`);
32
+
33
+ const data = {
34
+ req_0: {
35
+ module: 'vkey.GetVkeyServer',
36
+ method: 'CgiGetVkey',
37
+ param: {
38
+ filename: file,
39
+ guid,
40
+ songmid: songmidList,
41
+ songtype: [0],
42
+ uin,
43
+ loginflag: 1,
44
+ platform: '20'
45
+ }
46
+ },
47
+ loginUin: uin,
48
+ comm: {
49
+ uin,
50
+ format: 'json',
51
+ ct: 24,
52
+ cv: 0
53
+ }
54
+ };
55
+
56
+ const params = Object.assign({
57
+ format: 'json',
58
+ sign: 'zzannc1o6o9b4i971602f3554385022046ab796512b7012',
59
+ data: JSON.stringify(data)
60
+ });
61
+
62
+ const props = {
63
+ method: 'get',
64
+ params,
65
+ option: {}
66
+ };
67
+
68
+ if (songmid) {
69
+ await UCommon(props)
70
+ .then(res => {
71
+ const response = res.data;
72
+ const domain =
73
+ response?.req_0?.data?.sip?.filter?.((i: string) => !i.startsWith('http://ws'))?.[0] ||
74
+ response?.req_0?.data?.sip?.[0];
75
+
76
+ const playUrl: Record<string, { url: string; error?: string }> = {};
77
+ (response?.req_0?.data?.midurlinfo || []).forEach((item: any) => {
78
+ playUrl[item.songmid] = {
79
+ url: item.purl ? `${domain}${item.purl}` : '',
80
+ error: !item.purl ? '暂无播放链接' : undefined
81
+ };
82
+ });
83
+
84
+ response.playUrl = playUrl;
85
+ ctx.body = {
86
+ data: justPlayUrl ? { playUrl } : response
87
+ };
88
+ })
89
+ .catch(error => {
90
+ console.log('error', error);
91
+ });
92
+ } else {
93
+ ctx.status = 400;
94
+ ctx.body = {
95
+ data: {
96
+ message: 'no songmid'
97
+ }
98
+ };
99
+ }
100
+ };
101
+
102
+ export default controller;
@@ -0,0 +1,61 @@
1
+ import { KoaContext, Controller } from '../types';
2
+ import { UCommon } from '../../module';
3
+
4
+ const controller: Controller = async (ctx, next) => {
5
+ const { area_id = 15, version_id = 7, limit = 20, page = 0 } = ctx.query;
6
+ const start = (+page ? +page - 1 : 0) * +limit;
7
+
8
+ const data = {
9
+ comm: {
10
+ ct: 24
11
+ },
12
+ mv_tag: {
13
+ module: 'MvService.MvInfoProServer',
14
+ method: 'GetAllocTag',
15
+ param: {}
16
+ },
17
+ mv_list: {
18
+ module: 'MvService.MvInfoProServer',
19
+ method: 'GetAllocMvInfo',
20
+ param: {
21
+ start,
22
+ limit: +limit,
23
+ version_id,
24
+ area_id,
25
+ order: 1
26
+ }
27
+ }
28
+ };
29
+
30
+ const params = Object.assign({
31
+ format: 'json',
32
+ data: JSON.stringify(data)
33
+ });
34
+
35
+ const props = {
36
+ method: 'get',
37
+ params,
38
+ option: {}
39
+ };
40
+
41
+ if (version_id && area_id) {
42
+ await UCommon(props)
43
+ .then(res => {
44
+ const response = res.data;
45
+ ctx.status = 200;
46
+ ctx.body = {
47
+ response
48
+ };
49
+ })
50
+ .catch(error => {
51
+ console.log('error', error);
52
+ });
53
+ } else {
54
+ ctx.status = 400;
55
+ ctx.body = {
56
+ response: 'version_id or area_id is null'
57
+ };
58
+ }
59
+ };
60
+
61
+ export default controller;
@@ -0,0 +1,18 @@
1
+ import { KoaContext, Controller } from '../types';
2
+ import { getMvByTag } from '../../module';
3
+
4
+ const controller: Controller = async (ctx, next) => {
5
+ const props = {
6
+ method: 'get',
7
+ params: {},
8
+ option: {}
9
+ };
10
+
11
+ const { status, body } = await getMvByTag(props);
12
+ Object.assign(ctx, {
13
+ status,
14
+ body
15
+ });
16
+ };
17
+
18
+ export default controller;
@@ -0,0 +1,114 @@
1
+ import { KoaContext, Controller } from '../types';
2
+ import { UCommon } from '../../module';
3
+
4
+ const controller: Controller = async (ctx, next) => {
5
+ const { vid } = ctx.query;
6
+
7
+ const data = {
8
+ comm: {
9
+ ct: 24,
10
+ cv: 4747474
11
+ },
12
+ getMVUrl: {
13
+ module: 'gosrf.Stream.MvUrlProxy',
14
+ method: 'GetMvUrls',
15
+ param: {
16
+ vids: [vid],
17
+ request_typet: 10001
18
+ }
19
+ },
20
+ mvinfo: {
21
+ module: 'video.VideoDataServer',
22
+ method: 'get_video_info_batch',
23
+ param: {
24
+ vidlist: [vid],
25
+ required: [
26
+ 'vid', 'type', 'sid', 'cover_pic', 'duration', 'singers',
27
+ 'video_switch', 'msg', 'name', 'desc', 'playcnt', 'pubdate',
28
+ 'isfav', 'gmid'
29
+ ]
30
+ }
31
+ },
32
+ other: {
33
+ module: 'video.VideoLogicServer',
34
+ method: 'rec_video_byvid',
35
+ param: {
36
+ vid,
37
+ required: [
38
+ 'vid', 'type', 'sid', 'cover_pic', 'duration', 'singers',
39
+ 'video_switch', 'msg', 'name', 'desc', 'playcnt', 'pubdate',
40
+ 'isfav', 'gmid', 'uploader_headurl', 'uploader_nick',
41
+ 'uploader_encuin', 'uploader_uin', 'uploader_hasfollow',
42
+ 'uploader_follower_num'
43
+ ],
44
+ support: 1
45
+ }
46
+ }
47
+ };
48
+
49
+ const params = Object.assign({
50
+ format: 'json',
51
+ data: JSON.stringify(data)
52
+ });
53
+
54
+ const props = {
55
+ method: 'get',
56
+ params,
57
+ option: {}
58
+ };
59
+
60
+ if (vid) {
61
+ await UCommon(props)
62
+ .then(res => {
63
+ const response = res.data;
64
+ const mvurls = response?.getMVUrl?.data;
65
+
66
+ if (!mvurls || typeof mvurls !== 'object' || Object.keys(mvurls).length === 0) {
67
+ ctx.status = 502;
68
+ ctx.body = {
69
+ response: {
70
+ data: null,
71
+ error: 'Failed to get MV URL data'
72
+ }
73
+ };
74
+ return;
75
+ }
76
+
77
+ const mvurlskey = Object.keys(mvurls)[0];
78
+ const mp4_urls = mvurls[mvurlskey]?.mp4?.map((item: any) => item.freeflow_url) || [];
79
+ const hls_urls = mvurls[mvurlskey]?.hls?.map((item: any) => item.freeflow_url) || [];
80
+ const urls = [...mp4_urls, ...hls_urls];
81
+
82
+ let play_urls: string[] = [];
83
+ let playLists: Record<string, string[]> = {};
84
+
85
+ if (urls.length) {
86
+ urls.forEach((url: string[]) => {
87
+ play_urls = [...play_urls, ...url];
88
+ });
89
+ playLists = {
90
+ f10: play_urls.filter((item: string) => /\.f10\.mp4/.test(item)),
91
+ f20: play_urls.filter((item: string) => /\.f20\.mp4/.test(item)),
92
+ f30: play_urls.filter((item: string) => /\.f30\.mp4/.test(item)),
93
+ f40: play_urls.filter((item: string) => /\.f40\.mp4/.test(item))
94
+ };
95
+ }
96
+
97
+ response.playLists = playLists;
98
+ ctx.status = 200;
99
+ ctx.body = {
100
+ response
101
+ };
102
+ })
103
+ .catch(error => {
104
+ console.log('error', error);
105
+ });
106
+ } else {
107
+ ctx.status = 400;
108
+ ctx.body = {
109
+ response: 'vid is null'
110
+ };
111
+ }
112
+ };
113
+
114
+ export default controller;
@@ -0,0 +1,58 @@
1
+ import { KoaContext, Controller } from '../types';
2
+ import { UCommon } from '../../module';
3
+
4
+ const controller: Controller = async (ctx, next) => {
5
+ const page = +ctx.query.page || 1;
6
+ const num = +ctx.query.limit || 20;
7
+ const start = (page - 1) * num;
8
+
9
+ const data: any = {
10
+ new_album: {
11
+ module: 'newalbum.NewAlbumServer',
12
+ method: 'get_new_album_info',
13
+ param: {
14
+ area: 1,
15
+ start,
16
+ num
17
+ }
18
+ },
19
+ comm: {
20
+ ct: 24,
21
+ cv: 0
22
+ }
23
+ };
24
+
25
+ if (!start) {
26
+ data.new_album_tag = {
27
+ module: 'newalbum.NewAlbumServer',
28
+ method: 'get_new_album_area',
29
+ param: {}
30
+ };
31
+ }
32
+
33
+ const params = Object.assign({
34
+ format: 'json',
35
+ data: JSON.stringify(data)
36
+ });
37
+
38
+ const props = {
39
+ method: 'get',
40
+ params,
41
+ option: {}
42
+ };
43
+
44
+ await UCommon(props)
45
+ .then(res => {
46
+ const response = res.data;
47
+ ctx.status = 200;
48
+ ctx.body = {
49
+ status: 200,
50
+ response
51
+ };
52
+ })
53
+ .catch(error => {
54
+ console.log('error', error);
55
+ });
56
+ };
57
+
58
+ export default controller;
@@ -0,0 +1,16 @@
1
+ import { KoaContext, Controller } from '../types';
2
+ import { getQQLoginQr } from '../../module';
3
+
4
+ const controller: Controller = async (ctx, next) => {
5
+ const props = {
6
+ method: 'get'
7
+ };
8
+
9
+ const { status, body } = await getQQLoginQr(props);
10
+ Object.assign(ctx, {
11
+ status,
12
+ body
13
+ });
14
+ };
15
+
16
+ export default controller;
@@ -0,0 +1,18 @@
1
+ import { KoaContext, Controller } from '../types';
2
+ import { getRadioLists } from '../../module';
3
+
4
+ const controller: Controller = async (ctx, next) => {
5
+ const props = {
6
+ method: 'get',
7
+ params: {},
8
+ option: {}
9
+ };
10
+
11
+ const { status, body } = await getRadioLists(props);
12
+ Object.assign(ctx, {
13
+ status,
14
+ body
15
+ });
16
+ };
17
+
18
+ export default controller;
@@ -0,0 +1,67 @@
1
+ import { KoaContext, Controller } from '../types';
2
+ import { UCommon } from '../../module';
3
+
4
+ const controller: Controller = async (ctx, next) => {
5
+ const getWeekNumber = (d: Date): number => {
6
+ d = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
7
+ const dayNum = d.getUTCDay() || 7;
8
+ d.setUTCDate(d.getUTCDate() + 4 - dayNum);
9
+ const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
10
+ return Math.ceil((((d.getTime() - yearStart.getTime()) / 86400000) + 1) / 7);
11
+ };
12
+
13
+ const topId = +ctx.query.topId || 4;
14
+ const num = +ctx.query.limit || 20;
15
+ const offset = +ctx.query.page || 0;
16
+
17
+ let date = new Date();
18
+ const week = getWeekNumber(date);
19
+ const isoWeekYearVal = date.getFullYear();
20
+ const period = `${isoWeekYearVal}_${week}`;
21
+
22
+ const data = {
23
+ comm: {
24
+ ct: 24,
25
+ cv: 4747474,
26
+ format: 'json',
27
+ inCharset: 'utf-8',
28
+ needNewCode: 1,
29
+ uin: 0
30
+ },
31
+ req_1: {
32
+ module: 'musicToplist.ToplistInfoServer',
33
+ method: 'GetDetail',
34
+ param: {
35
+ topId,
36
+ offset,
37
+ num,
38
+ period
39
+ }
40
+ }
41
+ };
42
+
43
+ const params = Object.assign({
44
+ format: 'json',
45
+ data: JSON.stringify(data)
46
+ });
47
+
48
+ const props = {
49
+ method: 'get',
50
+ params,
51
+ option: {}
52
+ };
53
+
54
+ await UCommon(props)
55
+ .then(res => {
56
+ const response = res.data;
57
+ ctx.status = 200;
58
+ ctx.body = {
59
+ response
60
+ };
61
+ })
62
+ .catch(error => {
63
+ console.log('error', error);
64
+ });
65
+ };
66
+
67
+ export default controller;