feat: 新增云小编接口

This commit is contained in:
Zxwy 2026-07-17 16:44:53 +08:00
parent 321c25bd7d
commit 5ae1eab14c
11 changed files with 446 additions and 1 deletions

View File

@ -0,0 +1,17 @@
// 云小编领取任务积分
//
// activityId:
// 调用 rep/ugc/activity/get 获取
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
activityId: query.activityId || '5001',
}
return request(
`/api/rep/ugc/activity/collect`,
data,
createOption(query, 'eapi'),
)
}

View File

@ -0,0 +1,7 @@
// 云小编活动信息
const createOption = require('../util/option.js')
module.exports = (query, request) => {
return request(`/api/rep/ugc/activity/get`, {}, createOption(query, 'eapi'))
}

View File

@ -0,0 +1,16 @@
// 云小编领取一日会员
//
// 注:前提条件见 rep/ugc/user/vip
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
activityId: query.activityId || '5001',
}
return request(
`/api/rep/ugc/user/collect-vip`,
data,
createOption(query, 'eapi'),
)
}

View File

@ -0,0 +1,7 @@
// 云小编获取用户详情
const createOption = require('../util/option.js')
module.exports = (query, request) => {
return request(`/api/rep/ugc/user/get`, {}, createOption(query, 'eapi'))
}

View File

@ -0,0 +1,7 @@
// 云小编每日签到
const createOption = require('../util/option.js')
module.exports = (query, request) => {
return request(`/api/rep/ugc/user/sign`, {}, createOption(query, 'eapi'))
}

View File

@ -0,0 +1,12 @@
// 云小编查询会员任务状态
//
// 状态 (data.status)
// 10: 用户积分达50可免费领取1日黑胶会员
// 20: 用户积分已达50可免费领取1日黑胶会员
// 30: 已领取1日黑胶会员明天再来吧~
const createOption = require('../util/option.js')
module.exports = (query, request) => {
return request(`/api/rep/ugc/user/vip`, {}, createOption(query, 'eapi'))
}

View File

@ -0,0 +1,20 @@
// 云小编获取任务
//
// type:
// 1: 歌曲曲风审核 musicalStyleEnter
// 2: 歌曲语种审核 languageEnter
// 3: 歌曲原唱审核 oriSingerEnter
// 4: 情绪标签审核 emotionEnter
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
type: query.type || '4',
}
return request(
`/api/thinktank/audit/resource/detail`,
data,
createOption(query, 'eapi'),
)
}

View File

@ -0,0 +1,36 @@
// 云小编提交任务
//
// type:
// 1: 歌曲曲风审核 musicalStyleEnter
// 2: 歌曲语种审核 languageEnter
// 3: 歌曲原唱审核 oriSingerEnter
// 4: 情绪标签审核 emotionEnter
//
// taskId:
// 调用 thinktank/audit/resource/detail 获取
//
// judgement:
// 1: 同意, 2: 否决, 3: 跳过 (不算次数)
const createOption = require('../util/option.js')
module.exports = (query, request) => {
if (!query.taskId || !query.judgement)
return Promise.reject({
status: 400,
body: {
code: 400,
message: '参数不足',
},
})
const data = {
type: query.type || '4',
taskId: query.taskId,
judgement: query.judgement,
}
return request(
`/api/thinktank/audit/resource/update`,
data,
createOption(query, 'eapi'),
)
}

View File

@ -5493,6 +5493,92 @@ let data = encodeURIComponent(
**调用例子 :** `/ad/listening/rights/gain`
### 云小编 - 获取用户详情
说明: 登录后调用此接口, 获取云小编用户详情
**接口地址:** `/rep/ugc/user/get`
**调用例子:** `/rep/ugc/user/get`
### 云小编 - 每日签到
说明: 登录后调用此接口, 进行云小编签到, 领取 5 积分, 签到后 `/rep/ugc/user/get` 返回 `data.signed = 1`
**接口地址:** `/rep/ugc/user/sign`
**调用例子:** `/rep/ugc/user/sign`
### 云小编 - 查询会员任务状态
说明: 登录后调用此接口, 查询云小编会员任务状态, 当 `data.status = 20` 时, 可调用 `/rep/ugc/user/collect-vip` 领取会员
**接口地址:** `/rep/ugc/user/vip`
**调用例子:** `/rep/ugc/user/vip`
### 云小编 - 活动信息
说明: 登录后调用此接口, 查询云小编会员活动信息
**接口地址:** `/rep/ugc/activity/get`
**调用例子:** `/rep/ugc/activity/get`
### 云小编 - 获取任务
> 注意: 调用前请先使用官方客户端完成云小编“情绪标签审核”入站考试
**可选参数:**
`type`: 任务类型, 1: 歌曲曲风审核, 2: 歌曲语种审核, 3: 歌曲原唱审核, 4: 情绪标签审核, 默认 `4`
**接口地址:** `/thinktank/audit/resource/detail`
**调用例子:** `/thinktank/audit/resource/detail?type=4`
### 云小编 - 提交任务
> 注意: 投票结果会在后台审核, 一致 +3 积分, 不一致 -2 积分
**可选参数:**
`type`: 任务类型, 1: 歌曲曲风审核, 2: 歌曲语种审核, 3: 歌曲原唱审核, 4: 情绪标签审核, 默认 `4`
**必选参数:**
`taskId`: 任务 ID, 调用 `/thinktank/audit/resource/detail` 获取 `data.taskId`
`judgement`: 审核结果, 1: 同意, 2: 否决, 3: 跳过 (不算次数)
**接口地址:** `/thinktank/audit/resource/update`
**调用例子:** `/thinktank/audit/resource/update?type=4&taskId=123456&judgement=1`
### 云小编 - 领取任务积分
说明: 完成任务后调用此接口, 领取云小编任务积分
**可选参数:**
`activityId`: 活动 ID, 调用 `/rep/ugc/activity/get` 获取, 默认 `5001`
**接口地址:** `/rep/ugc/activity/collect`
**调用例子:** `/rep/ugc/activity/collect?activityId=5001`
### 云小编 - 领取一日会员
说明: 达成领取条件 (`/rep/ugc/user/vip`) 后调用此接口, 领取一日会员
**可选参数:**
`activityId`: 活动 ID, 调用 `/rep/ugc/activity/get` 获取, 默认 `5001`
**接口地址:** `/rep/ugc/user/collect-vip`
**调用例子:** `/rep/ugc/user/collect-vip?activityId=5001`
## 离线访问此文档
此文档同时也是 Progressive Web Apps(PWA), 加入了 serviceWorker, 可离线访问

View File

@ -98,7 +98,8 @@ curl -s {origin}/search?keywords=网易云</code></pre>
<a href="/avatar_update.html">头像更新示例</a> ·
<a href="/scrobble.html">听歌打卡示例</a> ·
<a href="/yidun.html">获取 CheckToken</a> ·
<a href="/free_listen.html">免费听权益</a>
<a href="/free_listen.html">免费听权益</a> ·
<a href="/ugc.html">云小编任务中心</a>
</div>
</section>

236
public/ugc.html Normal file
View File

@ -0,0 +1,236 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="referrer" content="no-referrer" />
<title>云小编任务中心</title>
<link rel="shortcut icon" href="docs/favicon.ico" type="image/x-icon" />
<style>
.box {
margin-top: 20px;
border: 2px dashed red;
border-radius: 8px;
height: 50px;
display: flex;
align-items: center;
}
</style>
</head>
<body>
<h2>云小编任务中心</h2>
<button id="setCookie">设置本地令牌</button>
<button id="loadall">一键载入</button>
<h3>用户信息 <button id="userGet">获取用户详情</button></h3>
<div id="user" class="box">
<img src="docs/favicon.ico" alt="avatar" width="50" height="50" />
<span style="margin-left: 10px">未登录</span>
<button disabled style="margin-left: 10px">签到</button>
</div>
<h3>会员领取 <button id="vipGet">获取会员详情</button></h3>
<div id="vip" class="box">
<span>未载入</span>
<button disabled style="margin-left: 10px">领取</button>
</div>
<h3>审核任务 <button id="taskGet">获取任务详情</button></h3>
<div id="task" class="box">
[<span>0</span>/<span>0</span>] 审核歌曲赚贡献分 (+66)
<button disabled style="margin-left: 10px">去完成</button>
</div>
<div id="song">
<img src="docs/favicon.ico" alt="cover" width="100" height="100" />
<p>未载入</p>
<audio controls></audio>
<p>标签</p>
<button disabled>同意</button>
<button disabled>否决</button>
<button disabled>跳过 (不计次数)</button>
<p>[00:00.00]歌词</p>
</div>
<script>
(function () {
var k_cookie = 'ncm_cookie';
var cookie = localStorage.getItem(k_cookie) || '';
document.getElementById('setCookie').onclick = function () {
var ck = prompt('请填写 Cookie:', cookie);
if (ck !== null) {
cookie = ck;
localStorage.setItem(k_cookie, ck);
}
};
/**
* 发起请求
* @param {string} url
* @param {Record<string,string>} params
* @param {(resp:Record<string,any>)=>void} done
*/
function request(url, params, done) {
var xhr = new XMLHttpRequest();
xhr.responseType = 'json';
xhr.timeout = 1e4; // 10s
xhr.onload = function () {
var r = xhr.response;
if (r.code !== 200) alert(r.message ? '' + r.code + ': ' + r.message : r.code);
else done(r);
};
xhr.onerror = function () {
alert(xhr.statusText);
};
if (cookie) params.cookie = cookie;
var s = '?_=' + Date.now();
for (var k in params) {
s += '&' + k + '=' + encodeURIComponent(params[k]);
}
xhr.open('GET', url + s);
xhr.send();
}
/// 用户信息 ///
var user = document.getElementById('user');
var user_img = /**@type {HTMLImageElement} */ (user.children[0]);
var user_name = /**@type {HTMLSpanElement} */ (user.children[1]);
var user_sign = /**@type {HTMLButtonElement} */ (user.children[2]);
var user_load = document.getElementById('userGet');
user_load.onclick = function () {
request('rep/ugc/user/get', {}, function (res) {
var d = res.data;
if (d.imgUrl) user_img.src = d.imgUrl + '?param=50y50';
user_name.innerText = d.name || '游客' + d.id;
user_sign.disabled = d.signed;
});
};
user_sign.onclick = function () {
if (!user_sign.disabled)
request('rep/ugc/user/sign', {}, function (res) {
var d = res.data;
user_sign.disabled = d;
alert('签到' + (d ? '成功' : '失败'));
});
};
/// 会员领取 ///
var vip = document.getElementById('vip');
var vip_tip = vip.children[0];
var vip_btn = vip.children[1];
var vip_load = document.getElementById('vipGet');
vip_load.onclick = function () {
request('rep/ugc/user/vip', {}, function (res) {
var d = res.data;
vip_tip.innerText = '' + d.status + ': ' + d.title;
vip_btn.disabled = d.status !== 20;
});
};
vip_btn.onclick = function () {
if (!vip_btn.disabled)
request('rep/ugc/user/collect-vip', {}, function (res) {
var d = res.data;
vip_btn.disabled = d;
alert('领取' + (d ? '成功' : '失败'));
});
};
/// 审核任务 ///
var task = document.getElementById('task');
var task_a = task.children[0];
var task_b = task.children[1];
var task_btn = task.children[2];
var task_load = document.getElementById('taskGet');
task_load.onclick = function () {
request('rep/ugc/activity/get', {}, function (res) {
var d = res.data;
task_a.innerText = d.count;
task_b.innerText = d.goalCount;
task_btn.disabled = d.activityId !== 5001;
});
};
task_btn.onclick = function () {
if (!task_btn.disabled) taskStart();
};
var song = document.getElementById('song');
var song_img = song.children[0];
var song_title = song.children[1];
var song_mp3 = song.children[2];
var song_tag = song.children[3];
var song_btn1 = song.children[4];
var song_btn2 = song.children[5];
var song_btn3 = song.children[6];
var song_lyric = song.children[7];
/**
* 获取任务
*/
function taskStart() {
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) {
alert('积分领取' + (res.data ? '成功,可以兑换会员了!' : '失败'));
});
return;
}
song_img.src = d.coverUrl + '?param=100y100';
song_title.innerText = '[' + d.resId + '] ' + d.resName + ' - ' + d.artists;
song_tag.innerText =
'[' + (d.auditCount + 1) + '/' + d.auditTaskCount + '] ' + d.initResult + '';
song_lyric.innerText = (d.lyric || '') + (d.transLyric || '');
song_mp3.src = d.songUrl;
song_mp3.play();
song_btn1.onclick = function () {
if (!song_btn1.disabled) taskSubmit(d.taskId, '1');
};
song_btn2.onclick = function () {
if (!song_btn2.disabled) taskSubmit(d.taskId, '2');
};
song_btn3.onclick = function () {
if (!song_btn3.disabled) taskSubmit(d.taskId, '3');
};
setTimeout(function () {
song_btn1.disabled = song_btn2.disabled = song_btn3.disabled = false;
}, 3e3);
});
}
/**
* 提交任务
* @param {string} taskId
* @param {'1'|'2'|'3'} judgement
*/
function taskSubmit(taskId, judgement) {
song_btn1.disabled = song_btn2.disabled = song_btn3.disabled = true;
request(
'thinktank/audit/resource/update',
{ type: '4', taskId: taskId, judgement: judgement },
function (res) {
var d = res.data;
if (d.result) taskStart();
else alert('未知状态: ' + JSON.stringify(d));
},
);
}
document.getElementById('loadall').onclick = function () {
user_load.click();
vip_load.click();
task_load.click();
};
})();
</script>
</body>
</html>