Skip to content

Commit 1fff1d5

Browse files
committed
feat: 增加歌单导入工具example
1 parent a71eaf7 commit 1fff1d5

3 files changed

Lines changed: 265 additions & 1 deletion

File tree

public/docs/home.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4929,7 +4929,8 @@ bitrate = Math.floor(br / 1000)
49294929

49304930
**可选参数 :**
49314931

4932-
`importStarPlaylist` : 是否导入`我喜欢的音乐`
4932+
`importStarPlaylist` : 是否导入`我喜欢的音乐`, 此项为true则不生成新的歌单
4933+
`playlistName` : 生成的歌单名, 仅文字导入和链接导入支持, 默认为```'导入音乐 '.concat(new Date().toLocaleString())```
49334934

49344935
**元数据导入 :**
49354936

public/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ <h2>例子:</h2>
9898
<li><a href="./cloud.html">云盘上传</a></li>
9999
<li><a href="./eapi_decrypt.html">eapi 参数/返回值解析</a></li>
100100
<li><a href="./api.html">API 调试界面</a></li>
101+
<li><a href="./playlist_import.html">歌单导入工具</a></li>
101102
</ul>
102103
</div>
103104

public/playlist_import.html

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
<!DOCTYPE html>
2+
<html lang="zh-CN">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>歌单导入工具</title>
6+
<!-- 引入Bootstrap CSS -->
7+
<link href="https://fastly.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
8+
<!-- 引入Bootstrap JS -->
9+
<script src="https://fastly.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
10+
<!-- 引入axios用于发送异步请求 -->
11+
<script src="https://fastly.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
12+
</head>
13+
<body>
14+
<div class="container mt-5">
15+
<h1 class="mb-4">歌单导入工具</h1>
16+
<p>请选择一种导入方式并填写相关信息:</p>
17+
18+
<!-- 表单开始 -->
19+
<form id="importForm" novalidate>
20+
<!-- 选项卡导航 -->
21+
<ul class="nav nav-tabs mb-3" id="importTabs" role="tablist">
22+
<li class="nav-item" role="presentation">
23+
<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>
24+
</li>
25+
<li class="nav-item" role="presentation">
26+
<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>
27+
</li>
28+
<li class="nav-item" role="presentation">
29+
<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>
30+
</li>
31+
</ul>
32+
33+
<!-- 选项卡面板 -->
34+
<div class="tab-content" id="importTabContent">
35+
<!-- 元数据导入 -->
36+
<div class="tab-pane fade show active" id="metadata" role="tabpanel" aria-labelledby="metadata-tab">
37+
<table class="table table-bordered mb-3">
38+
<thead>
39+
<tr>
40+
<th scope="col">歌曲名称</th>
41+
<th scope="col">艺术家</th>
42+
<th scope="col">专辑</th>
43+
</tr>
44+
</thead>
45+
<tbody id="metadataTableBody">
46+
<!-- 默认添加一行 -->
47+
<tr>
48+
<td><input type="text" class="form-control" name="name[]" placeholder="歌曲名称"></td>
49+
<td><input type="text" class="form-control" name="artist[]" placeholder="艺术家"></td>
50+
<td><input type="text" class="form-control" name="album[]" placeholder="专辑"></td>
51+
</tr>
52+
</tbody>
53+
</table>
54+
<button type="button" class="btn btn-secondary mb-3" id="addMetadataRow">增加歌曲</button>
55+
</div>
56+
<!-- 文字导入 -->
57+
<div class="tab-pane fade" id="text" role="tabpanel" aria-labelledby="text-tab">
58+
<div class="mb-3">
59+
<label for="textInput" class="form-label">文字:</label>
60+
<textarea class="form-control" id="textInput" name="text" rows="5"></textarea>
61+
</div>
62+
<div class="mb-3">
63+
<label for="playlistNameInput" class="form-label">歌单名:</label>
64+
<input type="text" class="form-control" id="playlistNameInput" name="playlistName" placeholder="请输入歌单名">
65+
</div>
66+
</div>
67+
<!-- 链接导入 -->
68+
<div class="tab-pane fade" id="link" role="tabpanel" aria-labelledby="link-tab">
69+
<div class="mb-3">
70+
<label for="linkInputs" class="form-label">链接:</label>
71+
<div id="linkInputsContainer">
72+
<div class="input-group mb-3">
73+
<input type="text" class="form-control" id="linkInput0" name="linkInput0" placeholder="请输入链接">
74+
<button type="button" class="btn btn-secondary removeLinkButton" data-index="0">×</button>
75+
</div>
76+
</div>
77+
<button type="button" class="btn btn-secondary mb-3" id="addLinkButton">增加链接</button>
78+
<div class="mb-3">
79+
<label for="playlistNameLinkInput" class="form-label">歌单名:</label>
80+
<input type="text" class="form-control" id="playlistNameLinkInput" name="playlistName" placeholder="请输入歌单名">
81+
</div>
82+
</div>
83+
</div>
84+
</div>
85+
86+
<!-- 是否导入我喜欢的音乐 -->
87+
<div class="form-check">
88+
<input class="form-check-input" type="checkbox" value="" id="importStarCheckbox">
89+
<label class="form-check-label" for="importStarCheckbox">
90+
导入“我喜欢的音乐”
91+
</label>
92+
</div>
93+
94+
<!-- 提交按钮 -->
95+
<button type="submit" class="btn btn-primary mt-3">导入歌曲</button>
96+
</form>
97+
<!-- 表单结束 -->
98+
99+
<script>
100+
// 动态增加链接输入框
101+
document.getElementById('addLinkButton').addEventListener('click', function() {
102+
var container = document.getElementById('linkInputsContainer');
103+
var newIndex = container.childElementCount - 1; // 减去非输入框元素的数量
104+
var newInput = document.createElement('input');
105+
newInput.type = 'text';
106+
newInput.className = 'form-control';
107+
newInput.id = `linkInput${newIndex}`;
108+
newInput.name = `linkInput${newIndex}`;
109+
newInput.placeholder = '请输入链接';
110+
111+
var removeButton = document.createElement('button');
112+
removeButton.type = 'button';
113+
removeButton.className = 'btn btn-secondary removeLinkButton';
114+
removeButton.textContent = '×';
115+
removeButton.dataset.index = newIndex.toString();
116+
removeButton.addEventListener('click', function() {
117+
var group = this.closest('.input-group');
118+
container.removeChild(group);
119+
});
120+
121+
var inputGroup = document.createElement('div');
122+
inputGroup.className = 'input-group mb-3';
123+
inputGroup.appendChild(newInput);
124+
inputGroup.appendChild(removeButton);
125+
126+
container.appendChild(inputGroup);
127+
});
128+
129+
// 动态增加元数据行
130+
document.getElementById('addMetadataRow').addEventListener('click', function() {
131+
var container = document.getElementById('metadataTableBody');
132+
var newRow = document.createElement('tr');
133+
134+
var nameInput = document.createElement('input');
135+
nameInput.type = 'text';
136+
nameInput.className = 'form-control';
137+
nameInput.name = 'name[]';
138+
nameInput.placeholder = '歌曲名称';
139+
140+
var artistInput = document.createElement('input');
141+
artistInput.type = 'text';
142+
artistInput.className = 'form-control';
143+
artistInput.name = 'artist[]';
144+
artistInput.placeholder = '艺术家';
145+
146+
var albumInput = document.createElement('input');
147+
albumInput.type = 'text';
148+
albumInput.className = 'form-control';
149+
albumInput.name = 'album[]';
150+
albumInput.placeholder = '专辑';
151+
152+
newRow.innerHTML = `
153+
<td>${nameInput.outerHTML}</td>
154+
<td>${artistInput.outerHTML}</td>
155+
<td>${albumInput.outerHTML}</td>
156+
`;
157+
158+
container.appendChild(newRow);
159+
});
160+
161+
document.getElementById('importForm').addEventListener('submit', async function(event) {
162+
// 阻止默认行为
163+
event.preventDefault();
164+
165+
// 获取表单值
166+
let text = document.getElementById('textInput').value;
167+
let links = [];
168+
let local = [];
169+
let playlistName = '';
170+
171+
// 获取所有链接输入框的值
172+
let linkInputs = document.querySelectorAll('#linkInputsContainer .input-group .form-control');
173+
linkInputs.forEach(function(input) {
174+
if (input.value.trim() !== '') {
175+
links.push(input.value);
176+
}
177+
});
178+
179+
// 获取元数据
180+
let metadataRows = document.querySelectorAll('#metadataTableBody tr');
181+
metadataRows.forEach(function(row) {
182+
let name = row.querySelector('input[name="name[]"]').value;
183+
let artist = row.querySelector('input[name="artist[]"]').value;
184+
let album = row.querySelector('input[name="album[]"]').value;
185+
if (name && artist && album) {
186+
local.push({ name, artist, album });
187+
}
188+
});
189+
190+
// 检查是否有且只有一个输入字段被填写
191+
let filledCount = (text ? 1 : 0) + (links.length > 0 ? 1 : 0) + (local.length > 0 ? 1 : 0);
192+
if (filledCount !== 1) {
193+
alert("请确保仅填写了一个输入字段!");
194+
return;
195+
}
196+
197+
// 获取歌单名
198+
if (document.getElementById('importStarCheckbox').checked) {
199+
playlistName = '我喜欢的音乐';
200+
} else {
201+
playlistName = document.getElementById('playlistNameInput').value ||
202+
document.getElementById('playlistNameLinkInput').value ||
203+
'导入音乐 ' + new Date().toLocaleString();
204+
}
205+
206+
// 创建请求参数
207+
let data = {};
208+
if (text) {
209+
data.text = text;
210+
data.playlistName = playlistName;
211+
} else if (links.length > 0) {
212+
data.link = JSON.stringify(links);
213+
data.playlistName = playlistName;
214+
} else if (local.length > 0) {
215+
data.local = JSON.stringify(local);
216+
}
217+
218+
// 添加额外参数
219+
if (document.getElementById('importStarCheckbox').checked) {
220+
data.importStarPlaylist = true;
221+
}
222+
223+
try {
224+
const res = await axios({
225+
url: `/playlist/import/name/task/create?timestamp=${Date.now()}`,
226+
method: 'post',
227+
data: data,
228+
});
229+
230+
let taskId = res.data?.data?.taskId
231+
if (taskId) {
232+
alert(`任务创建成功! 正在导入, 请稍等; 任务id:${taskId}`)
233+
// const res2 = await axios({
234+
// url: `/playlist/import/task/status?timestamp=${Date.now()}`,
235+
// method: 'post',
236+
// data: {
237+
// id: taskId
238+
// },
239+
// });
240+
// alert(JSON.stringify(res2.data, null, 2));
241+
}
242+
} catch (error) {
243+
console.error('Error:', error);
244+
alert('导入失败,请检查您的输入或稍后再试。');
245+
}
246+
});
247+
248+
// 监听复选框状态变化
249+
document.getElementById('importStarCheckbox').addEventListener('change', function() {
250+
let isChecked = this.checked;
251+
let playlistNameInputs = document.querySelectorAll('[name="playlistName"]');
252+
playlistNameInputs.forEach(function(input) {
253+
input.disabled = isChecked;
254+
});
255+
});
256+
257+
// 初始化时设置歌单名输入框的状态
258+
document.getElementById('importStarCheckbox').dispatchEvent(new Event('change'));
259+
</script>
260+
</div>
261+
</body>
262+
</html>

0 commit comments

Comments
 (0)