mirror of
https://gitlab.com/Binaryify/neteasecloudmusicapi.git
synced 2025-05-23 22:37:41 +08:00
Merge branch 'main' into 'main'
Some checks failed
Update Docker Hub Description / dockerHubDescription (push) Has been skipped
Node.js CI / Test (14.x) (push) Successful in 10m2s
Node.js CI / Test (16.x) (push) Successful in 9m50s
Node.js CI / Test (18.x) (push) Successful in 9m47s
Node.js CI / Lint (14.x) (push) Failing after 5m10s
Some checks failed
Update Docker Hub Description / dockerHubDescription (push) Has been skipped
Node.js CI / Test (14.x) (push) Successful in 10m2s
Node.js CI / Test (16.x) (push) Successful in 9m50s
Node.js CI / Test (18.x) (push) Successful in 9m47s
Node.js CI / Lint (14.x) (push) Failing after 5m10s
feat: 增加副歌时间、相关歌单推荐接口,原有相关歌单接口已废弃;fix: 将部分易盾白名单接口替换为eapi See merge request Binaryify/neteasecloudmusicapi!30
This commit is contained in:
commit
ae3ed350a8
@ -981,7 +981,7 @@
|
|||||||
|
|
||||||
- 新增 云盘歌曲删除, 热门话题, 电台 - 推荐类型, 电台 - 非热门类型, 电台 - 今日优选, 心动模式/智能播放等接口
|
- 新增 云盘歌曲删除, 热门话题, 电台 - 推荐类型, 电台 - 非热门类型, 电台 - 今日优选, 心动模式/智能播放等接口
|
||||||
|
|
||||||
- 更新文档:banner 接口 增加 `type` 参数; 获取动态消息接口增加 `pagesize` 和 `lasttime` 参数; 电台 - 付费精选接口修改默认`limit`为 30
|
- 更新文档:banner 接口 增加 `type` 参数; 获取动态列表接口增加 `pagesize` 和 `lasttime` 参数; 电台 - 付费精选接口修改默认`limit`为 30
|
||||||
|
|
||||||
### 3.8.1 | 2019.04.24
|
### 3.8.1 | 2019.04.24
|
||||||
|
|
||||||
|
@ -208,7 +208,7 @@ banner({ type: 0 }).then((res) => {
|
|||||||
62. 电台 - 详情
|
62. 电台 - 详情
|
||||||
63. 电台 - 节目
|
63. 电台 - 节目
|
||||||
64. 给评论点赞
|
64. 给评论点赞
|
||||||
65. 获取动态
|
65. 获取动态列表
|
||||||
66. 热搜列表(简略)
|
66. 热搜列表(简略)
|
||||||
67. 发送私信
|
67. 发送私信
|
||||||
68. 发送私信歌单
|
68. 发送私信歌单
|
||||||
@ -217,7 +217,7 @@ banner({ type: 0 }).then((res) => {
|
|||||||
71. 歌单分类
|
71. 歌单分类
|
||||||
72. 收藏的歌手列表
|
72. 收藏的歌手列表
|
||||||
73. 订阅的电台列表
|
73. 订阅的电台列表
|
||||||
74. 相关歌单推荐
|
74. 相关歌单
|
||||||
75. 付费精选接口
|
75. 付费精选接口
|
||||||
76. 音乐是否可用检查接口
|
76. 音乐是否可用检查接口
|
||||||
77. 登录状态
|
77. 登录状态
|
||||||
@ -447,6 +447,8 @@ banner({ type: 0 }).then((res) => {
|
|||||||
301. 听歌足迹 - 周/月/年收听报告
|
301. 听歌足迹 - 周/月/年收听报告
|
||||||
302. 歌单导入 - 元数据/文字/链接导入
|
302. 歌单导入 - 元数据/文字/链接导入
|
||||||
303. 歌单导入 - 任务状态
|
303. 歌单导入 - 任务状态
|
||||||
|
304. 副歌时间
|
||||||
|
305. 相关歌单推荐
|
||||||
|
|
||||||
## 单元测试
|
## 单元测试
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ module.exports = async (query, request) => {
|
|||||||
{
|
{
|
||||||
imgid: uploadInfo.imgId,
|
imgid: uploadInfo.imgId,
|
||||||
},
|
},
|
||||||
createOption(query, 'weapi'),
|
createOption(query),
|
||||||
)
|
)
|
||||||
return {
|
return {
|
||||||
status: 200,
|
status: 200,
|
||||||
|
@ -12,5 +12,5 @@ module.exports = (query, request) => {
|
|||||||
const data = {
|
const data = {
|
||||||
type: query.type || 0,
|
type: query.type || 0,
|
||||||
}
|
}
|
||||||
return request(`/api/point/dailyTask`, data, createOption(query, 'weapi'))
|
return request(`/api/point/dailyTask`, data, createOption(query))
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// 动态
|
// 获取动态列表
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
const createOption = require('../util/option.js')
|
||||||
module.exports = (query, request) => {
|
module.exports = (query, request) => {
|
||||||
|
@ -7,5 +7,5 @@ module.exports = (query, request) => {
|
|||||||
id: query.evId,
|
id: query.evId,
|
||||||
eventUserId: query.uid,
|
eventUserId: query.uid,
|
||||||
}
|
}
|
||||||
return request(`/api/event/forward`, data, createOption(query, 'weapi'))
|
return request(`/api/event/forward`, data, createOption(query))
|
||||||
}
|
}
|
||||||
|
@ -5,5 +5,5 @@ module.exports = (query, request) => {
|
|||||||
const data = {
|
const data = {
|
||||||
uid: query.uid,
|
uid: query.uid,
|
||||||
}
|
}
|
||||||
return request(`/api/song/like/get`, data, createOption(query, 'weapi'))
|
return request(`/api/song/like/get`, data, createOption(query))
|
||||||
}
|
}
|
||||||
|
@ -7,5 +7,5 @@ module.exports = (query, request) => {
|
|||||||
privacy: query.privacy, //0 为普通歌单,10 为隐私歌单
|
privacy: query.privacy, //0 为普通歌单,10 为隐私歌单
|
||||||
type: query.type || 'NORMAL', // NORMAL|VIDEO|SHARED
|
type: query.type || 'NORMAL', // NORMAL|VIDEO|SHARED
|
||||||
}
|
}
|
||||||
return request(`/api/playlist/create`, data, createOption(query, 'weapi'))
|
return request(`/api/playlist/create`, data, createOption(query))
|
||||||
}
|
}
|
||||||
|
11
module/playlist_detail_rcmd_get.js
Normal file
11
module/playlist_detail_rcmd_get.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// 相关歌单推荐
|
||||||
|
|
||||||
|
const createOption = require('../util/option.js')
|
||||||
|
module.exports = (query, request) => {
|
||||||
|
const data = {
|
||||||
|
scene: 'playlist_head',
|
||||||
|
playlistId: query.id,
|
||||||
|
newStyle: 'true',
|
||||||
|
}
|
||||||
|
return request(`/api/playlist/detail/rcmd/get`, data, createOption(query))
|
||||||
|
}
|
@ -7,9 +7,5 @@ module.exports = (query, request) => {
|
|||||||
limit: query.limit || 20,
|
limit: query.limit || 20,
|
||||||
offset: query.offset || 0,
|
offset: query.offset || 0,
|
||||||
}
|
}
|
||||||
return request(
|
return request(`/api/playlist/subscribers`, data, createOption(query))
|
||||||
`/api/playlist/subscribers`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,7 @@ module.exports = (query, request) => {
|
|||||||
']',
|
']',
|
||||||
}
|
}
|
||||||
|
|
||||||
return request(
|
return request(`/api/v3/song/detail`, idsData, createOption(query))
|
||||||
`/api/v3/song/detail`,
|
|
||||||
idsData,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ module.exports = async (query, request) => {
|
|||||||
const res = await request(
|
const res = await request(
|
||||||
`/api/playlist/manipulate/tracks`,
|
`/api/playlist/manipulate/tracks`,
|
||||||
data,
|
data,
|
||||||
createOption(query, 'weapi'),
|
createOption(query),
|
||||||
)
|
)
|
||||||
return {
|
return {
|
||||||
status: 200,
|
status: 200,
|
||||||
@ -33,7 +33,7 @@ module.exports = async (query, request) => {
|
|||||||
trackIds: JSON.stringify([...tracks, ...tracks]),
|
trackIds: JSON.stringify([...tracks, ...tracks]),
|
||||||
imme: 'true',
|
imme: 'true',
|
||||||
},
|
},
|
||||||
createOption(query, 'weapi'),
|
createOption(query),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
|
@ -9,5 +9,5 @@ module.exports = (query, request) => {
|
|||||||
'/api/playlist/tags/update': `{"id":${query.id},"tags":"${query.tags}"}`,
|
'/api/playlist/tags/update': `{"id":${query.id},"tags":"${query.tags}"}`,
|
||||||
'/api/playlist/update/name': `{"id":${query.id},"name":"${query.name}"}`,
|
'/api/playlist/update/name': `{"id":${query.id},"name":"${query.name}"}`,
|
||||||
}
|
}
|
||||||
return request(`/api/batch`, data, createOption(query, 'weapi'))
|
return request(`/api/batch`, data, createOption(query))
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,5 @@ module.exports = (query, request) => {
|
|||||||
const data = {
|
const data = {
|
||||||
id: query.id,
|
id: query.id,
|
||||||
}
|
}
|
||||||
return request(
|
return request(`/api/playlist/update/playcount`, data, createOption(query))
|
||||||
`/api/playlist/update/playcount`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,5 @@ module.exports = (query, request) => {
|
|||||||
startMusicId: query.sid || query.id,
|
startMusicId: query.sid || query.id,
|
||||||
count: query.count || 1,
|
count: query.count || 1,
|
||||||
}
|
}
|
||||||
return request(
|
return request(`/api/playmode/intelligence/list`, data, createOption(query))
|
||||||
`/api/playmode/intelligence/list`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
@ -10,5 +10,5 @@ module.exports = (query, request) => {
|
|||||||
nickname: query.nickname,
|
nickname: query.nickname,
|
||||||
countrycode: query.countrycode || '86',
|
countrycode: query.countrycode || '86',
|
||||||
}
|
}
|
||||||
return request(`/api/register/cellphone`, data, createOption(query, 'weapi'))
|
return request(`/api/register/cellphone`, data, createOption(query))
|
||||||
}
|
}
|
||||||
|
@ -8,5 +8,5 @@ module.exports = (query, request) => {
|
|||||||
msg: query.msg,
|
msg: query.msg,
|
||||||
userIds: '[' + query.user_ids + ']',
|
userIds: '[' + query.user_ids + ']',
|
||||||
}
|
}
|
||||||
return request(`/api/msg/private/send`, data, createOption(query, 'weapi'))
|
return request(`/api/msg/private/send`, data, createOption(query))
|
||||||
}
|
}
|
||||||
|
@ -7,5 +7,5 @@ module.exports = (query, request) => {
|
|||||||
msg: query.msg,
|
msg: query.msg,
|
||||||
userIds: '[' + query.user_ids + ']',
|
userIds: '[' + query.user_ids + ']',
|
||||||
}
|
}
|
||||||
return request(`/api/msg/private/send`, data, createOption(query, 'weapi'))
|
return request(`/api/msg/private/send`, data, createOption(query))
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,5 @@ module.exports = (query, request) => {
|
|||||||
msg: query.msg || '',
|
msg: query.msg || '',
|
||||||
id: query.id || '',
|
id: query.id || '',
|
||||||
}
|
}
|
||||||
return request(
|
return request(`/api/share/friends/resource`, data, createOption(query))
|
||||||
`/api/share/friends/resource`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
11
module/song_chorus.js
Normal file
11
module/song_chorus.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// 副歌时间
|
||||||
|
const createOption = require('../util/option.js')
|
||||||
|
module.exports = (query, request) => {
|
||||||
|
return request(
|
||||||
|
`/api/song/chorus`,
|
||||||
|
{
|
||||||
|
ids: JSON.stringify([query.id]),
|
||||||
|
},
|
||||||
|
createOption(query),
|
||||||
|
)
|
||||||
|
}
|
@ -11,5 +11,5 @@ module.exports = (query, request) => {
|
|||||||
province: query.province,
|
province: query.province,
|
||||||
signature: query.signature,
|
signature: query.signature,
|
||||||
}
|
}
|
||||||
return request(`/api/user/profile/update`, data, createOption(query, 'weapi'))
|
return request(`/api/user/profile/update`, data, createOption(query))
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
62. 电台 - 详情
|
62. 电台 - 详情
|
||||||
63. 电台 - 节目
|
63. 电台 - 节目
|
||||||
64. 给评论点赞
|
64. 给评论点赞
|
||||||
65. 获取动态
|
65. 获取动态列表
|
||||||
66. 热搜列表(简略)
|
66. 热搜列表(简略)
|
||||||
67. 发送私信
|
67. 发送私信
|
||||||
68. 发送私信歌单
|
68. 发送私信歌单
|
||||||
@ -89,7 +89,7 @@
|
|||||||
71. 歌单分类
|
71. 歌单分类
|
||||||
72. 收藏的歌手列表
|
72. 收藏的歌手列表
|
||||||
73. 订阅的电台列表
|
73. 订阅的电台列表
|
||||||
74. 相关歌单推荐
|
74. 相关歌单
|
||||||
75. 付费精选接口
|
75. 付费精选接口
|
||||||
76. 音乐是否可用检查接口
|
76. 音乐是否可用检查接口
|
||||||
77. 登录状态
|
77. 登录状态
|
||||||
@ -319,6 +319,8 @@
|
|||||||
301. 听歌足迹 - 周/月/年收听报告
|
301. 听歌足迹 - 周/月/年收听报告
|
||||||
302. 歌单导入 - 元数据/文字/链接导入
|
302. 歌单导入 - 元数据/文字/链接导入
|
||||||
303. 歌单导入 - 任务状态
|
303. 歌单导入 - 任务状态
|
||||||
|
304. 副歌时间
|
||||||
|
305. 相关歌单推荐
|
||||||
|
|
||||||
## 安装
|
## 安装
|
||||||
|
|
||||||
@ -1225,7 +1227,7 @@ tags: 歌单标签
|
|||||||
|
|
||||||
**调用例子 :** `/playmode/intelligence/list?id=33894312&pid=24381616` , `/playmode/intelligence/list?id=33894312&pid=24381616&sid=36871368`
|
**调用例子 :** `/playmode/intelligence/list?id=33894312&pid=24381616` , `/playmode/intelligence/list?id=33894312&pid=24381616&sid=36871368`
|
||||||
|
|
||||||
### 获取动态消息
|
### 获取动态列表
|
||||||
|
|
||||||
说明 : 调用此接口 , 可获取各种动态 , 对应网页版网易云,朋友界面里的各种动态消息
|
说明 : 调用此接口 , 可获取各种动态 , 对应网页版网易云,朋友界面里的各种动态消息
|
||||||
,如分享的视频,音乐,照片等!
|
,如分享的视频,音乐,照片等!
|
||||||
@ -1441,15 +1443,17 @@ tags: 歌单标签
|
|||||||
|
|
||||||
**调用例子 :** `/top/playlist/highquality?before=1503639064232&limit=3`
|
**调用例子 :** `/top/playlist/highquality?before=1503639064232&limit=3`
|
||||||
|
|
||||||
### 相关歌单推荐
|
### 相关歌单
|
||||||
|
|
||||||
说明 : 调用此接口,传入歌单 id 可获取相关歌单(对应页面 [https://music.163.com/#/playlist?id=1](https://music.163.com/#/playlist?id=1))
|
说明: 请替换为[相关歌单推荐](#相关歌单推荐)接口; 本接口通过html抓取内容, 现已无法抓取歌单
|
||||||
|
|
||||||
**必选参数 :** `id` : 歌单 id
|
~~说明 : 调用此接口,传入歌单 id 可获取相关歌单(对应页面 [https://music.163.com/#/playlist?id=1](https://music.163.com/#/playlist?id=1))~~
|
||||||
|
|
||||||
**接口地址 :** `/related/playlist`
|
~~**必选参数 :** `id` : 歌单 id~~
|
||||||
|
|
||||||
**调用例子 :** `/related/playlist?id=1`
|
~~**接口地址 :** `/related/playlist`~~
|
||||||
|
|
||||||
|
~~**调用例子 :** `/related/playlist?id=1`~~
|
||||||
|
|
||||||
### 获取歌单详情
|
### 获取歌单详情
|
||||||
|
|
||||||
@ -4925,7 +4929,8 @@ bitrate = Math.floor(br / 1000)
|
|||||||
|
|
||||||
**可选参数 :**
|
**可选参数 :**
|
||||||
|
|
||||||
`importStarPlaylist` : 是否导入`我喜欢的音乐`
|
`importStarPlaylist` : 是否导入`我喜欢的音乐`, 此项为true则不生成新的歌单
|
||||||
|
`playlistName` : 生成的歌单名, 仅文字导入和链接导入支持, 默认为```'导入音乐 '.concat(new Date().toLocaleString())```
|
||||||
|
|
||||||
**元数据导入 :**
|
**元数据导入 :**
|
||||||
|
|
||||||
@ -4989,6 +4994,30 @@ let link = encodeURIComponent(
|
|||||||
|
|
||||||
**调用例子:** `/playlist/import/task/status?id=123834369`
|
**调用例子:** `/playlist/import/task/status?id=123834369`
|
||||||
|
|
||||||
|
### 副歌时间
|
||||||
|
|
||||||
|
说明: 调用此接口, 传入歌曲id, 获取副歌时间
|
||||||
|
|
||||||
|
**必选参数:**
|
||||||
|
|
||||||
|
`id`: 歌曲id
|
||||||
|
|
||||||
|
**接口地址:** `/song/chorus`
|
||||||
|
|
||||||
|
**调用例子:** `/song/chorus?id=2058263032`
|
||||||
|
|
||||||
|
### 相关歌单推荐
|
||||||
|
|
||||||
|
说明: 调用此接口, 传入歌单id, 获取相关歌单推荐
|
||||||
|
|
||||||
|
**必选参数:**
|
||||||
|
|
||||||
|
`id`: 歌单id
|
||||||
|
|
||||||
|
**接口地址:** `/playlist/detail/rcmd/get`
|
||||||
|
|
||||||
|
**调用例子:** `/playlist/detail/rcmd/get?id=8039587836`
|
||||||
|
|
||||||
## 离线访问此文档
|
## 离线访问此文档
|
||||||
|
|
||||||
此文档同时也是 Progressive Web Apps(PWA), 加入了 serviceWorker, 可离线访问
|
此文档同时也是 Progressive Web Apps(PWA), 加入了 serviceWorker, 可离线访问
|
||||||
|
@ -98,6 +98,7 @@
|
|||||||
<li><a href="./cloud.html">云盘上传</a></li>
|
<li><a href="./cloud.html">云盘上传</a></li>
|
||||||
<li><a href="./eapi_decrypt.html">eapi 参数/返回值解析</a></li>
|
<li><a href="./eapi_decrypt.html">eapi 参数/返回值解析</a></li>
|
||||||
<li><a href="./api.html">API 调试界面</a></li>
|
<li><a href="./api.html">API 调试界面</a></li>
|
||||||
|
<li><a href="./playlist_import.html">歌单导入工具</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
262
public/playlist_import.html
Normal file
262
public/playlist_import.html
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>歌单导入工具</title>
|
||||||
|
<!-- 引入Bootstrap CSS -->
|
||||||
|
<link href="https://fastly.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<!-- 引入Bootstrap JS -->
|
||||||
|
<script src="https://fastly.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<!-- 引入axios用于发送异步请求 -->
|
||||||
|
<script src="https://fastly.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container mt-5">
|
||||||
|
<h1 class="mb-4">歌单导入工具</h1>
|
||||||
|
<p>请选择一种导入方式并填写相关信息:</p>
|
||||||
|
|
||||||
|
<!-- 表单开始 -->
|
||||||
|
<form id="importForm" novalidate>
|
||||||
|
<!-- 选项卡导航 -->
|
||||||
|
<ul class="nav nav-tabs mb-3" id="importTabs" role="tablist">
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link active" id="metadata-tab" data-bs-toggle="tab" data-bs-target="#metadata" type="button" role="tab" aria-controls="metadata" aria-selected="true">元数据导入</button>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link" id="text-tab" data-bs-toggle="tab" data-bs-target="#text" type="button" role="tab" aria-controls="text" aria-selected="false">文字导入</button>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link" id="link-tab" data-bs-toggle="tab" data-bs-target="#link" type="button" role="tab" aria-controls="link" aria-selected="false">链接导入</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!-- 选项卡面板 -->
|
||||||
|
<div class="tab-content" id="importTabContent">
|
||||||
|
<!-- 元数据导入 -->
|
||||||
|
<div class="tab-pane fade show active" id="metadata" role="tabpanel" aria-labelledby="metadata-tab">
|
||||||
|
<table class="table table-bordered mb-3">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">歌曲名称</th>
|
||||||
|
<th scope="col">艺术家</th>
|
||||||
|
<th scope="col">专辑</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="metadataTableBody">
|
||||||
|
<!-- 默认添加一行 -->
|
||||||
|
<tr>
|
||||||
|
<td><input type="text" class="form-control" name="name[]" placeholder="歌曲名称"></td>
|
||||||
|
<td><input type="text" class="form-control" name="artist[]" placeholder="艺术家"></td>
|
||||||
|
<td><input type="text" class="form-control" name="album[]" placeholder="专辑"></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<button type="button" class="btn btn-secondary mb-3" id="addMetadataRow">增加歌曲</button>
|
||||||
|
</div>
|
||||||
|
<!-- 文字导入 -->
|
||||||
|
<div class="tab-pane fade" id="text" role="tabpanel" aria-labelledby="text-tab">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="textInput" class="form-label">文字:</label>
|
||||||
|
<textarea class="form-control" id="textInput" name="text" rows="5"></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="playlistNameInput" class="form-label">歌单名:</label>
|
||||||
|
<input type="text" class="form-control" id="playlistNameInput" name="playlistName" placeholder="请输入歌单名">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 链接导入 -->
|
||||||
|
<div class="tab-pane fade" id="link" role="tabpanel" aria-labelledby="link-tab">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="linkInputs" class="form-label">链接:</label>
|
||||||
|
<div id="linkInputsContainer">
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<input type="text" class="form-control" id="linkInput0" name="linkInput0" placeholder="请输入链接">
|
||||||
|
<button type="button" class="btn btn-secondary removeLinkButton" data-index="0">×</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn btn-secondary mb-3" id="addLinkButton">增加链接</button>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="playlistNameLinkInput" class="form-label">歌单名:</label>
|
||||||
|
<input type="text" class="form-control" id="playlistNameLinkInput" name="playlistName" placeholder="请输入歌单名">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 是否导入我喜欢的音乐 -->
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" value="" id="importStarCheckbox">
|
||||||
|
<label class="form-check-label" for="importStarCheckbox">
|
||||||
|
导入“我喜欢的音乐”
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 提交按钮 -->
|
||||||
|
<button type="submit" class="btn btn-primary mt-3">导入歌曲</button>
|
||||||
|
</form>
|
||||||
|
<!-- 表单结束 -->
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// 动态增加链接输入框
|
||||||
|
document.getElementById('addLinkButton').addEventListener('click', function() {
|
||||||
|
var container = document.getElementById('linkInputsContainer');
|
||||||
|
var newIndex = container.childElementCount - 1; // 减去非输入框元素的数量
|
||||||
|
var newInput = document.createElement('input');
|
||||||
|
newInput.type = 'text';
|
||||||
|
newInput.className = 'form-control';
|
||||||
|
newInput.id = `linkInput${newIndex}`;
|
||||||
|
newInput.name = `linkInput${newIndex}`;
|
||||||
|
newInput.placeholder = '请输入链接';
|
||||||
|
|
||||||
|
var removeButton = document.createElement('button');
|
||||||
|
removeButton.type = 'button';
|
||||||
|
removeButton.className = 'btn btn-secondary removeLinkButton';
|
||||||
|
removeButton.textContent = '×';
|
||||||
|
removeButton.dataset.index = newIndex.toString();
|
||||||
|
removeButton.addEventListener('click', function() {
|
||||||
|
var group = this.closest('.input-group');
|
||||||
|
container.removeChild(group);
|
||||||
|
});
|
||||||
|
|
||||||
|
var inputGroup = document.createElement('div');
|
||||||
|
inputGroup.className = 'input-group mb-3';
|
||||||
|
inputGroup.appendChild(newInput);
|
||||||
|
inputGroup.appendChild(removeButton);
|
||||||
|
|
||||||
|
container.appendChild(inputGroup);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 动态增加元数据行
|
||||||
|
document.getElementById('addMetadataRow').addEventListener('click', function() {
|
||||||
|
var container = document.getElementById('metadataTableBody');
|
||||||
|
var newRow = document.createElement('tr');
|
||||||
|
|
||||||
|
var nameInput = document.createElement('input');
|
||||||
|
nameInput.type = 'text';
|
||||||
|
nameInput.className = 'form-control';
|
||||||
|
nameInput.name = 'name[]';
|
||||||
|
nameInput.placeholder = '歌曲名称';
|
||||||
|
|
||||||
|
var artistInput = document.createElement('input');
|
||||||
|
artistInput.type = 'text';
|
||||||
|
artistInput.className = 'form-control';
|
||||||
|
artistInput.name = 'artist[]';
|
||||||
|
artistInput.placeholder = '艺术家';
|
||||||
|
|
||||||
|
var albumInput = document.createElement('input');
|
||||||
|
albumInput.type = 'text';
|
||||||
|
albumInput.className = 'form-control';
|
||||||
|
albumInput.name = 'album[]';
|
||||||
|
albumInput.placeholder = '专辑';
|
||||||
|
|
||||||
|
newRow.innerHTML = `
|
||||||
|
<td>${nameInput.outerHTML}</td>
|
||||||
|
<td>${artistInput.outerHTML}</td>
|
||||||
|
<td>${albumInput.outerHTML}</td>
|
||||||
|
`;
|
||||||
|
|
||||||
|
container.appendChild(newRow);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('importForm').addEventListener('submit', async function(event) {
|
||||||
|
// 阻止默认行为
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
// 获取表单值
|
||||||
|
let text = document.getElementById('textInput').value;
|
||||||
|
let links = [];
|
||||||
|
let local = [];
|
||||||
|
let playlistName = '';
|
||||||
|
|
||||||
|
// 获取所有链接输入框的值
|
||||||
|
let linkInputs = document.querySelectorAll('#linkInputsContainer .input-group .form-control');
|
||||||
|
linkInputs.forEach(function(input) {
|
||||||
|
if (input.value.trim() !== '') {
|
||||||
|
links.push(input.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 获取元数据
|
||||||
|
let metadataRows = document.querySelectorAll('#metadataTableBody tr');
|
||||||
|
metadataRows.forEach(function(row) {
|
||||||
|
let name = row.querySelector('input[name="name[]"]').value;
|
||||||
|
let artist = row.querySelector('input[name="artist[]"]').value;
|
||||||
|
let album = row.querySelector('input[name="album[]"]').value;
|
||||||
|
if (name && artist && album) {
|
||||||
|
local.push({ name, artist, album });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 检查是否有且只有一个输入字段被填写
|
||||||
|
let filledCount = (text ? 1 : 0) + (links.length > 0 ? 1 : 0) + (local.length > 0 ? 1 : 0);
|
||||||
|
if (filledCount !== 1) {
|
||||||
|
alert("请确保仅填写了一个输入字段!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取歌单名
|
||||||
|
if (document.getElementById('importStarCheckbox').checked) {
|
||||||
|
playlistName = '我喜欢的音乐';
|
||||||
|
} else {
|
||||||
|
playlistName = document.getElementById('playlistNameInput').value ||
|
||||||
|
document.getElementById('playlistNameLinkInput').value ||
|
||||||
|
'导入音乐 ' + new Date().toLocaleString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建请求参数
|
||||||
|
let data = {};
|
||||||
|
if (text) {
|
||||||
|
data.text = text;
|
||||||
|
data.playlistName = playlistName;
|
||||||
|
} else if (links.length > 0) {
|
||||||
|
data.link = JSON.stringify(links);
|
||||||
|
data.playlistName = playlistName;
|
||||||
|
} else if (local.length > 0) {
|
||||||
|
data.local = JSON.stringify(local);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加额外参数
|
||||||
|
if (document.getElementById('importStarCheckbox').checked) {
|
||||||
|
data.importStarPlaylist = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await axios({
|
||||||
|
url: `/playlist/import/name/task/create?timestamp=${Date.now()}`,
|
||||||
|
method: 'post',
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
|
||||||
|
let taskId = res.data?.data?.taskId
|
||||||
|
if (taskId) {
|
||||||
|
alert(`任务创建成功! 正在导入, 请稍等; 任务id:${taskId}`)
|
||||||
|
// const res2 = await axios({
|
||||||
|
// url: `/playlist/import/task/status?timestamp=${Date.now()}`,
|
||||||
|
// method: 'post',
|
||||||
|
// data: {
|
||||||
|
// id: taskId
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// alert(JSON.stringify(res2.data, null, 2));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error:', error);
|
||||||
|
alert('导入失败,请检查您的输入或稍后再试。');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 监听复选框状态变化
|
||||||
|
document.getElementById('importStarCheckbox').addEventListener('change', function() {
|
||||||
|
let isChecked = this.checked;
|
||||||
|
let playlistNameInputs = document.querySelectorAll('[name="playlistName"]');
|
||||||
|
playlistNameInputs.forEach(function(input) {
|
||||||
|
input.disabled = isChecked;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始化时设置歌单名输入框的状态
|
||||||
|
document.getElementById('importStarCheckbox').dispatchEvent(new Event('change'));
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
x
Reference in New Issue
Block a user