mirror of
https://github.com/NeteaseCloudMusicApiEnhanced/api-enhanced.git
synced 2026-10-20 22:51:23 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7822ab08d3 | ||
|
|
41bd6d82ce | ||
|
|
6f8dd1d971 | ||
|
|
ddd0af5474 | ||
|
|
fbd2e06419 | ||
|
|
35d1c61cb4 | ||
|
|
a183e153ef | ||
|
|
2fa78c3826 | ||
|
|
5ae1eab14c | ||
|
|
321c25bd7d | ||
|
|
f527c1ef73 |
+3
-10
@@ -1,11 +1,5 @@
|
|||||||
// 获取广告
|
// 获取广告
|
||||||
// 基于逆向网易云音乐 v9.5.45 RN Hermes 源码:
|
|
||||||
// - adService.getAd() → Network.nativeRequest → /api/ad/get
|
|
||||||
// - 需要 X-antiCheatToken 易盾反作弊头
|
|
||||||
// - 使用 xeapi 加密
|
|
||||||
//
|
|
||||||
// 返回 extra.reqId 可用于 ad_listening_rights_gain 的 reqUid
|
|
||||||
//
|
|
||||||
const createOption = require('../util/option.js')
|
const createOption = require('../util/option.js')
|
||||||
|
|
||||||
module.exports = async (query, request) => {
|
module.exports = async (query, request) => {
|
||||||
@@ -13,13 +7,12 @@ module.exports = async (query, request) => {
|
|||||||
type_ids: query.type_ids || '["400002_0"]',
|
type_ids: query.type_ids || '["400002_0"]',
|
||||||
}
|
}
|
||||||
|
|
||||||
const option = createOption(query, 'xeapi')
|
const option = createOption(query, 'xeapi', 'v3')
|
||||||
option.checkToken = true
|
|
||||||
|
|
||||||
const res = await request(`/api/ad/get`, data, option)
|
const res = await request(`/api/ad/get`, data, option)
|
||||||
const raw = res.body
|
const raw = res.body
|
||||||
|
|
||||||
// 提取广告中的 req_id (用于领取权益)
|
// 提取广告中的 req_id
|
||||||
let reqId = ''
|
let reqId = ''
|
||||||
try {
|
try {
|
||||||
if (raw?.ads) {
|
if (raw?.ads) {
|
||||||
|
|||||||
@@ -72,11 +72,11 @@ module.exports = async (query, request) => {
|
|||||||
reqParam: JSON.stringify(rightsParam),
|
reqParam: JSON.stringify(rightsParam),
|
||||||
}
|
}
|
||||||
|
|
||||||
const option = createOption(query, 'xeapi')
|
const res = await request(
|
||||||
// 关键: 开启 X-antiCheatToken 头
|
`/api/ad/listening/rights/gain`,
|
||||||
option.checkToken = true
|
data,
|
||||||
|
createOption(query, 'xeapi', 'v3'),
|
||||||
const res = await request(`/api/ad/listening/rights/gain`, data, option)
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
status: 200,
|
status: 200,
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
// 发送安全验证码
|
||||||
|
|
||||||
|
const createOption = require('../util/option.js')
|
||||||
|
module.exports = (query, request) => {
|
||||||
|
const data = {
|
||||||
|
ctcode: query.ctcode || '86',
|
||||||
|
}
|
||||||
|
return request(
|
||||||
|
`/api/sms/captcha/safe/sent`,
|
||||||
|
data,
|
||||||
|
createOption(query, 'eapi'),
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
// 发送验证码
|
||||||
|
|
||||||
|
const createOption = require('../util/option.js')
|
||||||
|
module.exports = (query, request) => {
|
||||||
|
const data = {
|
||||||
|
ctcode: query.ctcode || '86',
|
||||||
|
secrete: 'music_middleuser_pclogin',
|
||||||
|
cellphone: query.phone,
|
||||||
|
scene: '0',
|
||||||
|
}
|
||||||
|
return request(
|
||||||
|
`/api/middle/captcha/sent/v1`,
|
||||||
|
data,
|
||||||
|
createOption(query, 'eapi'),
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -6,5 +6,9 @@ module.exports = (query, request) => {
|
|||||||
cellphone: query.phone,
|
cellphone: query.phone,
|
||||||
countrycode: query.countrycode,
|
countrycode: query.countrycode,
|
||||||
}
|
}
|
||||||
return request(`/api/cellphone/existence/check`, data, createOption(query))
|
return request(
|
||||||
|
`/api/cellphone/existence/check`,
|
||||||
|
data,
|
||||||
|
createOption(query, 'eapi'),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -25,6 +25,6 @@ module.exports = (query, request) => {
|
|||||||
return request(
|
return request(
|
||||||
`/api/resource/comments/${query.t}`,
|
`/api/resource/comments/${query.t}`,
|
||||||
data,
|
data,
|
||||||
createOption(query, 'weapi'),
|
createOption(query, 'eapi', 'v2'),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
const { resourceTypeMap } = require('../util/config.json')
|
||||||
|
// 发送评论
|
||||||
|
|
||||||
|
const createOption = require('../util/option.js')
|
||||||
|
module.exports = (query, request) => {
|
||||||
|
const data = {
|
||||||
|
threadId: resourceTypeMap[query.type] + query.id,
|
||||||
|
content: query.content,
|
||||||
|
resourceType: '0',
|
||||||
|
expressionPicId: '-1',
|
||||||
|
bubbleId: '-1',
|
||||||
|
}
|
||||||
|
return request(
|
||||||
|
`/api/resource/comments/add`,
|
||||||
|
data,
|
||||||
|
createOption(query, 'xeapi', 'v3'),
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
const { resourceTypeMap } = require('../util/config.json')
|
||||||
|
// 删除评论
|
||||||
|
|
||||||
|
const createOption = require('../util/option.js')
|
||||||
|
module.exports = (query, request) => {
|
||||||
|
const data = {
|
||||||
|
commentId: query.cid,
|
||||||
|
threadId: resourceTypeMap[query.type] + query.id,
|
||||||
|
}
|
||||||
|
return request(
|
||||||
|
`/api/resource/comments/delete`,
|
||||||
|
data,
|
||||||
|
createOption(query, 'xeapi'),
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
const { resourceTypeMap } = require('../util/config.json')
|
||||||
|
// 发送评论
|
||||||
|
|
||||||
|
const createOption = require('../util/option.js')
|
||||||
|
module.exports = (query, request) => {
|
||||||
|
const data = {
|
||||||
|
threadId: resourceTypeMap[query.type] + query.id,
|
||||||
|
commentId: query.cid,
|
||||||
|
content: query.content,
|
||||||
|
resourceType: '0',
|
||||||
|
}
|
||||||
|
return request(
|
||||||
|
`/api/v1/resource/comments/reply`,
|
||||||
|
data,
|
||||||
|
createOption(query, 'xeapi', 'v3'),
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
// 强制下线设备
|
||||||
|
|
||||||
|
const createOption = require('../util/option.js')
|
||||||
|
module.exports = (query, request) => {
|
||||||
|
const data = {
|
||||||
|
key: query.deviceKey,
|
||||||
|
captcha: query.captcha || '',
|
||||||
|
}
|
||||||
|
return request(
|
||||||
|
`/api/middle/user/security/device/kickoff`,
|
||||||
|
data,
|
||||||
|
createOption(query, 'eapi'),
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
// 登录设备列表
|
||||||
|
|
||||||
|
const createOption = require('../util/option.js')
|
||||||
|
module.exports = (query, request) => {
|
||||||
|
const data = {
|
||||||
|
excStatus: '9',
|
||||||
|
}
|
||||||
|
return request(
|
||||||
|
`/api/middle/user/device/list`,
|
||||||
|
data,
|
||||||
|
createOption(query, 'eapi'),
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ module.exports = async (query, request) => {
|
|||||||
? query.captcha
|
? query.captcha
|
||||||
: query.md5_password || CryptoJS.MD5(query.password).toString(),
|
: query.md5_password || CryptoJS.MD5(query.password).toString(),
|
||||||
remember: 'true',
|
remember: 'true',
|
||||||
|
secureCaptcha: query.sca || '',
|
||||||
}
|
}
|
||||||
let result = await request(
|
let result = await request(
|
||||||
`/api/w/login/cellphone`,
|
`/api/w/login/cellphone`,
|
||||||
|
|||||||
@@ -9,6 +9,6 @@ module.exports = (query, request) => {
|
|||||||
? { checkToken: query.checkToken || APP_CONF.checkToken }
|
? { checkToken: query.checkToken || APP_CONF.checkToken }
|
||||||
: {}),
|
: {}),
|
||||||
}
|
}
|
||||||
query.checkToken = true // 强制开启checkToken
|
query.checkToken = 'v2' // 强制开启checkToken
|
||||||
return request(`/api/playlist/${path}`, data, createOption(query, 'eapi'))
|
return request(`/api/playlist/${path}`, data, createOption(query, 'eapi'))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
// 易盾反作弊 Token 注册端点
|
||||||
|
// 调用后获取实时 token 并存入共享存储,供后续带 checkToken 的请求使用
|
||||||
|
//
|
||||||
|
// GET /register/checktoken → 返回当前 token(尚无则自动获取)
|
||||||
|
// POST /register/checktoken → 强制刷新 token
|
||||||
|
// GET /register/checktoken?refresh=1 → 强制刷新
|
||||||
|
//
|
||||||
|
const { default: axios } = require('axios')
|
||||||
|
const { APP_CONF } = require('../util/config.json')
|
||||||
|
|
||||||
|
const URL = APP_CONF.dunDomainV2 + '/v2/config/js?pn=YD00000558929251'
|
||||||
|
let _token = ''
|
||||||
|
|
||||||
|
async function fetch() {
|
||||||
|
const res = await axios.get(URL, { timeout: 10000 })
|
||||||
|
const data = res.data
|
||||||
|
if (data && data.code === 200 && data.result && data.result.conf) {
|
||||||
|
return data.result.conf
|
||||||
|
}
|
||||||
|
throw new Error('易盾返回异常: ' + JSON.stringify(data).substring(0, 200))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 端点处理
|
||||||
|
module.exports = async (query) => {
|
||||||
|
const refresh = query.refresh === '1' || query.refresh === 'true'
|
||||||
|
let token = refresh ? null : _token
|
||||||
|
if (!token) {
|
||||||
|
token = await fetch()
|
||||||
|
_token = token
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
status: 200,
|
||||||
|
body: { code: 200, token, registered: !!token },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 给 request.js 读取用
|
||||||
|
module.exports.getToken = () => _token
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
const { default: axios } = require('axios')
|
const { default: axios } = require('axios')
|
||||||
const { APP_CONF } = require('../util/config.json')
|
const { APP_CONF } = require('../util/config.json')
|
||||||
|
|
||||||
const URL = APP_CONF.dunDomain + '/v3/b?pn=YD00000558929251'
|
const URL = APP_CONF.dunDomainV3 + '/v3/b?pn=YD00000558929251'
|
||||||
let _token = ''
|
let _token = ''
|
||||||
|
|
||||||
async function fetch() {
|
async function fetch() {
|
||||||
@@ -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'),
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// 云小编活动信息
|
||||||
|
|
||||||
|
const createOption = require('../util/option.js')
|
||||||
|
|
||||||
|
module.exports = (query, request) => {
|
||||||
|
return request(`/api/rep/ugc/activity/get`, {}, createOption(query, 'eapi'))
|
||||||
|
}
|
||||||
@@ -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'),
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// 云小编获取用户详情
|
||||||
|
|
||||||
|
const createOption = require('../util/option.js')
|
||||||
|
|
||||||
|
module.exports = (query, request) => {
|
||||||
|
return request(`/api/rep/ugc/user/get`, {}, createOption(query, 'eapi'))
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// 云小编每日签到
|
||||||
|
|
||||||
|
const createOption = require('../util/option.js')
|
||||||
|
|
||||||
|
module.exports = (query, request) => {
|
||||||
|
return request(`/api/rep/ugc/user/sign`, {}, createOption(query, 'eapi'))
|
||||||
|
}
|
||||||
@@ -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'))
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
// 此版本不再采用 br 作为音质区分的标准
|
// 此版本不再采用 br 作为音质区分的标准
|
||||||
// 而是采用 standard, exhigh, lossless, hires, jyeffect(高清环绕声), sky(沉浸环绕声), jymaster(超清母带) 进行音质判断
|
// 而是采用 standard, exhigh, lossless, hires, jyeffect(高清环绕声), sky(沉浸环绕声), jymaster(超清母带) 进行音质判断
|
||||||
// 当unblock为true时, 会尝试使用unblockmusic-utils进行解锁, 同时音质设置不会生效, 但仍然为必须传入参数
|
// 当unblock为true时, 会尝试使用unblockmusic-utils进行解锁, 同时音质设置不会生效, 但仍然为必须传入参数
|
||||||
|
// 当level为sky时, 可通过 immerseType 选择沉浸声类型, 支持 c51(c51类型)、ste(环绕立体声类型)、aac(aac类型), 默认为 c51
|
||||||
|
|
||||||
const logger = require('../util/logger.js')
|
const logger = require('../util/logger.js')
|
||||||
const createOption = require('../util/option.js')
|
const createOption = require('../util/option.js')
|
||||||
@@ -51,7 +52,7 @@ module.exports = async (query, request) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (data.level == 'sky') {
|
if (data.level == 'sky') {
|
||||||
data.immerseType = 'c51'
|
data.immerseType = query.immerseType || 'c51'
|
||||||
}
|
}
|
||||||
return request(
|
return request(
|
||||||
`/api/song/enhance/player/url/v1`,
|
`/api/song/enhance/player/url/v1`,
|
||||||
|
|||||||
@@ -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'),
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -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'),
|
||||||
|
)
|
||||||
|
}
|
||||||
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@neteasecloudmusicapienhanced/api",
|
"name": "@neteasecloudmusicapienhanced/api",
|
||||||
"version": "4.37.0",
|
"version": "4.38.0",
|
||||||
"description": "全网最全的网易云音乐API接口 || A revival project for NeteaseCloudMusicApi Node.js Services (Half Refactor & Enhanced) || 网易云音乐 API 备份 + 增强 || 本项目自原版v4.28.0版本后开始自行维护",
|
"description": "全网最全的网易云音乐API接口 || A revival project for NeteaseCloudMusicApi Node.js Services (Half Refactor & Enhanced) || 网易云音乐 API 备份 + 增强 || 本项目自原版v4.28.0版本后开始自行维护",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "nodemon app.js",
|
"dev": "nodemon app.js",
|
||||||
@@ -98,8 +98,8 @@
|
|||||||
"@types/express-fileupload": "^1.5.1",
|
"@types/express-fileupload": "^1.5.1",
|
||||||
"@types/mocha": "^10.0.10",
|
"@types/mocha": "^10.0.10",
|
||||||
"@types/node": "25.9.2",
|
"@types/node": "25.9.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.64.0",
|
"@typescript-eslint/eslint-plugin": "^8.65.0",
|
||||||
"@typescript-eslint/parser": "^8.64.0",
|
"@typescript-eslint/parser": "^8.65.0",
|
||||||
"eslint": "^9.39.5",
|
"eslint": "^9.39.5",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-html": "^8.1.4",
|
"eslint-plugin-html": "^8.1.4",
|
||||||
@@ -112,7 +112,7 @@
|
|||||||
"nodemon": "^3.1.14",
|
"nodemon": "^3.1.14",
|
||||||
"pkg": "^5.8.1",
|
"pkg": "^5.8.1",
|
||||||
"power-assert": "^1.6.1",
|
"power-assert": "^1.6.1",
|
||||||
"prettier": "^3.9.5",
|
"prettier": "^3.9.6",
|
||||||
"typescript": "^5.9.3"
|
"typescript": "^5.9.3"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
|
|||||||
Generated
+79
-84
@@ -73,11 +73,11 @@ importers:
|
|||||||
specifier: 25.9.2
|
specifier: 25.9.2
|
||||||
version: 25.9.2
|
version: 25.9.2
|
||||||
'@typescript-eslint/eslint-plugin':
|
'@typescript-eslint/eslint-plugin':
|
||||||
specifier: ^8.64.0
|
specifier: ^8.65.0
|
||||||
version: 8.64.0(@typescript-eslint/parser@8.64.0(eslint@9.39.5)(typescript@5.9.3))(eslint@9.39.5)(typescript@5.9.3)
|
version: 8.65.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5)(typescript@5.9.3))(eslint@9.39.5)(typescript@5.9.3)
|
||||||
'@typescript-eslint/parser':
|
'@typescript-eslint/parser':
|
||||||
specifier: ^8.64.0
|
specifier: ^8.65.0
|
||||||
version: 8.64.0(eslint@9.39.5)(typescript@5.9.3)
|
version: 8.65.0(eslint@9.39.5)(typescript@5.9.3)
|
||||||
eslint:
|
eslint:
|
||||||
specifier: ^9.39.5
|
specifier: ^9.39.5
|
||||||
version: 9.39.5
|
version: 9.39.5
|
||||||
@@ -89,7 +89,7 @@ importers:
|
|||||||
version: 8.1.4
|
version: 8.1.4
|
||||||
eslint-plugin-prettier:
|
eslint-plugin-prettier:
|
||||||
specifier: ^5.5.6
|
specifier: ^5.5.6
|
||||||
version: 5.5.6(eslint-config-prettier@10.1.8(eslint@9.39.5))(eslint@9.39.5)(prettier@3.9.5)
|
version: 5.5.6(eslint-config-prettier@10.1.8(eslint@9.39.5))(eslint@9.39.5)(prettier@3.9.6)
|
||||||
globals:
|
globals:
|
||||||
specifier: ^17.7.0
|
specifier: ^17.7.0
|
||||||
version: 17.7.0
|
version: 17.7.0
|
||||||
@@ -115,8 +115,8 @@ importers:
|
|||||||
specifier: ^1.6.1
|
specifier: ^1.6.1
|
||||||
version: 1.6.1
|
version: 1.6.1
|
||||||
prettier:
|
prettier:
|
||||||
specifier: ^3.9.5
|
specifier: ^3.9.6
|
||||||
version: 3.9.5
|
version: 3.9.6
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ^5.9.3
|
specifier: ^5.9.3
|
||||||
version: 5.9.3
|
version: 5.9.3
|
||||||
@@ -147,9 +147,9 @@ packages:
|
|||||||
'@borewit/text-codec@0.2.2':
|
'@borewit/text-codec@0.2.2':
|
||||||
resolution: {integrity: sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==}
|
resolution: {integrity: sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==}
|
||||||
|
|
||||||
'@eslint-community/eslint-utils@4.9.1':
|
'@eslint-community/eslint-utils@4.10.0':
|
||||||
resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==}
|
resolution: {integrity: sha512-rd6n9Sefya1R1Vd594TRwzeHq2VnmICbvh3jebyt1Hs/6OoCSYNVpjGRRsKSTwAq3SKl09w0AfRCU57hoDLmxg==}
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
|
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
|
||||||
|
|
||||||
@@ -301,63 +301,63 @@ packages:
|
|||||||
'@types/serve-static@2.2.0':
|
'@types/serve-static@2.2.0':
|
||||||
resolution: {integrity: sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==}
|
resolution: {integrity: sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==}
|
||||||
|
|
||||||
'@typescript-eslint/eslint-plugin@8.64.0':
|
'@typescript-eslint/eslint-plugin@8.65.0':
|
||||||
resolution: {integrity: sha512-CGvQPBxN3wZLu6Rz2kFUpZeoCm78xUic92ck39KPePkO1NPOwjCqdQnm5Q87tpWw9vcBvW8XLrDXjH9PWYtJ3Q==}
|
resolution: {integrity: sha512-IEgob78X12rHpUmtcwFsXhZdVGJtwTVP8FiCLZkR6GlYVrl2PcuB+KhCE5BlVC/eQpQnu8WXRtkHZuPar+gCRA==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@typescript-eslint/parser': ^8.64.0
|
'@typescript-eslint/parser': ^8.65.0
|
||||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||||
typescript: '>=4.8.4 <6.1.0'
|
typescript: '>=4.8.4 <6.1.0'
|
||||||
|
|
||||||
'@typescript-eslint/parser@8.64.0':
|
'@typescript-eslint/parser@8.65.0':
|
||||||
resolution: {integrity: sha512-KA0OshtlcCCXmbfqyZkM5pV3/WNraJf7DkJRLpyrmwPtud57H5BDX7C3k0LPSPxpprfRL+cJDGabF10mvNCoCw==}
|
resolution: {integrity: sha512-CZ4nMxWwgu1HEEFNkeaCptra9QCtkmKdgf3sWh1rl1trIhmxLilgTV4cwcbQ4wemnT4sWQN8CaKOmdYx+g2gMA==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||||
typescript: '>=4.8.4 <6.1.0'
|
typescript: '>=4.8.4 <6.1.0'
|
||||||
|
|
||||||
'@typescript-eslint/project-service@8.64.0':
|
'@typescript-eslint/project-service@8.65.0':
|
||||||
resolution: {integrity: sha512-tk4WpOJ6IEbGrVHaNmM0YRrwAD3exZlIK3iadQNAxh4YKk6jvUQ4ecq18n+v7+meh+cJ3j+D8nbk8sRKhlwLQg==}
|
resolution: {integrity: sha512-SxnPhbTsGahizDgbu7oqFH/xVtzIqMd/s+WtnSxNxJZJpLbdT5IPdzg8EZxO3+PoKahXmwJLeNQOpKJb3/bi7Q==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: '>=4.8.4 <6.1.0'
|
typescript: '>=4.8.4 <6.1.0'
|
||||||
|
|
||||||
'@typescript-eslint/scope-manager@8.64.0':
|
'@typescript-eslint/scope-manager@8.65.0':
|
||||||
resolution: {integrity: sha512-CXEaFdYXjSTgKhisNkwCcJwTP8Pl+fmRrEQrri4nm3vU743bALrxzLmq7fHG/7e6a5xO0lDYeURpZmBuhHk54w==}
|
resolution: {integrity: sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
|
|
||||||
'@typescript-eslint/tsconfig-utils@8.64.0':
|
'@typescript-eslint/tsconfig-utils@8.65.0':
|
||||||
resolution: {integrity: sha512-2yo8rRNKuzbVWQp5kslhANqZ2uDAeROQHBRZNPu8JDsHmeFNj/XJJhX/FhNUWmkHHvoNsKa6+tHJiig87EzsQw==}
|
resolution: {integrity: sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: '>=4.8.4 <6.1.0'
|
typescript: '>=4.8.4 <6.1.0'
|
||||||
|
|
||||||
'@typescript-eslint/type-utils@8.64.0':
|
'@typescript-eslint/type-utils@8.65.0':
|
||||||
resolution: {integrity: sha512-XWG4Fmmv/6SvyS9nH8jWrKs6terwJvE8cyRt1CzYYqzp9OrPhCT4cMc/f7C6RZCwG+qMmiffJS1/qJP8G1URtg==}
|
resolution: {integrity: sha512-YjaZ7PRI5qY7ax2L3PbvX0rRyGtipAReCWs0mhhDBHjH/vl0g0BonaGXrKdKpMbIIsMIwDgbk/xzkBTyAltS5g==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||||
typescript: '>=4.8.4 <6.1.0'
|
typescript: '>=4.8.4 <6.1.0'
|
||||||
|
|
||||||
'@typescript-eslint/types@8.64.0':
|
'@typescript-eslint/types@8.65.0':
|
||||||
resolution: {integrity: sha512-qjhfuTfLXjA4IOzXvz0rTjT01BqEiIgPoUeMwiEjnaHKJMTNo8rH5pYW1a2L/0Dnux2fPC85AeyJoWaGa8WxTA==}
|
resolution: {integrity: sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
|
|
||||||
'@typescript-eslint/typescript-estree@8.64.0':
|
'@typescript-eslint/typescript-estree@8.65.0':
|
||||||
resolution: {integrity: sha512-Pztpsn1aCE1oWDvDEfUk31nngvvF7vUB5SwHFEaZIFpvw7WJtqUHHL4plBZDA9HfWJJjL13BdG0YrJInTUvoVA==}
|
resolution: {integrity: sha512-JboAE2swaYt4tb1fHhHTABE2K+OLy09XfcTbhnk4Pw96f9dd2e9iYsJ28gBggHlo5z5x1rkyWvcPoTuNTd4oGg==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: '>=4.8.4 <6.1.0'
|
typescript: '>=4.8.4 <6.1.0'
|
||||||
|
|
||||||
'@typescript-eslint/utils@8.64.0':
|
'@typescript-eslint/utils@8.65.0':
|
||||||
resolution: {integrity: sha512-aJUGVB3+U0htrrCjoA8qukw8cm8fNCGAxK/tVoS70k8aeb7DETKeFozRiVFIwEeN9WJLsjaP3ph8I60tY2XZoQ==}
|
resolution: {integrity: sha512-gXiwIHsYreboxeJucHKPvgwl7dXt50mF8s1/c00cP/WoVTyWKFdtfhRWwZiXYFU5H2O8vVoSLNrexFZjYS/SGA==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||||
typescript: '>=4.8.4 <6.1.0'
|
typescript: '>=4.8.4 <6.1.0'
|
||||||
|
|
||||||
'@typescript-eslint/visitor-keys@8.64.0':
|
'@typescript-eslint/visitor-keys@8.65.0':
|
||||||
resolution: {integrity: sha512-mrtuL8Nsn6gi2H4mo5KMTp823M+3Q19Ew/i+Zlikq20tIMm99C3Ez0dCmkWWnxut20esQvTg8aUSEhMcAOXhEw==}
|
resolution: {integrity: sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
|
|
||||||
'@unblockneteasemusic/server@0.28.0':
|
'@unblockneteasemusic/server@0.28.0':
|
||||||
@@ -973,10 +973,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==}
|
resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
|
|
||||||
eslint-visitor-keys@3.4.3:
|
|
||||||
resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
|
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
|
||||||
|
|
||||||
eslint-visitor-keys@4.2.1:
|
eslint-visitor-keys@4.2.1:
|
||||||
resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==}
|
resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
@@ -1833,8 +1829,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
|
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
|
|
||||||
own-keys@1.0.1:
|
own-keys@1.0.2:
|
||||||
resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==}
|
resolution: {integrity: sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
p-is-promise@3.0.0:
|
p-is-promise@3.0.0:
|
||||||
@@ -2006,8 +2002,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==}
|
resolution: {integrity: sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==}
|
||||||
engines: {node: '>=6.0.0'}
|
engines: {node: '>=6.0.0'}
|
||||||
|
|
||||||
prettier@3.9.5:
|
prettier@3.9.6:
|
||||||
resolution: {integrity: sha512-/FVl766LpUfB5vXgCYOYa0MeV/441Ia99AeICQIQFTY/Nw0roZwULcXpku5i1/m5kt/baz+s4Zogspd839HSMg==}
|
resolution: {integrity: sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
@@ -2687,10 +2683,10 @@ snapshots:
|
|||||||
|
|
||||||
'@borewit/text-codec@0.2.2': {}
|
'@borewit/text-codec@0.2.2': {}
|
||||||
|
|
||||||
'@eslint-community/eslint-utils@4.9.1(eslint@9.39.5)':
|
'@eslint-community/eslint-utils@4.10.0(eslint@9.39.5)':
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint: 9.39.5
|
eslint: 9.39.5
|
||||||
eslint-visitor-keys: 3.4.3
|
eslint-visitor-keys: 5.0.1
|
||||||
|
|
||||||
'@eslint-community/regexpp@4.12.2': {}
|
'@eslint-community/regexpp@4.12.2': {}
|
||||||
|
|
||||||
@@ -2867,14 +2863,14 @@ snapshots:
|
|||||||
'@types/http-errors': 2.0.5
|
'@types/http-errors': 2.0.5
|
||||||
'@types/node': 25.9.2
|
'@types/node': 25.9.2
|
||||||
|
|
||||||
'@typescript-eslint/eslint-plugin@8.64.0(@typescript-eslint/parser@8.64.0(eslint@9.39.5)(typescript@5.9.3))(eslint@9.39.5)(typescript@5.9.3)':
|
'@typescript-eslint/eslint-plugin@8.65.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5)(typescript@5.9.3))(eslint@9.39.5)(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint-community/regexpp': 4.12.2
|
'@eslint-community/regexpp': 4.12.2
|
||||||
'@typescript-eslint/parser': 8.64.0(eslint@9.39.5)(typescript@5.9.3)
|
'@typescript-eslint/parser': 8.65.0(eslint@9.39.5)(typescript@5.9.3)
|
||||||
'@typescript-eslint/scope-manager': 8.64.0
|
'@typescript-eslint/scope-manager': 8.65.0
|
||||||
'@typescript-eslint/type-utils': 8.64.0(eslint@9.39.5)(typescript@5.9.3)
|
'@typescript-eslint/type-utils': 8.65.0(eslint@9.39.5)(typescript@5.9.3)
|
||||||
'@typescript-eslint/utils': 8.64.0(eslint@9.39.5)(typescript@5.9.3)
|
'@typescript-eslint/utils': 8.65.0(eslint@9.39.5)(typescript@5.9.3)
|
||||||
'@typescript-eslint/visitor-keys': 8.64.0
|
'@typescript-eslint/visitor-keys': 8.65.0
|
||||||
eslint: 9.39.5
|
eslint: 9.39.5
|
||||||
ignore: 7.0.6
|
ignore: 7.0.6
|
||||||
natural-compare: 1.4.0
|
natural-compare: 1.4.0
|
||||||
@@ -2883,41 +2879,41 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/parser@8.64.0(eslint@9.39.5)(typescript@5.9.3)':
|
'@typescript-eslint/parser@8.65.0(eslint@9.39.5)(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/scope-manager': 8.64.0
|
'@typescript-eslint/scope-manager': 8.65.0
|
||||||
'@typescript-eslint/types': 8.64.0
|
'@typescript-eslint/types': 8.65.0
|
||||||
'@typescript-eslint/typescript-estree': 8.64.0(typescript@5.9.3)
|
'@typescript-eslint/typescript-estree': 8.65.0(typescript@5.9.3)
|
||||||
'@typescript-eslint/visitor-keys': 8.64.0
|
'@typescript-eslint/visitor-keys': 8.65.0
|
||||||
debug: 4.4.3
|
debug: 4.4.3
|
||||||
eslint: 9.39.5
|
eslint: 9.39.5
|
||||||
typescript: 5.9.3
|
typescript: 5.9.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/project-service@8.64.0(typescript@5.9.3)':
|
'@typescript-eslint/project-service@8.65.0(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/tsconfig-utils': 8.64.0(typescript@5.9.3)
|
'@typescript-eslint/tsconfig-utils': 8.65.0(typescript@5.9.3)
|
||||||
'@typescript-eslint/types': 8.64.0
|
'@typescript-eslint/types': 8.65.0
|
||||||
debug: 4.4.3
|
debug: 4.4.3
|
||||||
typescript: 5.9.3
|
typescript: 5.9.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/scope-manager@8.64.0':
|
'@typescript-eslint/scope-manager@8.65.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/types': 8.64.0
|
'@typescript-eslint/types': 8.65.0
|
||||||
'@typescript-eslint/visitor-keys': 8.64.0
|
'@typescript-eslint/visitor-keys': 8.65.0
|
||||||
|
|
||||||
'@typescript-eslint/tsconfig-utils@8.64.0(typescript@5.9.3)':
|
'@typescript-eslint/tsconfig-utils@8.65.0(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
typescript: 5.9.3
|
typescript: 5.9.3
|
||||||
|
|
||||||
'@typescript-eslint/type-utils@8.64.0(eslint@9.39.5)(typescript@5.9.3)':
|
'@typescript-eslint/type-utils@8.65.0(eslint@9.39.5)(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/types': 8.64.0
|
'@typescript-eslint/types': 8.65.0
|
||||||
'@typescript-eslint/typescript-estree': 8.64.0(typescript@5.9.3)
|
'@typescript-eslint/typescript-estree': 8.65.0(typescript@5.9.3)
|
||||||
'@typescript-eslint/utils': 8.64.0(eslint@9.39.5)(typescript@5.9.3)
|
'@typescript-eslint/utils': 8.65.0(eslint@9.39.5)(typescript@5.9.3)
|
||||||
debug: 4.4.3
|
debug: 4.4.3
|
||||||
eslint: 9.39.5
|
eslint: 9.39.5
|
||||||
ts-api-utils: 2.5.0(typescript@5.9.3)
|
ts-api-utils: 2.5.0(typescript@5.9.3)
|
||||||
@@ -2925,14 +2921,14 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/types@8.64.0': {}
|
'@typescript-eslint/types@8.65.0': {}
|
||||||
|
|
||||||
'@typescript-eslint/typescript-estree@8.64.0(typescript@5.9.3)':
|
'@typescript-eslint/typescript-estree@8.65.0(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/project-service': 8.64.0(typescript@5.9.3)
|
'@typescript-eslint/project-service': 8.65.0(typescript@5.9.3)
|
||||||
'@typescript-eslint/tsconfig-utils': 8.64.0(typescript@5.9.3)
|
'@typescript-eslint/tsconfig-utils': 8.65.0(typescript@5.9.3)
|
||||||
'@typescript-eslint/types': 8.64.0
|
'@typescript-eslint/types': 8.65.0
|
||||||
'@typescript-eslint/visitor-keys': 8.64.0
|
'@typescript-eslint/visitor-keys': 8.65.0
|
||||||
debug: 4.4.3
|
debug: 4.4.3
|
||||||
minimatch: 10.2.5
|
minimatch: 10.2.5
|
||||||
semver: 7.8.5
|
semver: 7.8.5
|
||||||
@@ -2942,20 +2938,20 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/utils@8.64.0(eslint@9.39.5)(typescript@5.9.3)':
|
'@typescript-eslint/utils@8.65.0(eslint@9.39.5)(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint-community/eslint-utils': 4.9.1(eslint@9.39.5)
|
'@eslint-community/eslint-utils': 4.10.0(eslint@9.39.5)
|
||||||
'@typescript-eslint/scope-manager': 8.64.0
|
'@typescript-eslint/scope-manager': 8.65.0
|
||||||
'@typescript-eslint/types': 8.64.0
|
'@typescript-eslint/types': 8.65.0
|
||||||
'@typescript-eslint/typescript-estree': 8.64.0(typescript@5.9.3)
|
'@typescript-eslint/typescript-estree': 8.65.0(typescript@5.9.3)
|
||||||
eslint: 9.39.5
|
eslint: 9.39.5
|
||||||
typescript: 5.9.3
|
typescript: 5.9.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/visitor-keys@8.64.0':
|
'@typescript-eslint/visitor-keys@8.65.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/types': 8.64.0
|
'@typescript-eslint/types': 8.65.0
|
||||||
eslint-visitor-keys: 5.0.1
|
eslint-visitor-keys: 5.0.1
|
||||||
|
|
||||||
'@unblockneteasemusic/server@0.28.0':
|
'@unblockneteasemusic/server@0.28.0':
|
||||||
@@ -3527,7 +3523,7 @@ snapshots:
|
|||||||
object-inspect: 1.13.4
|
object-inspect: 1.13.4
|
||||||
object-keys: 1.1.1
|
object-keys: 1.1.1
|
||||||
object.assign: 4.1.7
|
object.assign: 4.1.7
|
||||||
own-keys: 1.0.1
|
own-keys: 1.0.2
|
||||||
regexp.prototype.flags: 1.5.4
|
regexp.prototype.flags: 1.5.4
|
||||||
safe-array-concat: 1.1.4
|
safe-array-concat: 1.1.4
|
||||||
safe-push-apply: 1.0.0
|
safe-push-apply: 1.0.0
|
||||||
@@ -3656,10 +3652,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
htmlparser2: 10.1.0
|
htmlparser2: 10.1.0
|
||||||
|
|
||||||
eslint-plugin-prettier@5.5.6(eslint-config-prettier@10.1.8(eslint@9.39.5))(eslint@9.39.5)(prettier@3.9.5):
|
eslint-plugin-prettier@5.5.6(eslint-config-prettier@10.1.8(eslint@9.39.5))(eslint@9.39.5)(prettier@3.9.6):
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint: 9.39.5
|
eslint: 9.39.5
|
||||||
prettier: 3.9.5
|
prettier: 3.9.6
|
||||||
prettier-linter-helpers: 1.0.1
|
prettier-linter-helpers: 1.0.1
|
||||||
synckit: 0.11.13
|
synckit: 0.11.13
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
@@ -3670,15 +3666,13 @@ snapshots:
|
|||||||
esrecurse: 4.3.0
|
esrecurse: 4.3.0
|
||||||
estraverse: 5.3.0
|
estraverse: 5.3.0
|
||||||
|
|
||||||
eslint-visitor-keys@3.4.3: {}
|
|
||||||
|
|
||||||
eslint-visitor-keys@4.2.1: {}
|
eslint-visitor-keys@4.2.1: {}
|
||||||
|
|
||||||
eslint-visitor-keys@5.0.1: {}
|
eslint-visitor-keys@5.0.1: {}
|
||||||
|
|
||||||
eslint@9.39.5:
|
eslint@9.39.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint-community/eslint-utils': 4.9.1(eslint@9.39.5)
|
'@eslint-community/eslint-utils': 4.10.0(eslint@9.39.5)
|
||||||
'@eslint-community/regexpp': 4.12.2
|
'@eslint-community/regexpp': 4.12.2
|
||||||
'@eslint/config-array': 0.21.2
|
'@eslint/config-array': 0.21.2
|
||||||
'@eslint/config-helpers': 0.4.2
|
'@eslint/config-helpers': 0.4.2
|
||||||
@@ -4662,8 +4656,9 @@ snapshots:
|
|||||||
type-check: 0.4.0
|
type-check: 0.4.0
|
||||||
word-wrap: 1.2.5
|
word-wrap: 1.2.5
|
||||||
|
|
||||||
own-keys@1.0.1:
|
own-keys@1.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
get-intrinsic: 1.3.0
|
get-intrinsic: 1.3.0
|
||||||
object-keys: 1.1.1
|
object-keys: 1.1.1
|
||||||
safe-push-apply: 1.0.0
|
safe-push-apply: 1.0.0
|
||||||
@@ -4899,7 +4894,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
fast-diff: 1.3.0
|
fast-diff: 1.3.0
|
||||||
|
|
||||||
prettier@3.9.5: {}
|
prettier@3.9.6: {}
|
||||||
|
|
||||||
process-nextick-args@2.0.1: {}
|
process-nextick-args@2.0.1: {}
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB |
+249
-5
@@ -283,7 +283,9 @@ AI 生成的图,仅供娱乐()
|
|||||||
|
|
||||||
`md5_password`: md5 加密后的密码,传入后 `password` 参数将失效
|
`md5_password`: md5 加密后的密码,传入后 `password` 参数将失效
|
||||||
|
|
||||||
`captcha`: 验证码,使用 [`/captcha/sent`](#发送验证码)接口传入手机号获取验证码,调用此接口传入验证码,可使用验证码登录,传入后 `password` 参数将失效
|
`captcha`: 验证码,使用 `/captcha/sent` 或 `/captcha/sent/v1`接口传入手机号获取验证码,调用此接口传入验证码,可使用验证码登录,传入后 `password` 参数将失效
|
||||||
|
|
||||||
|
`sca`: 网易易盾滑块验证token, 获取方式未知
|
||||||
|
|
||||||
**接口地址 :** `/login/cellphone`
|
**接口地址 :** `/login/cellphone`
|
||||||
|
|
||||||
@@ -397,6 +399,19 @@ body {
|
|||||||
|
|
||||||
**调用例子 :** `/captcha/sent?phone=13xxx`
|
**调用例子 :** `/captcha/sent?phone=13xxx`
|
||||||
|
|
||||||
|
### 新版发送验证码
|
||||||
|
|
||||||
|
说明 : 调用此接口 ,传入手机号码, 可发送验证码
|
||||||
|
|
||||||
|
**必选参数 :** `phone`: 手机号码
|
||||||
|
|
||||||
|
**可选参数 :**
|
||||||
|
`ctcode`: 国家区号,默认 86 即中国
|
||||||
|
|
||||||
|
**接口地址 :** `/captcha/sent/v1`
|
||||||
|
|
||||||
|
**调用例子 :** `/captcha/sent/v1?phone=13xxx`
|
||||||
|
|
||||||
### 验证验证码
|
### 验证验证码
|
||||||
|
|
||||||
说明 : 调用此接口 ,传入手机号码和验证码, 可校验验证码是否正确
|
说明 : 调用此接口 ,传入手机号码和验证码, 可校验验证码是否正确
|
||||||
@@ -1259,9 +1274,11 @@ tags: 歌单标签
|
|||||||
`lossless`=>`无损`, `hires`=>`Hi-Res`, `jyeffect` => `高清环绕声`, `sky` => `沉浸环绕声`, `dolby` => `杜比全景声`, `jymaster` => `超清母带`
|
`lossless`=>`无损`, `hires`=>`Hi-Res`, `jyeffect` => `高清环绕声`, `sky` => `沉浸环绕声`, `dolby` => `杜比全景声`, `jymaster` => `超清母带`
|
||||||
`unblock`: 是否使用使用歌曲解锁, 分为`true`和`false`
|
`unblock`: 是否使用使用歌曲解锁, 分为`true`和`false`
|
||||||
|
|
||||||
|
**可选参数 :** `immerseType`: 沉浸声环绕声类型, 分为 `c51` => `c51类型`, `ste` => `环绕立体声类型`, `aac` => `aac类型`, 仅在 `level=sky` 时生效, 默认为 `c51`
|
||||||
|
|
||||||
**接口地址 :** `/song/url/v1`
|
**接口地址 :** `/song/url/v1`
|
||||||
|
|
||||||
**调用例子 :** `/song/url/v1?id=1969519579&level=exhigh` `/song/url/v1?id=1969519579,33894312&level=lossless`
|
**调用例子 :** `/song/url/v1?id=1969519579&level=exhigh` `/song/url/v1?id=1969519579,33894312&level=lossless` `/song/url/v1?id=1969519579&level=sky&immerseType=ste`
|
||||||
|
|
||||||
说明:`杜比全景声`音质需要设备支持,不同的设备可能会返回不同码率的 url。cookie 需要传入`os=pc`保证返回正常码率的 url。
|
说明:`杜比全景声`音质需要设备支持,不同的设备可能会返回不同码率的 url。cookie 需要传入`os=pc`保证返回正常码率的 url。
|
||||||
|
|
||||||
@@ -1395,8 +1412,6 @@ tags: 歌单标签
|
|||||||
|
|
||||||
说明 : 调用此接口 , 传入类型和歌单 id 可收藏歌单或者取消收藏歌单
|
说明 : 调用此接口 , 传入类型和歌单 id 可收藏歌单或者取消收藏歌单
|
||||||
|
|
||||||
!> 警告: 在`v4.29.7`版本后, 在网易云登陆后请求要带上`timestamp`字段, 否则会导致请求不合法
|
|
||||||
|
|
||||||
**必选参数 :**
|
**必选参数 :**
|
||||||
|
|
||||||
`t` : 类型,1:收藏,2:取消收藏
|
`t` : 类型,1:收藏,2:取消收藏
|
||||||
@@ -5473,7 +5488,236 @@ let data = encodeURIComponent(
|
|||||||
|
|
||||||
**接口地址 :** `/song/cloud/download`
|
**接口地址 :** `/song/cloud/download`
|
||||||
|
|
||||||
**调用例子 :** `/song/cloud/download?id=123456789`
|
**调用例子 :** `/song/cloud/download?id=123456789`'
|
||||||
|
|
||||||
|
### 获取广告
|
||||||
|
|
||||||
|
说明 : 调用此接口, 可获取广告
|
||||||
|
|
||||||
|
**接口地址 :** `/ad/get`
|
||||||
|
|
||||||
|
**调用例子 :** `/ad/get`
|
||||||
|
|
||||||
|
### 获取30分钟免费听歌时长
|
||||||
|
|
||||||
|
说明 : 登录后调用此接口, 获取30分钟免费听歌时长
|
||||||
|
|
||||||
|
!> 警告: 通过调取接口出现的任何问题由调用者自行承担
|
||||||
|
|
||||||
|
**可选参数 :** `reqUid` 通过`/ad/get` 获取的广告ID
|
||||||
|
|
||||||
|
**接口地址 :** `/ad/listening/rights/gain`
|
||||||
|
|
||||||
|
**调用例子 :** `/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`
|
||||||
|
|
||||||
|
### 发送/删除评论
|
||||||
|
|
||||||
|
说明 : 调用此接口,可发送评论或者删除评论
|
||||||
|
|
||||||
|
1. 发送评论
|
||||||
|
|
||||||
|
**必选参数**
|
||||||
|
|
||||||
|
`type`: 数字,资源类型,对应歌曲,mv,专辑,歌单,电台,视频对应以下类型
|
||||||
|
|
||||||
|
```
|
||||||
|
0: 歌曲
|
||||||
|
|
||||||
|
1: mv
|
||||||
|
|
||||||
|
2: 歌单
|
||||||
|
|
||||||
|
3: 专辑
|
||||||
|
|
||||||
|
4: 电台
|
||||||
|
|
||||||
|
5: 视频
|
||||||
|
|
||||||
|
6: 动态
|
||||||
|
```
|
||||||
|
|
||||||
|
`id`: 对应资源 id
|
||||||
|
|
||||||
|
`content`: 要发送的内容
|
||||||
|
|
||||||
|
**调用例子** : `/comment/add?type=1&id=5436712&content=test` (往广岛之恋 mv 发送评论: test)
|
||||||
|
|
||||||
|
2. 回复评论
|
||||||
|
|
||||||
|
**必选参数**
|
||||||
|
|
||||||
|
`type`: 数字,资源类型,对应歌曲,mv,专辑,歌单,电台,视频对应以下类型
|
||||||
|
|
||||||
|
```
|
||||||
|
0: 歌曲
|
||||||
|
|
||||||
|
1: mv
|
||||||
|
|
||||||
|
2: 歌单
|
||||||
|
|
||||||
|
3: 专辑
|
||||||
|
|
||||||
|
4: 电台
|
||||||
|
|
||||||
|
5: 视频
|
||||||
|
|
||||||
|
6: 动态
|
||||||
|
```
|
||||||
|
|
||||||
|
`id`: 对应资源 id
|
||||||
|
|
||||||
|
`cid`: 评论 id
|
||||||
|
|
||||||
|
`content`: 要发送的内容
|
||||||
|
|
||||||
|
**调用例子** : `/comment/add?type=1&id=5436712&cid=1535550516319&content=test` (往广岛之恋 mv 回复test评论: test)
|
||||||
|
|
||||||
|
3. 删除评论
|
||||||
|
|
||||||
|
**必选参数**
|
||||||
|
|
||||||
|
`type`: 数字,资源类型,对应歌曲,mv,专辑,歌单,电台,视频对应以下类型
|
||||||
|
|
||||||
|
```
|
||||||
|
0: 歌曲
|
||||||
|
|
||||||
|
1: mv
|
||||||
|
|
||||||
|
2: 歌单
|
||||||
|
|
||||||
|
3: 专辑
|
||||||
|
|
||||||
|
4: 电台节目
|
||||||
|
|
||||||
|
5: 视频
|
||||||
|
|
||||||
|
6: 动态
|
||||||
|
|
||||||
|
7: 电台
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
`id`: 对应资源 id
|
||||||
|
|
||||||
|
`cid`: 评论 id
|
||||||
|
|
||||||
|
**调用例子** : `/comment?type=1&id=5436712&cid=1535550516319` (在广岛之恋 mv 删除评论)
|
||||||
|
|
||||||
|
### 获取在线设备列表
|
||||||
|
|
||||||
|
说明: 登录后调用此接口, 获取在线设备列表
|
||||||
|
|
||||||
|
**接口地址:** `/device/list`
|
||||||
|
|
||||||
|
**调用例子:** `/device/list`
|
||||||
|
|
||||||
|
### 发送安全验证码
|
||||||
|
|
||||||
|
说明: 登录后调用此接口, 传入手机号, 可发送安全验证码
|
||||||
|
|
||||||
|
**必选参数 :** `phone`: 手机号
|
||||||
|
|
||||||
|
**接口地址 :** `/captcha/safe/sent`
|
||||||
|
|
||||||
|
**调用例子 :** `/captcha/safe/sent?phone=13XXXXXXXXX`
|
||||||
|
|
||||||
|
### 强制下线设备
|
||||||
|
|
||||||
|
说明: 登录后调用此接口, 传入设备 id, 可强制下线设备的登录会话
|
||||||
|
|
||||||
|
**必选参数 :** `key`: 设备的 `deviceKey`, 可通过 `/device/list` 获取
|
||||||
|
|
||||||
|
`captcha`: 安全验证码, 可通过 `/captcha/safe/sent` 获取
|
||||||
|
|
||||||
|
**接口地址 :** `/device/kickoff`
|
||||||
|
|
||||||
|
**调用例子 :** `/device/kickoff?key=00ALDFGEXXXXXXXXXXXXXXXXX&captcha=1234`
|
||||||
|
|
||||||
## 离线访问此文档
|
## 离线访问此文档
|
||||||
|
|
||||||
|
|||||||
@@ -172,7 +172,7 @@
|
|||||||
setTag('s1tag', 'busy', '注册中…')
|
setTag('s1tag', 'busy', '注册中…')
|
||||||
setNum('s1num', false)
|
setNum('s1num', false)
|
||||||
try {
|
try {
|
||||||
const res = await fetch(nocache(base + '/register/checktoken?refresh=1'))
|
const res = await fetch(nocache(base + '/register/checktoken/v3?refresh=1'))
|
||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
$('s1pre').textContent = JSON.stringify(data, null, 2)
|
$('s1pre').textContent = JSON.stringify(data, null, 2)
|
||||||
if (data.token) {
|
if (data.token) {
|
||||||
|
|||||||
+2
-1
@@ -98,7 +98,8 @@ curl -s {origin}/search?keywords=网易云</code></pre>
|
|||||||
<a href="/avatar_update.html">头像更新示例</a> ·
|
<a href="/avatar_update.html">头像更新示例</a> ·
|
||||||
<a href="/scrobble.html">听歌打卡示例</a> ·
|
<a href="/scrobble.html">听歌打卡示例</a> ·
|
||||||
<a href="/yidun.html">获取 CheckToken</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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
+701
@@ -0,0 +1,701 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>云小编任务中心 - 网易云音乐 API Enhanced</title>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||||
|
min-height: 100vh;
|
||||||
|
background: #f5f5f5;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 40px auto;
|
||||||
|
background: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 32px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-link {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: #666;
|
||||||
|
font-size: 14px;
|
||||||
|
text-decoration: none;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-link:hover {
|
||||||
|
color: #333;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Section ---- */
|
||||||
|
.section {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section:last-of-type {
|
||||||
|
border-bottom: none;
|
||||||
|
margin-bottom: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Form ---- */
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: block;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #555;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
label .tag {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 400;
|
||||||
|
padding: 1px 6px;
|
||||||
|
border-radius: 3px;
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
label .tag.r {
|
||||||
|
background: #fee2e2;
|
||||||
|
color: #991b1b;
|
||||||
|
}
|
||||||
|
|
||||||
|
label .tag.o {
|
||||||
|
background: #fef3c7;
|
||||||
|
color: #92400e;
|
||||||
|
}
|
||||||
|
|
||||||
|
label .tag.g {
|
||||||
|
background: #d1fae5;
|
||||||
|
color: #065f46;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"],
|
||||||
|
input[type="number"],
|
||||||
|
textarea {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px 14px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 14px;
|
||||||
|
outline: none;
|
||||||
|
font-family: inherit;
|
||||||
|
transition: border-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"]:focus,
|
||||||
|
input[type="number"]:focus,
|
||||||
|
textarea:focus {
|
||||||
|
border-color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
resize: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row .form-group {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-fill {
|
||||||
|
margin-top: 5px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-fill span {
|
||||||
|
color: #0066cc;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-fill span:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px;
|
||||||
|
background: #333;
|
||||||
|
color: white;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 500;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.2s ease;
|
||||||
|
border: none;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover {
|
||||||
|
background: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:disabled {
|
||||||
|
background: #ccc;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sm {
|
||||||
|
display: inline-block;
|
||||||
|
width: auto;
|
||||||
|
padding: 6px 16px;
|
||||||
|
background: #333;
|
||||||
|
color: white;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.2s ease;
|
||||||
|
border: none;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sm:hover {
|
||||||
|
background: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sm:disabled {
|
||||||
|
background: #ccc;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sm.green {
|
||||||
|
background: #059669;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sm.green:hover {
|
||||||
|
background: #047857;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sm.green:disabled {
|
||||||
|
background: #a7f3d0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sm.red {
|
||||||
|
background: #dc2626;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sm.red:hover {
|
||||||
|
background: #b91c1c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sm.red:disabled {
|
||||||
|
background: #fca5a5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sm.gray {
|
||||||
|
background: #6b7280;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sm.gray:hover {
|
||||||
|
background: #4b5563;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sm.gray:disabled {
|
||||||
|
background: #d1d5db;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result {
|
||||||
|
margin-top: 16px;
|
||||||
|
padding: 12px 16px;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: left;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-break: break-all;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result.success {
|
||||||
|
background: #d1fae5;
|
||||||
|
color: #065f46;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result.error {
|
||||||
|
background: #fee2e2;
|
||||||
|
color: #991b1b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result.info {
|
||||||
|
background: #e0f2fe;
|
||||||
|
color: #0369a1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-link {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 24px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-link a {
|
||||||
|
color: #666;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-link a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Info Card ---- */
|
||||||
|
.info-card {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
padding: 16px;
|
||||||
|
background: #f9fafb;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-card .avatar {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border-radius: 50%;
|
||||||
|
object-fit: cover;
|
||||||
|
background: #e5e7eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-card .info-text {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-card .btn-sm {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Song Review ---- */
|
||||||
|
.song-review {
|
||||||
|
margin-top: 16px;
|
||||||
|
padding: 16px;
|
||||||
|
background: #f9fafb;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.song-review .cover {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
border-radius: 6px;
|
||||||
|
object-fit: cover;
|
||||||
|
background: #e5e7eb;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.song-review .song-title {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.song-review audio {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.song-review .song-tag {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.song-review .btn-group {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.song-review .lyric {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #555;
|
||||||
|
background: #fff;
|
||||||
|
padding: 10px 12px;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
max-height: 120px;
|
||||||
|
overflow-y: auto;
|
||||||
|
font-family: monospace;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-text {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>云小编任务中心</h1>
|
||||||
|
<p class="subtitle">管理云音乐审核任务、签到与会员权益领取</p>
|
||||||
|
|
||||||
|
<a href="/qrlogin-nocookie.html" class="login-link">还没登录?点击登录</a>
|
||||||
|
|
||||||
|
<!-- Cookie -->
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="cookie">Cookie <span class="tag o">可选</span></label>
|
||||||
|
<textarea id="cookie" placeholder="留空则默认读取本地存储的登录态" rows="2"></textarea>
|
||||||
|
<div class="quick-fill">
|
||||||
|
<span onclick="loadLocalCookie()">读取本地 Cookie</span>
|
||||||
|
<span onclick="clearCookie()">清除 Cookie</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-header">
|
||||||
|
<span class="section-title">用户信息</span>
|
||||||
|
<button class="btn-sm" id="userGet">获取用户详情</button>
|
||||||
|
</div>
|
||||||
|
<div class="info-card" id="user">
|
||||||
|
<img alt="头像" class="avatar" id="userAvatar" />
|
||||||
|
<span class="info-text" id="userName">未登录</span>
|
||||||
|
<button class="btn-sm green" id="userSign" disabled>签到</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-header">
|
||||||
|
<span class="section-title">会员领取</span>
|
||||||
|
<button class="btn-sm" id="vipGet">获取会员详情</button>
|
||||||
|
</div>
|
||||||
|
<div class="info-card" id="vip">
|
||||||
|
<span class="info-text" id="vipStatus">未载入</span>
|
||||||
|
<button class="btn-sm" id="vipCollect" disabled>领取</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-header">
|
||||||
|
<span class="section-title">审核任务</span>
|
||||||
|
<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>
|
||||||
|
<button class="btn-sm" id="taskStart" disabled>去完成</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Song Review -->
|
||||||
|
<div class="song-review" id="song" style="display: none;">
|
||||||
|
<img alt="封面" class="cover" id="songCover" />
|
||||||
|
<div class="song-title" id="songTitle">未载入</div>
|
||||||
|
<audio controls id="songAudio"></audio>
|
||||||
|
<div class="song-tag" id="songTag"></div>
|
||||||
|
<div class="btn-group">
|
||||||
|
<button class="btn-sm green" id="songApprove" disabled>同意</button>
|
||||||
|
<button class="btn-sm red" id="songReject" disabled>否决</button>
|
||||||
|
<button class="btn-sm gray" id="songSkip" disabled>跳过 (不计次数)</button>
|
||||||
|
</div>
|
||||||
|
<div class="lyric" id="songLyric">[00:00.00] 暂无歌词</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="result" class="result" style="display: none;"></div>
|
||||||
|
|
||||||
|
<div class="footer-link">
|
||||||
|
<a href="/">返回首页</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="https://fastly.jsdelivr.net/npm/axios@0.26.1/dist/axios.min.js"></script>
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
var k_cookie = 'ncm_cookie';
|
||||||
|
var cookie = localStorage.getItem(k_cookie) || '';
|
||||||
|
|
||||||
|
/* ---- DOM refs ---- */
|
||||||
|
var cookieInput = document.getElementById('cookie');
|
||||||
|
var resultDiv = document.getElementById('result');
|
||||||
|
|
||||||
|
/* ---- Init ---- */
|
||||||
|
if (cookie) {
|
||||||
|
cookieInput.value = cookie;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Cookie ---- */
|
||||||
|
window.loadLocalCookie = function () {
|
||||||
|
var local = localStorage.getItem(k_cookie);
|
||||||
|
if (local) {
|
||||||
|
cookie = local;
|
||||||
|
cookieInput.value = local;
|
||||||
|
showResult('已成功读取本地 Cookie', 'success');
|
||||||
|
} else {
|
||||||
|
showResult('未在本地发现登录 Cookie,请先登录或手动粘贴', 'error');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.clearCookie = function () {
|
||||||
|
cookie = '';
|
||||||
|
cookieInput.value = '';
|
||||||
|
localStorage.removeItem(k_cookie);
|
||||||
|
showResult('已清除本地 Cookie', 'info');
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ---- Result ---- */
|
||||||
|
function hideResult() {
|
||||||
|
resultDiv.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
function showResult(message, type) {
|
||||||
|
resultDiv.textContent = message;
|
||||||
|
resultDiv.className = 'result ' + type;
|
||||||
|
resultDiv.style.display = 'block';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCookie() {
|
||||||
|
var ck = cookieInput.value.trim();
|
||||||
|
if (ck) cookie = ck;
|
||||||
|
return ck || cookie || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发起请求 (兼容旧版)
|
||||||
|
* @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;
|
||||||
|
xhr.onload = function () {
|
||||||
|
var r = xhr.response;
|
||||||
|
if (r.code !== 200) {
|
||||||
|
showResult('错误 ' + r.code + ': ' + (r.message || '未知错误'), 'error');
|
||||||
|
} else {
|
||||||
|
done(r);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.onerror = function () {
|
||||||
|
showResult('网络请求失败: ' + xhr.statusText, 'error');
|
||||||
|
};
|
||||||
|
var ck = getCookie();
|
||||||
|
if (ck) params.cookie = ck;
|
||||||
|
var s = '?_=' + Date.now();
|
||||||
|
for (var k in params) {
|
||||||
|
s += '&' + k + '=' + encodeURIComponent(params[k]);
|
||||||
|
}
|
||||||
|
xhr.open('GET', url + s);
|
||||||
|
xhr.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 用户信息 ///
|
||||||
|
var userAvatar = document.getElementById('userAvatar');
|
||||||
|
var userName = document.getElementById('userName');
|
||||||
|
var userSign = document.getElementById('userSign');
|
||||||
|
var userGet = document.getElementById('userGet');
|
||||||
|
|
||||||
|
userGet.onclick = function () {
|
||||||
|
request('rep/ugc/user/get', {}, function (res) {
|
||||||
|
var d = res.data;
|
||||||
|
if (d.imgUrl) userAvatar.src = d.imgUrl + '?param=50y50';
|
||||||
|
userName.textContent = d.name || '游客' + d.id;
|
||||||
|
userSign.disabled = d.signed;
|
||||||
|
showResult('用户信息加载成功', 'success');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
userSign.onclick = function () {
|
||||||
|
if (!userSign.disabled) {
|
||||||
|
userSign.disabled = true;
|
||||||
|
request('rep/ugc/user/sign', {}, function (res) {
|
||||||
|
var d = res.data;
|
||||||
|
userSign.disabled = d;
|
||||||
|
showResult('签到' + (d ? '成功 ✓' : '失败 ✗'), d ? 'success' : 'error');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// 会员领取 ///
|
||||||
|
var vipStatus = document.getElementById('vipStatus');
|
||||||
|
var vipCollect = document.getElementById('vipCollect');
|
||||||
|
var vipGet = document.getElementById('vipGet');
|
||||||
|
|
||||||
|
vipGet.onclick = function () {
|
||||||
|
request('rep/ugc/user/vip', {}, function (res) {
|
||||||
|
var d = res.data;
|
||||||
|
vipStatus.textContent = d.status + ': ' + d.title;
|
||||||
|
vipCollect.disabled = d.status !== 20;
|
||||||
|
showResult('会员详情加载成功', 'success');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
vipCollect.onclick = function () {
|
||||||
|
if (!vipCollect.disabled) {
|
||||||
|
vipCollect.disabled = true;
|
||||||
|
request('rep/ugc/user/collect-vip', {}, function (res) {
|
||||||
|
var d = res.data;
|
||||||
|
vipCollect.disabled = d;
|
||||||
|
showResult('领取' + (d ? '成功 ✓' : '失败 ✗'), d ? 'success' : 'error');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// 审核任务 ///
|
||||||
|
var taskCount = document.getElementById('taskCount');
|
||||||
|
var taskGoal = document.getElementById('taskGoal');
|
||||||
|
var taskStartBtn = document.getElementById('taskStart');
|
||||||
|
var taskGetBtn = document.getElementById('taskGet');
|
||||||
|
|
||||||
|
taskGetBtn.onclick = function () {
|
||||||
|
request('/rep/ugc/activity/get', {}, function (res) {
|
||||||
|
var d = res.data;
|
||||||
|
taskCount.textContent = d.count;
|
||||||
|
taskGoal.textContent = d.goalCount;
|
||||||
|
taskStartBtn.disabled = d.activityId !== 5001;
|
||||||
|
showResult('任务详情加载成功', 'success');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
taskStartBtn.onclick = function () {
|
||||||
|
if (!taskStartBtn.disabled) taskStart();
|
||||||
|
};
|
||||||
|
|
||||||
|
/// 歌曲审核区域 ///
|
||||||
|
var song = document.getElementById('song');
|
||||||
|
var songCover = document.getElementById('songCover');
|
||||||
|
var songTitle = document.getElementById('songTitle');
|
||||||
|
var songAudio = document.getElementById('songAudio');
|
||||||
|
var songTag = document.getElementById('songTag');
|
||||||
|
var songApprove = document.getElementById('songApprove');
|
||||||
|
var songReject = document.getElementById('songReject');
|
||||||
|
var songSkip = document.getElementById('songSkip');
|
||||||
|
var songLyric = document.getElementById('songLyric');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取任务
|
||||||
|
*/
|
||||||
|
function taskStart() {
|
||||||
|
song.style.display = 'none';
|
||||||
|
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');
|
||||||
|
});
|
||||||
|
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] 暂无歌词';
|
||||||
|
songAudio.src = d.songUrl;
|
||||||
|
songAudio.play().catch(function () { /* 自动播放被浏览器阻止 */ });
|
||||||
|
|
||||||
|
songApprove.onclick = function () { if (!songApprove.disabled) taskSubmit(d.taskId, '1'); };
|
||||||
|
songReject.onclick = function () { if (!songReject.disabled) taskSubmit(d.taskId, '2'); };
|
||||||
|
songSkip.onclick = function () { if (!songSkip.disabled) taskSubmit(d.taskId, '3'); };
|
||||||
|
|
||||||
|
songApprove.disabled = songReject.disabled = songSkip.disabled = true;
|
||||||
|
song.style.display = 'block';
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
songApprove.disabled = songReject.disabled = songSkip.disabled = false;
|
||||||
|
}, 3e3);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提交任务
|
||||||
|
* @param {string} taskId
|
||||||
|
* @param {'1'|'2'|'3'} judgement
|
||||||
|
*/
|
||||||
|
function taskSubmit(taskId, judgement) {
|
||||||
|
songApprove.disabled = songReject.disabled = songSkip.disabled = true;
|
||||||
|
request(
|
||||||
|
'thinktank/audit/resource/update',
|
||||||
|
{ type: '4', taskId: taskId, judgement: judgement },
|
||||||
|
function (res) {
|
||||||
|
var d = res.data;
|
||||||
|
if (d.result) {
|
||||||
|
showResult('审核提交成功,加载下一首...', 'success');
|
||||||
|
taskStart();
|
||||||
|
} else {
|
||||||
|
showResult('未知状态: ' + JSON.stringify(d), 'error');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 一键载入 ///
|
||||||
|
document.getElementById('loadall').onclick = function () {
|
||||||
|
userGet.click();
|
||||||
|
vipGet.click();
|
||||||
|
taskGetBtn.click();
|
||||||
|
showResult('正在载入所有数据...', 'info');
|
||||||
|
};
|
||||||
|
|
||||||
|
window.loadLocalCookie();
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
+1
-1
@@ -88,7 +88,7 @@
|
|||||||
tag.textContent = '获取中…'
|
tag.textContent = '获取中…'
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const url = base + '/register/checktoken' + (refresh ? '?refresh=1' : '')
|
const url = base + '/register/checktoken/v2' + (refresh ? '?refresh=1' : '')
|
||||||
const res = await fetch(url)
|
const res = await fetch(url)
|
||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
$('respDisplay').textContent = JSON.stringify(data, null, 2)
|
$('respDisplay').textContent = JSON.stringify(data, null, 2)
|
||||||
|
|||||||
+3
-1
@@ -11,11 +11,13 @@
|
|||||||
},
|
},
|
||||||
"APP_CONF": {
|
"APP_CONF": {
|
||||||
"apiDomain": "https://interface.music.163.com",
|
"apiDomain": "https://interface.music.163.com",
|
||||||
|
"eapiDomain": "https://interfacepc.music.163.com",
|
||||||
"xeapiDomain": "https://interface3.music.163.com",
|
"xeapiDomain": "https://interface3.music.163.com",
|
||||||
"domain": "https://music.163.com",
|
"domain": "https://music.163.com",
|
||||||
"clDomian": "https://clientlog.music.163.com",
|
"clDomian": "https://clientlog.music.163.com",
|
||||||
"clDomian3": "https://clientlog3.music.163.com",
|
"clDomian3": "https://clientlog3.music.163.com",
|
||||||
"dunDomain": "https://ac.dun.163yun.com",
|
"dunDomainV3": "https://ac.dun.163yun.com",
|
||||||
|
"dunDomainV2": "https://ac.dun.163.com",
|
||||||
"encrypt": true,
|
"encrypt": true,
|
||||||
"encryptResponse": false,
|
"encryptResponse": false,
|
||||||
"clientSign": "18:C0:4D:B9:8F:FE@@@453832335F384641365F424635335F303030315F303031425F343434415F343643365F333638332@@@@@@6ff673ef74955b38bce2fa8562d95c976ed4758b1227c4e9ee345987cee17bc9",
|
"clientSign": "18:C0:4D:B9:8F:FE@@@453832335F384641365F424635335F303030315F303031425F343434415F343643365F333638332@@@@@@6ff673ef74955b38bce2fa8562d95c976ed4758b1227c4e9ee345987cee17bc9",
|
||||||
|
|||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
const createOption = (query, crypto = '') => {
|
const createOption = (query, crypto = '', checkToken = false) => {
|
||||||
return {
|
return {
|
||||||
crypto: query.crypto || crypto || '',
|
crypto: query.crypto || crypto || '',
|
||||||
cookie: query.cookie || process.env.NETEASE_COOKIE,
|
cookie: query.cookie || process.env.NETEASE_COOKIE,
|
||||||
@@ -11,7 +11,7 @@ const createOption = (query, crypto = '') => {
|
|||||||
: ['true', true].includes(query.randomCNIP),
|
: ['true', true].includes(query.randomCNIP),
|
||||||
e_r: query.e_r || undefined,
|
e_r: query.e_r || undefined,
|
||||||
domain: query.domain || '',
|
domain: query.domain || '',
|
||||||
checkToken: query.checkToken || false,
|
checkToken: query.checkToken || checkToken,
|
||||||
headers: query.headers || {},
|
headers: query.headers || {},
|
||||||
timeout: query.timeout || 0,
|
timeout: query.timeout || 0,
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-4
@@ -18,7 +18,12 @@ const {
|
|||||||
} = require('./index')
|
} = require('./index')
|
||||||
const { URLSearchParams, URL } = require('url')
|
const { URLSearchParams, URL } = require('url')
|
||||||
const { APP_CONF } = require('../util/config.json')
|
const { APP_CONF } = require('../util/config.json')
|
||||||
const { getToken: antiCheatToken } = require('../module/register_checktoken')
|
const {
|
||||||
|
getToken: antiCheatTokenV2,
|
||||||
|
} = require('../module/register_checktoken_v2')
|
||||||
|
const {
|
||||||
|
getToken: antiCheatTokenV3,
|
||||||
|
} = require('../module/register_checktoken_v3')
|
||||||
|
|
||||||
// 预先读取匿名token并缓存
|
// 预先读取匿名token并缓存
|
||||||
const anonymous_token = fs.readFileSync(
|
const anonymous_token = fs.readFileSync(
|
||||||
@@ -107,7 +112,7 @@ const userAgentMap = {
|
|||||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36',
|
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36',
|
||||||
},
|
},
|
||||||
api: {
|
api: {
|
||||||
pc: 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 Chrome/91.0.4472.164 NeteaseMusicDesktop/3.0.18.203152',
|
pc: 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 Chrome/91.0.4472.164 NeteaseMusicDesktop/3.1.29.205117',
|
||||||
android:
|
android:
|
||||||
'NeteaseMusic/9.1.65.240927161425(9001065);Dalvik/2.1.0 (Linux; U; Android 14; 23013RK75C Build/UKQ1.230804.001)',
|
'NeteaseMusic/9.1.65.240927161425(9001065);Dalvik/2.1.0 (Linux; U; Android 14; 23013RK75C Build/UKQ1.230804.001)',
|
||||||
iphone: 'NeteaseMusic 9.0.90/5038 (iPhone; iOS 16.2; zh_CN)',
|
iphone: 'NeteaseMusic 9.0.90/5038 (iPhone; iOS 16.2; zh_CN)',
|
||||||
@@ -117,6 +122,7 @@ const userAgentMap = {
|
|||||||
// 预先定义常量
|
// 预先定义常量
|
||||||
const DOMAIN = APP_CONF.domain
|
const DOMAIN = APP_CONF.domain
|
||||||
const API_DOMAIN = APP_CONF.apiDomain
|
const API_DOMAIN = APP_CONF.apiDomain
|
||||||
|
const EAPI_DOMAIN = APP_CONF.eapiDomain
|
||||||
const XEAPI_DOMAIN = APP_CONF.xeapiDomain
|
const XEAPI_DOMAIN = APP_CONF.xeapiDomain
|
||||||
const ENCRYPT_RESPONSE = APP_CONF.encryptResponse
|
const ENCRYPT_RESPONSE = APP_CONF.encryptResponse
|
||||||
const SPECIAL_STATUS_CODES = new Set([201, 302, 400, 502, 800, 801, 802, 803])
|
const SPECIAL_STATUS_CODES = new Set([201, 302, 400, 502, 800, 801, 802, 803])
|
||||||
@@ -182,7 +188,15 @@ const generateRequestId = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const createRequest = (uri, data, options) => {
|
const createRequest = (uri, data, options) => {
|
||||||
const token = options.checkToken ? antiCheatToken() : ''
|
let token = ''
|
||||||
|
switch (options.checkToken) {
|
||||||
|
case 'v2':
|
||||||
|
token = antiCheatTokenV2()
|
||||||
|
break
|
||||||
|
case 'v3':
|
||||||
|
token = antiCheatTokenV3()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
// 变量声明和初始化
|
// 变量声明和初始化
|
||||||
@@ -329,7 +343,7 @@ const createRequest = (uri, data, options) => {
|
|||||||
data.header = header
|
data.header = header
|
||||||
|
|
||||||
encryptData = encrypt.eapi(uri, data)
|
encryptData = encrypt.eapi(uri, data)
|
||||||
url = (options.domain || API_DOMAIN) + '/eapi/' + uri.substr(5)
|
url = (options.domain || EAPI_DOMAIN) + '/eapi/' + uri.substr(5)
|
||||||
} else if (crypto === 'api') {
|
} else if (crypto === 'api') {
|
||||||
url = (options.domain || API_DOMAIN) + uri
|
url = (options.domain || API_DOMAIN) + uri
|
||||||
encryptData = data
|
encryptData = data
|
||||||
|
|||||||
Reference in New Issue
Block a user