mirror of
https://github.com/NeteaseCloudMusicApiEnhanced/api-enhanced.git
synced 2026-10-23 16:11:24 +08:00
feat: 新增云小编抽奖接口
This commit is contained in:
+195
-17
@@ -4,6 +4,8 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="referrer" content="no-referrer" />
|
||||
<link rel="icon" href="docs/netease.png" />
|
||||
<title>云小编任务中心 - 网易云音乐 API Enhanced</title>
|
||||
<style>
|
||||
* {
|
||||
@@ -325,6 +327,10 @@
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
#userPoint {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* ---- Song Review ---- */
|
||||
.song-review {
|
||||
margin-top: 16px;
|
||||
@@ -377,7 +383,7 @@
|
||||
border-radius: 6px;
|
||||
border: 1px solid #e5e7eb;
|
||||
white-space: pre-wrap;
|
||||
max-height: 120px;
|
||||
max-height: 160px;
|
||||
overflow-y: auto;
|
||||
font-family: monospace;
|
||||
line-height: 1.6;
|
||||
@@ -404,6 +410,8 @@
|
||||
<div class="quick-fill">
|
||||
<span onclick="loadLocalCookie()">读取本地 Cookie</span>
|
||||
<span onclick="clearCookie()">清除 Cookie</span>
|
||||
<span onclick="saveCookie()">保存 Cookie</span>
|
||||
<span onclick="loadAll()">一键载入</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -413,8 +421,9 @@
|
||||
<button class="btn-sm" id="userGet">获取用户详情</button>
|
||||
</div>
|
||||
<div class="info-card" id="user">
|
||||
<img alt="头像" class="avatar" id="userAvatar" />
|
||||
<img src="docs/netease.png" alt="头像" class="avatar" id="userAvatar" />
|
||||
<span class="info-text" id="userName">未登录</span>
|
||||
<span id="userPoint">0</span>
|
||||
<button class="btn-sm green" id="userSign" disabled>签到</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -436,7 +445,7 @@
|
||||
<button class="btn-sm" id="taskGet">获取任务详情</button>
|
||||
</div>
|
||||
<div class="info-card" id="task">
|
||||
<span class="info-text" id="taskInfo">[<span id="taskCount">0</span>/<span id="taskGoal">0</span>] 审核歌曲赚贡献分 (+66)</span>
|
||||
<span class="info-text" id="taskInfo">[<span id="taskCount">0</span>/<span id="taskGoal">0</span>] 审核歌曲赚贡献分 (+<span id="taskPoint">0</span>)</span>
|
||||
<button class="btn-sm" id="taskStart" disabled>去完成</button>
|
||||
</div>
|
||||
|
||||
@@ -462,7 +471,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://fastly.jsdelivr.net/npm/[email protected]/dist/axios.min.js"></script>
|
||||
<script>
|
||||
(function () {
|
||||
var k_cookie = 'ncm_cookie';
|
||||
@@ -496,6 +504,12 @@
|
||||
showResult('已清除本地 Cookie', 'info');
|
||||
};
|
||||
|
||||
window.saveCookie = function () {
|
||||
var ck = getCookie()
|
||||
if (ck) localStorage.setItem(k_cookie, ck)
|
||||
showResult('已保存本地 Cookie', 'info');
|
||||
}
|
||||
|
||||
/* ---- Result ---- */
|
||||
function hideResult() {
|
||||
resultDiv.style.display = 'none';
|
||||
@@ -547,6 +561,7 @@
|
||||
/// 用户信息 ///
|
||||
var userAvatar = document.getElementById('userAvatar');
|
||||
var userName = document.getElementById('userName');
|
||||
var userPoint = document.getElementById('userPoint');
|
||||
var userSign = document.getElementById('userSign');
|
||||
var userGet = document.getElementById('userGet');
|
||||
|
||||
@@ -555,6 +570,7 @@
|
||||
var d = res.data;
|
||||
if (d.imgUrl) userAvatar.src = d.imgUrl + '?param=50y50';
|
||||
userName.textContent = d.name || '游客' + d.id;
|
||||
userPoint.textContent = d.availablePoints;
|
||||
userSign.disabled = d.signed;
|
||||
showResult('用户信息加载成功', 'success');
|
||||
});
|
||||
@@ -567,6 +583,7 @@
|
||||
var d = res.data;
|
||||
userSign.disabled = d;
|
||||
showResult('签到' + (d ? '成功 ✓' : '失败 ✗'), d ? 'success' : 'error');
|
||||
if (d) userGet.click();
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -599,21 +616,36 @@
|
||||
/// 审核任务 ///
|
||||
var taskCount = document.getElementById('taskCount');
|
||||
var taskGoal = document.getElementById('taskGoal');
|
||||
var taskPoint = document.getElementById('taskPoint');
|
||||
var taskStartBtn = document.getElementById('taskStart');
|
||||
var taskGetBtn = document.getElementById('taskGet');
|
||||
|
||||
taskGetBtn.onclick = function () {
|
||||
request('/rep/ugc/activity/get', {}, function (res) {
|
||||
request('rep/ugc/activity/get', {}, function (res) {
|
||||
var d = res.data;
|
||||
taskCount.textContent = d.count;
|
||||
taskGoal.textContent = d.goalCount;
|
||||
taskStartBtn.disabled = d.activityId !== 5001;
|
||||
taskPoint.textContent = d.points;
|
||||
// 注:超过 100 可能有 bug,导致 thinktank/audit/resource/detail 获取的任务 ID 一直是 5002,目标数量也不对,暂时限制前两个任务
|
||||
taskStartBtn.disabled = d.activityId !== 5001 && d.activityId !== 5002; // 5001: 1-50, 5002: 51-100
|
||||
showResult('任务详情加载成功', 'success');
|
||||
// 任务完成,领取积分
|
||||
if (d.count >= d.goalCount) {
|
||||
request('rep/ugc/activity/collect', { activityId: d.activityId }, function (res) {
|
||||
var d = res.data;
|
||||
showResult('积分领取' + (d ? '成功,可以兑换会员了!' : '失败'), d ? 'success' : 'error');
|
||||
// 刷新任务状态
|
||||
if (d) loadAll();
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
taskStartBtn.onclick = function () {
|
||||
if (!taskStartBtn.disabled) taskStart();
|
||||
if (!taskStartBtn.disabled) {
|
||||
songAudio.pause();
|
||||
examInit();
|
||||
}
|
||||
};
|
||||
|
||||
/// 歌曲审核区域 ///
|
||||
@@ -627,26 +659,113 @@
|
||||
var songSkip = document.getElementById('songSkip');
|
||||
var songLyric = document.getElementById('songLyric');
|
||||
|
||||
var examType = 'emotionEnter';
|
||||
// 考试初始化、检查状态
|
||||
function examInit() {
|
||||
request('rep/ugc/exam/info/get', { examType: examType }, function (res) {
|
||||
var d = res.data;
|
||||
switch (d.process) {
|
||||
case 'whole_exam_end':
|
||||
// 通过考试
|
||||
if (d.hasPassExamination) {
|
||||
taskStart();
|
||||
return;
|
||||
}
|
||||
request('rep/ugc/exam/result/get', { examType: examType, taskId: d.taskId }, function (res) {
|
||||
var d = res.data;
|
||||
showResult('考试未通过:正确数:' + d.wrightNum + ',正确率:' + d.wrightRate, 'error');
|
||||
});
|
||||
case 'no':
|
||||
// 未通过或未开始
|
||||
request('rep/ugc/exam/start', { examType: examType }, function (res) {
|
||||
examStart(res.data.taskId);
|
||||
});
|
||||
break;
|
||||
case 'process':
|
||||
// 正在考试
|
||||
examStart(d.taskId);
|
||||
break;
|
||||
default:
|
||||
showResult('未知考试进度:' + d.process, 'error');
|
||||
return;
|
||||
}
|
||||
// 在上个信息不为异常时显示考试中提示
|
||||
if (d.process !== 'whole_exam_end' && !resultDiv.className.endsWith('error')) showResult('正在考试,请认真审题!', 'info');
|
||||
});
|
||||
}
|
||||
// 考试取题开始
|
||||
function examStart(taskId) {
|
||||
request('rep/ugc/exam/question/single/get', { examType: examType, taskId: taskId }, function (res) {
|
||||
var d = res.data;
|
||||
|
||||
songCover.src = d.coverUrl + '?param=100y100';
|
||||
songTitle.textContent = '[' + d.resId + '] ' + d.resName + ' - ' + d.artists;
|
||||
songTag.textContent = '[' + (d.auditCount + 1) + '/' + d.auditTaskCount + '] 当前结果: ' + d.questionContent + '?';
|
||||
songLyric.textContent = d.lyric ? d.transLyric ? lrctran(d.lyric, d.transLyric) : d.lyric : '[00:00.00] 暂无歌词';
|
||||
songLyric.scrollTop = 0;
|
||||
// 有时候就是没有播放链接,只能根据歌词硬审
|
||||
if (d.songUrl) {
|
||||
songAudio.src = d.songUrl;
|
||||
songAudio.play().catch(function () { /* 自动播放被浏览器阻止 */ });
|
||||
} else {
|
||||
songAudio.src = ''; // 清理播放器
|
||||
}
|
||||
songApprove.onclick = function () { if (!songApprove.disabled) examSubmit(taskId, d.questionId, 'A') };
|
||||
songReject.onclick = function () { if (!songReject.disabled) examSubmit(taskId, d.questionId, 'B') };
|
||||
songSkip.onclick = null;
|
||||
|
||||
songApprove.disabled = songReject.disabled = songSkip.disabled = true;
|
||||
song.style.display = 'block';
|
||||
|
||||
setTimeout(function () {
|
||||
songApprove.disabled = songReject.disabled = false;
|
||||
}, 3e3);
|
||||
});
|
||||
}
|
||||
// 考试提交
|
||||
function examSubmit(taskId, questionId, answer) {
|
||||
songAudio.pause();
|
||||
songApprove.disabled = songReject.disabled = songSkip.disabled = true;
|
||||
request(
|
||||
'rep/ugc/exam/submit',
|
||||
{ examType: examType, taskId: taskId, questionId: questionId, answer: answer },
|
||||
function (res) {
|
||||
var d = res.data;
|
||||
if (d.result) {
|
||||
showResult('回答正确,加载下一首...', 'success');
|
||||
} else {
|
||||
showResult('回答错误:' + d.analysis, 'error');
|
||||
}
|
||||
examInit();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取任务
|
||||
*/
|
||||
function taskStart() {
|
||||
song.style.display = 'none';
|
||||
request('/thinktank/audit/resource/detail', { type: '4' }, function (res) {
|
||||
request('thinktank/audit/resource/detail', { type: '4' }, function (res) {
|
||||
var d = res.data;
|
||||
|
||||
if (d.auditCount >= 50) {
|
||||
request('rep/ugc/activity/collect', { activityId: '5001' }, function (res) {
|
||||
showResult('积分领取' + (res.data ? '成功,可以兑换会员了!' : '失败'), res.data ? 'success' : 'error');
|
||||
});
|
||||
if (d.auditCount >= Number(taskGoal.textContent)) {
|
||||
showResult('当前阶段任务已完成', 'success');
|
||||
song.style.display = 'none';
|
||||
taskGetBtn.click();
|
||||
return;
|
||||
}
|
||||
// 没有链接,直接跳过
|
||||
if (!d.songUrl) {
|
||||
showResult('未返回播放链接,3 秒后自动跳过', 'info');
|
||||
setTimeout(function () { taskSubmit(d.taskId, '3') }, 3e3);
|
||||
return;
|
||||
}
|
||||
|
||||
songCover.src = d.coverUrl + '?param=100y100';
|
||||
songTitle.textContent = '[' + d.resId + '] ' + d.resName + ' - ' + d.artists;
|
||||
songTag.textContent = '[' + (d.auditCount + 1) + '/' + d.auditTaskCount + '] 当前结果: ' + d.initResult + '?';
|
||||
songLyric.textContent = (d.lyric || '') + (d.transLyric || '');
|
||||
if (!songLyric.textContent.trim()) songLyric.textContent = '[00:00.00] 暂无歌词';
|
||||
songLyric.textContent = d.lyric ? d.transLyric ? lrctran(d.lyric, d.transLyric) : d.lyric : '[00:00.00] 暂无歌词';
|
||||
songLyric.scrollTop = 0;
|
||||
songAudio.src = d.songUrl;
|
||||
songAudio.play().catch(function () { /* 自动播放被浏览器阻止 */ });
|
||||
|
||||
@@ -669,6 +788,7 @@
|
||||
* @param {'1'|'2'|'3'} judgement
|
||||
*/
|
||||
function taskSubmit(taskId, judgement) {
|
||||
songAudio.pause();
|
||||
songApprove.disabled = songReject.disabled = songSkip.disabled = true;
|
||||
request(
|
||||
'thinktank/audit/resource/update',
|
||||
@@ -676,7 +796,10 @@
|
||||
function (res) {
|
||||
var d = res.data;
|
||||
if (d.result) {
|
||||
showResult('审核提交成功,加载下一首...', 'success');
|
||||
showResult((d.test ? '抽查' : '审核') + '提交成功,加载下一首...', 'success');
|
||||
taskStart();
|
||||
} else if (d.test) {
|
||||
showResult('抽查失败: [' + d.dayErrorNum + '/' + d.dayErrorNumStandard + '] ' + d.errorAnalysis, 'error');
|
||||
taskStart();
|
||||
} else {
|
||||
showResult('未知状态: ' + JSON.stringify(d), 'error');
|
||||
@@ -685,8 +808,63 @@
|
||||
);
|
||||
}
|
||||
|
||||
/**解析歌词时间戳和文本 */
|
||||
function lrctrim(lyrics) {
|
||||
var lines = lyrics.split('\n');
|
||||
var data = [];
|
||||
lines.forEach(function (line, index) {
|
||||
var matches = line.match(/\[(\d{2}):(\d{2}[\.:]?\d*)\]/);
|
||||
if (matches) {
|
||||
var minutes = parseInt(matches[1], 10);
|
||||
var seconds = parseFloat(matches[2].replace('.', ':')) || 0;
|
||||
var timestamp = minutes * 6e4 + seconds * 1e3;
|
||||
var text = line.replace(/\[\d{2}:\d{2}[\.:]?\d*\]/g, '').trim();
|
||||
text = text.replace(/\s\s+/g, ' '); // Replace multiple spaces with a single space
|
||||
data.push([timestamp, index, text]);
|
||||
}
|
||||
});
|
||||
data.sort(function (a, b) {
|
||||
return a[0] - b[0];
|
||||
});
|
||||
return data;
|
||||
}
|
||||
/**合并原文歌词和翻译歌词 */
|
||||
function lrctran(lyric, tlyric) {
|
||||
lyric = lrctrim(lyric);
|
||||
tlyric = lrctrim(tlyric);
|
||||
var len1 = lyric.length;
|
||||
var len2 = tlyric.length;
|
||||
var result = '';
|
||||
for (var i = 0, j = 0; i < len1 && j < len2; i++) {
|
||||
while (lyric[i][0] > tlyric[j][0] && j + 1 < len2) {
|
||||
j++;
|
||||
}
|
||||
if (lyric[i][0] === tlyric[j][0]) {
|
||||
tlyric[j][2] = tlyric[j][2].replace('/', '');
|
||||
if (tlyric[j][2]) {
|
||||
lyric[i][2] += ' (' + tlyric[j][2] + ')';
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
for (var k = 0; k < len1; k++) {
|
||||
var t = lyric[k][0];
|
||||
result += '['.concat(
|
||||
String(Math.floor(t / 6e4)).padStart(2, '0'),
|
||||
':',
|
||||
String(Math.floor((t % 6e4) / 1e3)).padStart(2, '0'),
|
||||
'.',
|
||||
String(t % 1e3).padStart(3, '0'),
|
||||
']',
|
||||
lyric[k][2],
|
||||
'\n',
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// 一键载入 ///
|
||||
document.getElementById('loadall').onclick = function () {
|
||||
window.loadAll = function () {
|
||||
userGet.click();
|
||||
vipGet.click();
|
||||
taskGetBtn.click();
|
||||
|
||||
Reference in New Issue
Block a user