mirror of
https://github.com/Jerryplusy/rc-plugin.git
synced 2025-10-14 08:09:19 +00:00
commit
9a61d9c96a
@ -1,15 +1,17 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { formatTime } from '../utils/other.js'
|
import fs from "node:fs";
|
||||||
|
import { formatTime, toGBorTB } from '../utils/other.js'
|
||||||
import puppeteer from "../../../lib/puppeteer/puppeteer.js";
|
import puppeteer from "../../../lib/puppeteer/puppeteer.js";
|
||||||
import PickSongList from "../model/pick-song.js";
|
import PickSongList from "../model/pick-song.js";
|
||||||
import NeteaseMusicInfo from '../model/neteaseMusicInfo.js'
|
import NeteaseMusicInfo from '../model/neteaseMusicInfo.js'
|
||||||
import { NETEASE_API_CN, NETEASE_SONG_DOWNLOAD, NETEASE_TEMP_API } from "../constants/tools.js";
|
import { NETEASE_API_CN, NETEASE_SONG_DOWNLOAD, NETEASE_TEMP_API } from "../constants/tools.js";
|
||||||
import { COMMON_USER_AGENT, REDIS_YUNZAI_ISOVERSEA, REDIS_YUNZAI_SONGINFO } from "../constants/constant.js";
|
import { COMMON_USER_AGENT, REDIS_YUNZAI_ISOVERSEA, REDIS_YUNZAI_SONGINFO, REDIS_YUNZAI_CLOUDSONGLIST } from "../constants/constant.js";
|
||||||
import { downloadAudio } from "../utils/common.js";
|
import { downloadAudio } from "../utils/common.js";
|
||||||
import { redisExistKey, redisGetKey, redisSetKey } from "../utils/redis-util.js";
|
import { redisExistKey, redisGetKey, redisSetKey } from "../utils/redis-util.js";
|
||||||
import { checkAndRemoveFile } from "../utils/file.js";
|
import { checkAndRemoveFile } from "../utils/file.js";
|
||||||
import { sendMusicCard } from "../utils/yunzai-util.js";
|
import { sendMusicCard } from "../utils/yunzai-util.js";
|
||||||
import config from "../model/config.js";
|
import config from "../model/config.js";
|
||||||
|
import FormData from 'form-data';
|
||||||
|
|
||||||
export class songRequest extends plugin {
|
export class songRequest extends plugin {
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -27,9 +29,29 @@ export class songRequest extends plugin {
|
|||||||
fnc: "playSong"
|
fnc: "playSong"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
reg: "^#?上传(.*)",
|
reg: "^#?上传$",
|
||||||
fnc: "upLoad"
|
fnc: "upLoad"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
reg: '^#?我的云盘$|#rnc|#RNC',
|
||||||
|
fnc: 'myCloud',
|
||||||
|
permission: 'master'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
reg: '^#?云盘更新|#?更新云盘$',
|
||||||
|
fnc: 'songCloudUpdate',
|
||||||
|
permission: 'master'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
reg: '^#?上传云盘|#?上传网盘$|#rnu|#RNU',
|
||||||
|
fnc: 'uploadCloud',
|
||||||
|
permission: 'master'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
reg: '^#?清除云盘缓存$',
|
||||||
|
fnc: 'cleanCloudData',
|
||||||
|
permission: 'master'
|
||||||
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
this.toolsConfig = config.getConfig("tools");
|
this.toolsConfig = config.getConfig("tools");
|
||||||
@ -51,6 +73,8 @@ export class songRequest extends plugin {
|
|||||||
this.songRequestMaxList = this.toolsConfig.songRequestMaxList
|
this.songRequestMaxList = this.toolsConfig.songRequestMaxList
|
||||||
// 视频保存路径
|
// 视频保存路径
|
||||||
this.defaultPath = this.toolsConfig.defaultPath;
|
this.defaultPath = this.toolsConfig.defaultPath;
|
||||||
|
// uid
|
||||||
|
this.uid = this.toolsConfig.neteaseUserId
|
||||||
}
|
}
|
||||||
|
|
||||||
async pickSong(e) {
|
async pickSong(e) {
|
||||||
@ -59,6 +83,7 @@ export class songRequest extends plugin {
|
|||||||
logger.info('当前未开启网易云点歌')
|
logger.info('当前未开启网易云点歌')
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
// 获取自定义API
|
||||||
const autoSelectNeteaseApi = await this.pickApi()
|
const autoSelectNeteaseApi = await this.pickApi()
|
||||||
// 只在群里可以使用
|
// 只在群里可以使用
|
||||||
let group_id = e.group.group_id
|
let group_id = e.group.group_id
|
||||||
@ -68,17 +93,35 @@ export class songRequest extends plugin {
|
|||||||
const saveId = songInfo.findIndex(item => item.group_id === e.group.group_id)
|
const saveId = songInfo.findIndex(item => item.group_id === e.group.group_id)
|
||||||
let musicDate = { 'group_id': group_id, data: [] }
|
let musicDate = { 'group_id': group_id, data: [] }
|
||||||
// 获取搜索歌曲列表信息
|
// 获取搜索歌曲列表信息
|
||||||
let searchUrl = autoSelectNeteaseApi + '/search?keywords={}&limit=' + this.songRequestMaxList //搜索API
|
|
||||||
let detailUrl = autoSelectNeteaseApi + "/song/detail?ids={}" //歌曲详情API
|
let detailUrl = autoSelectNeteaseApi + "/song/detail?ids={}" //歌曲详情API
|
||||||
if (e.msg.replace(/\s+/g, "").match(/点歌(.+)/)) {
|
if (e.msg.replace(/\s+/g, "").match(/点歌(.+)/)) {
|
||||||
const songKeyWord = e.msg.replace(/\s+/g, "").match(/点歌(.+)/)[1]
|
const songKeyWord = e.msg.replace(/\s+/g, "").match(/点歌(.+)/)[1]
|
||||||
|
// 获取云盘歌单列表
|
||||||
|
const cloudSongList = await this.getCloudSong()
|
||||||
|
// 搜索云盘歌单并进行搜索
|
||||||
|
const matchedSongs = await cloudSongList.filter(({ songName, singerName }) =>
|
||||||
|
songName.includes(songKeyWord) || singerName.includes(songKeyWord)
|
||||||
|
);
|
||||||
|
// 计算列表数 计算偏移量
|
||||||
|
let songListCount = matchedSongs.length >= this.songRequestMaxList ? this.songRequestMaxList : matchedSongs.length
|
||||||
|
let searchCount = this.songRequestMaxList - songListCount
|
||||||
|
for (let i = 0; i < songListCount; i++) {
|
||||||
|
musicDate.data.push({
|
||||||
|
'id': matchedSongs[i].id,
|
||||||
|
'songName': matchedSongs[i].songName,
|
||||||
|
'singerName': matchedSongs[i].singerName,
|
||||||
|
'duration': matchedSongs[i].duration
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let searchUrl = autoSelectNeteaseApi + '/search?keywords={}&limit=' + searchCount + '&offset=' + songListCount//搜索API
|
||||||
searchUrl = searchUrl.replace("{}", songKeyWord)
|
searchUrl = searchUrl.replace("{}", songKeyWord)
|
||||||
await axios.get(searchUrl, {
|
await axios.get(searchUrl, {
|
||||||
headers: {
|
headers: {
|
||||||
"User-Agent": COMMON_USER_AGENT
|
"User-Agent": COMMON_USER_AGENT
|
||||||
},
|
},
|
||||||
}).then(async res => {
|
}).then(async res => {
|
||||||
if (res.data.result.songs) {
|
if (res.data.result.songs || musicDate.data[0]) {
|
||||||
|
try {
|
||||||
for (const info of res.data.result.songs) {
|
for (const info of res.data.result.songs) {
|
||||||
musicDate.data.push({
|
musicDate.data.push({
|
||||||
'id': info.id,
|
'id': info.id,
|
||||||
@ -87,6 +130,9 @@ export class songRequest extends plugin {
|
|||||||
'duration': formatTime(info.duration)
|
'duration': formatTime(info.duration)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logger.info('并未获取云服务歌曲')
|
||||||
|
}
|
||||||
const ids = musicDate.data.map(item => item.id).join(',');
|
const ids = musicDate.data.map(item => item.id).join(',');
|
||||||
detailUrl = detailUrl.replace("{}", ids)
|
detailUrl = detailUrl.replace("{}", ids)
|
||||||
await axios.get(detailUrl, {
|
await axios.get(detailUrl, {
|
||||||
@ -185,8 +231,46 @@ export class songRequest extends plugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 获取云盘信息
|
||||||
|
async myCloud(e) {
|
||||||
|
const autoSelectNeteaseApi = await this.pickApi()
|
||||||
|
const cloudUrl = autoSelectNeteaseApi + '/user/cloud'
|
||||||
|
// 云盘数据API
|
||||||
|
await axios.get(cloudUrl, {
|
||||||
|
headers: {
|
||||||
|
"User-Agent": COMMON_USER_AGENT,
|
||||||
|
"Cookie": this.neteaseCookie
|
||||||
|
},
|
||||||
|
}).then(res => {
|
||||||
|
const cloudData = {
|
||||||
|
'songCount': res.data.count,
|
||||||
|
'useSize': toGBorTB(res.data.size),
|
||||||
|
'cloudSize': toGBorTB(res.data.maxSize)
|
||||||
|
}
|
||||||
|
e.reply(`云盘数据\n歌曲数量:${cloudData.songCount}\n云盘容量:${cloudData.cloudSize}\n已使用容量:${cloudData.useSize}\n数据可能有延迟`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新云盘
|
||||||
|
async songCloudUpdate(e) {
|
||||||
|
try {
|
||||||
|
await this.cleanCloudData()
|
||||||
|
await this.getCloudSong(e, true)
|
||||||
|
try {
|
||||||
|
await e?.reply('更新成功')
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('trss又拉屎了?')
|
||||||
|
}
|
||||||
|
await this.myCloud(e)
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('更新云盘失败', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传音频文件
|
||||||
async upLoad(e) {
|
async upLoad(e) {
|
||||||
let msg = await e.getReply();
|
let msg = await e?.getReply();
|
||||||
const musicUrlReg = /(http:|https:)\/\/music.163.com\/song\/media\/outer\/url\?id=(\d+)/;
|
const musicUrlReg = /(http:|https:)\/\/music.163.com\/song\/media\/outer\/url\?id=(\d+)/;
|
||||||
const musicUrlReg2 = /(http:|https:)\/\/y.music.163.com\/m\/song\?(.*)&id=(\d+)/;
|
const musicUrlReg2 = /(http:|https:)\/\/y.music.163.com\/m\/song\?(.*)&id=(\d+)/;
|
||||||
const musicUrlReg3 = /(http:|https:)\/\/music.163.com\/m\/song\/(\d+)/;
|
const musicUrlReg3 = /(http:|https:)\/\/music.163.com\/m\/song\/(\d+)/;
|
||||||
@ -198,17 +282,122 @@ export class songRequest extends plugin {
|
|||||||
const title = msg.message[0].data.match(/"title":"([^"]+)"/)[1]
|
const title = msg.message[0].data.match(/"title":"([^"]+)"/)[1]
|
||||||
const desc = msg.message[0].data.match(/"desc":"([^"]+)"/)[1]
|
const desc = msg.message[0].data.match(/"desc":"([^"]+)"/)[1]
|
||||||
if (id === "") return
|
if (id === "") return
|
||||||
let path = this.getCurDownloadPath(e) + '/' + title + '-' + desc + '.' + 'flac'
|
let path = this.getCurDownloadPath(e) + '/' + title + '-' + desc + '.flac'
|
||||||
try {
|
try {
|
||||||
// 上传群文件
|
// 上传群文件
|
||||||
await this.uploadGroupFile(e, path);
|
await this.uploadGroupFile(e, path);
|
||||||
// 删除文件
|
// 删除文件
|
||||||
await checkAndRemoveFile(path);
|
await checkAndRemoveFile(path);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(error)
|
logger.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 上传云盘
|
||||||
|
async uploadCloud(e) {
|
||||||
|
let msg = await e?.getReply();
|
||||||
|
const autoSelectNeteaseApi = await this.pickApi()
|
||||||
|
const musicUrlReg = /(http:|https:)\/\/music.163.com\/song\/media\/outer\/url\?id=(\d+)/;
|
||||||
|
const musicUrlReg2 = /(http:|https:)\/\/y.music.163.com\/m\/song\?(.*)&id=(\d+)/;
|
||||||
|
const musicUrlReg3 = /(http:|https:)\/\/music.163.com\/m\/song\/(\d+)/;
|
||||||
|
const id =
|
||||||
|
musicUrlReg2.exec(msg.message[0].data)?.[3] ||
|
||||||
|
musicUrlReg.exec(msg.message[0].data)?.[2] ||
|
||||||
|
musicUrlReg3.exec(msg.message[0].data)?.[2] ||
|
||||||
|
/(?<!user)id=(\d+)/.exec(msg.message[0].data)[1] || "";
|
||||||
|
const title = msg.message[0].data.match(/"title":"([^"]+)"/)[1]
|
||||||
|
const desc = msg.message[0].data.match(/"desc":"([^"]+)"/)[1]
|
||||||
|
if (id === "") return
|
||||||
|
let path = this.getCurDownloadPath(e) + '/' + title + '-' + desc + '.flac'
|
||||||
|
let tryCount = 0
|
||||||
|
const tryUpload = async () => {
|
||||||
|
let formData = new FormData()
|
||||||
|
await formData.append('songFile', fs.createReadStream(path))
|
||||||
|
const headers = {
|
||||||
|
...formData.getHeaders(),
|
||||||
|
'Cookie': this.neteaseCookie,
|
||||||
|
};
|
||||||
|
const updateUrl = autoSelectNeteaseApi + `/cloud?time=${Date.now()}`
|
||||||
|
axios({
|
||||||
|
method: 'post',
|
||||||
|
url: updateUrl,
|
||||||
|
headers: headers,
|
||||||
|
data: formData,
|
||||||
|
})
|
||||||
|
.then(async res => {
|
||||||
|
if (res.data.code == 200) {
|
||||||
|
let matchUrl = autoSelectNeteaseApi + '/cloud/match?uid=' + this.uid + "&sid=" + res.data.privateCloud.songId + '&asid=' + id
|
||||||
|
await axios.get(matchUrl, {
|
||||||
|
headers: {
|
||||||
|
"User-Agent": COMMON_USER_AGENT,
|
||||||
|
"Cookie": this.neteaseCookie
|
||||||
|
},
|
||||||
|
}).then(res => {
|
||||||
|
logger.info('歌曲信息匹配成功')
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
logger.error('歌曲信息匹配错误', error)
|
||||||
|
})
|
||||||
|
this.songCloudUpdate(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
tryCount += 1;
|
||||||
|
logger.info('失败喽~再试一次')
|
||||||
|
if (tryCount < 3) {
|
||||||
|
tryUpload(); // 直接调用
|
||||||
|
} else {
|
||||||
|
logger.error('怎么想都传不上去吧', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
};
|
||||||
|
tryUpload();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取云盘歌单
|
||||||
|
async getCloudSong(e, cloudUpdate = false) {
|
||||||
|
let songList = await redisGetKey(REDIS_YUNZAI_CLOUDSONGLIST) || []
|
||||||
|
if (!songList[0] || cloudUpdate) {
|
||||||
|
const autoSelectNeteaseApi = await this.pickApi();
|
||||||
|
const limit = 100;
|
||||||
|
let offset = 0;
|
||||||
|
let cloudUrl = autoSelectNeteaseApi + `/user/cloud?limit=${limit}&offset=${offset}×tamp=${Date.now()}`;
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
const res = await axios.get(cloudUrl, {
|
||||||
|
headers: {
|
||||||
|
"User-Agent": COMMON_USER_AGENT,
|
||||||
|
"Cookie": this.neteaseCookie
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const songs = res.data.data.map(({ simpleSong }) => ({
|
||||||
|
'songName': simpleSong.name,
|
||||||
|
'id': simpleSong.id,
|
||||||
|
'singerName': simpleSong.ar[0].name || '喵喵~',
|
||||||
|
'duration': '云盘'
|
||||||
|
}));
|
||||||
|
songList.push(...songs);
|
||||||
|
if (!res.data.hasMore) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
offset += limit;
|
||||||
|
cloudUrl = autoSelectNeteaseApi + `/user/cloud?limit=${limit}&offset=${offset}`;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("获取歌单失败", error);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await redisSetKey(REDIS_YUNZAI_CLOUDSONGLIST, songList)
|
||||||
|
return songList;
|
||||||
|
} else {
|
||||||
|
return songList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async cleanCloudData(e) {
|
||||||
|
await redisSetKey(REDIS_YUNZAI_CLOUDSONGLIST, [])
|
||||||
|
}
|
||||||
|
|
||||||
// 判断是否海外服务器
|
// 判断是否海外服务器
|
||||||
async isOverseasServer() {
|
async isOverseasServer() {
|
||||||
@ -237,7 +426,6 @@ export class songRequest extends plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 检测cooike活性
|
// 检测cooike活性
|
||||||
|
|
||||||
async checkCooike(statusUrl) {
|
async checkCooike(statusUrl) {
|
||||||
let status
|
let status
|
||||||
await axios.get(statusUrl, {
|
await axios.get(statusUrl, {
|
||||||
@ -245,8 +433,9 @@ export class songRequest extends plugin {
|
|||||||
"User-Agent": COMMON_USER_AGENT,
|
"User-Agent": COMMON_USER_AGENT,
|
||||||
"Cookie": this.neteaseCookie
|
"Cookie": this.neteaseCookie
|
||||||
},
|
},
|
||||||
}).then(res => {
|
}).then(async res => {
|
||||||
const userInfo = res.data.data.profile
|
const userInfo = res.data.data.profile
|
||||||
|
await config.updateField("tools", "neteaseUserId", res.data.data.profile.userId);
|
||||||
if (userInfo) {
|
if (userInfo) {
|
||||||
logger.info('ck活着,使用ck进行高音质下载')
|
logger.info('ck活着,使用ck进行高音质下载')
|
||||||
status = true
|
status = true
|
||||||
@ -306,11 +495,11 @@ export class songRequest extends plugin {
|
|||||||
},
|
},
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
const wikiData = res.data.data.blocks[1].creatives
|
const wikiData = res.data.data.blocks[1].creatives
|
||||||
try {
|
|
||||||
typelist.push(wikiData[0].resources[0]?.uiElement?.mainTitle?.title || "")
|
typelist.push(wikiData[0].resources[0].uiElement.mainTitle.title)
|
||||||
// 防止数据过深出错
|
// 防止数据过深出错
|
||||||
const recTags = wikiData[1]
|
const recTags = wikiData[1]
|
||||||
if (recTags?.resources[0]) {
|
if (recTags.resources[0]) {
|
||||||
for (let i = 0; i < Math.min(3, recTags.resources.length); i++) {
|
for (let i = 0; i < Math.min(3, recTags.resources.length); i++) {
|
||||||
if (recTags.resources[i] && recTags.resources[i].uiElement && recTags.resources[i].uiElement.mainTitle.title) {
|
if (recTags.resources[i] && recTags.resources[i].uiElement && recTags.resources[i].uiElement.mainTitle.title) {
|
||||||
typelist.push(recTags.resources[i].uiElement.mainTitle.title)
|
typelist.push(recTags.resources[i].uiElement.mainTitle.title)
|
||||||
@ -322,10 +511,7 @@ export class songRequest extends plugin {
|
|||||||
if (wikiData[2].uiElement.mainTitle.title == 'BPM') {
|
if (wikiData[2].uiElement.mainTitle.title == 'BPM') {
|
||||||
typelist.push('BPM ' + wikiData[2].uiElement.textLinks[0].text)
|
typelist.push('BPM ' + wikiData[2].uiElement.textLinks[0].text)
|
||||||
} else {
|
} else {
|
||||||
typelist.push(wikiData[2].uiElement.textLinks[0].text || '')
|
typelist.push(wikiData[2].uiElement.textLinks[0].text)
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
logger.error('获取标签报错:', error)
|
|
||||||
}
|
}
|
||||||
typelist.push(AudioLevel)
|
typelist.push(AudioLevel)
|
||||||
})
|
})
|
||||||
|
@ -29,6 +29,7 @@ songRequestMaxList: 10 # 网易云点歌请求最大列表数
|
|||||||
neteaseCookie: '' # 网易云ck
|
neteaseCookie: '' # 网易云ck
|
||||||
neteaseCloudAPIServer: '' # 网易云自建服务器地址
|
neteaseCloudAPIServer: '' # 网易云自建服务器地址
|
||||||
neteaseCloudAudioQuality: exhigh # 网易云解析最高音质 默认exhigh(极高) 分类:standard => 标准,higher => 较高, exhigh=>极高, lossless=>无损, hires=>Hi-Res, jyeffect => 高清环绕声, sky => 沉浸环绕声, dolby => 杜比全景声, jymaster => 超清母带
|
neteaseCloudAudioQuality: exhigh # 网易云解析最高音质 默认exhigh(极高) 分类:standard => 标准,higher => 较高, exhigh=>极高, lossless=>无损, hires=>Hi-Res, jyeffect => 高清环绕声, sky => 沉浸环绕声, dolby => 杜比全景声, jymaster => 超清母带
|
||||||
|
neteaseUserId: '' # 网易云用户ID 不要手动更改!!!!除非你非常清楚你在做什么
|
||||||
|
|
||||||
youtubeGraphicsOptions: 720 # YouTobe的下载画质,0为原画,1080,720,480,自定义画面高度(默认为720)
|
youtubeGraphicsOptions: 720 # YouTobe的下载画质,0为原画,1080,720,480,自定义画面高度(默认为720)
|
||||||
youtubeClipTime: 0 # YouTobe限制的最大视频时长(默认不开启),单位:秒 最好不要超过5分钟,否则截取效率非常低
|
youtubeClipTime: 0 # YouTobe限制的最大视频时长(默认不开启),单位:秒 最好不要超过5分钟,否则截取效率非常低
|
||||||
|
@ -80,6 +80,11 @@ export const REDIS_YUNZAI_ISOVERSEA = "Yz:rconsole:tools:oversea";
|
|||||||
*/
|
*/
|
||||||
export const REDIS_YUNZAI_SONGINFO = "Yz:rconsole:tools:songinfo";
|
export const REDIS_YUNZAI_SONGINFO = "Yz:rconsole:tools:songinfo";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存网易云云盘列表
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
export const REDIS_YUNZAI_CLOUDSONGLIST = "Yz:rconsole:tools:cloudsonglist";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 某些功能的解析白名单
|
* 某些功能的解析白名单
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.3.4",
|
"axios": "^1.3.4",
|
||||||
|
"form-data": "^4.0.1",
|
||||||
"qrcode": "^1.5.3",
|
"qrcode": "^1.5.3",
|
||||||
"p-queue": "^8.0.1"
|
"p-queue": "^8.0.1"
|
||||||
}
|
}
|
||||||
|
@ -128,6 +128,10 @@ html {
|
|||||||
box-shadow: 0px 0px 3px rgba(255, 255, 255, 0.4);
|
box-shadow: 0px 0px 3px rgba(255, 255, 255, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.typeNav:first-child {
|
||||||
|
margin-left: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
.logo{
|
.logo{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -62,11 +62,30 @@ html {
|
|||||||
|
|
||||||
.navDuration {
|
.navDuration {
|
||||||
color: #aaa;
|
color: #aaa;
|
||||||
width: 40px;
|
width: 70px;
|
||||||
font-size: 25px;
|
font-size: 25px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.cloudBox{
|
||||||
|
height: 100%;
|
||||||
|
width: 70px;
|
||||||
|
justify-content: center;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cloud{
|
||||||
|
color: #dd001b;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0px 8px;
|
||||||
|
font-size: 22px;
|
||||||
|
height: 40px;
|
||||||
|
width: 70px;
|
||||||
|
border-radius: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
border: 1px solid;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,6 +93,7 @@ html {
|
|||||||
width: 90px;
|
width: 90px;
|
||||||
height: 90px;
|
height: 90px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bgicon {
|
.bgicon {
|
||||||
@ -104,3 +124,12 @@ html {
|
|||||||
margin-left: -20px;
|
margin-left: -20px;
|
||||||
font-family: 'number'
|
font-family: 'number'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.footer{
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 20px;
|
||||||
|
margin-top: 20px;
|
||||||
|
color: rgba(255, 255, 255, 0.7);
|
||||||
|
font-family: 'number';
|
||||||
|
}
|
@ -22,12 +22,19 @@
|
|||||||
<div class="singerText">{{ info.singerName }}</div>
|
<div class="singerText">{{ info.singerName }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{ if info.duration == '云盘' }}
|
||||||
|
<div class="cloudBox">
|
||||||
|
<div class="cloud">{{ info.duration }}</div>
|
||||||
|
</div>
|
||||||
|
{{ else }}
|
||||||
<div class="navDuration">{{ info.duration }}</div>
|
<div class="navDuration">{{ info.duration }}</div>
|
||||||
|
{{ /if }}
|
||||||
</div>
|
</div>
|
||||||
{{ /each }}
|
{{ /each }}
|
||||||
<div class="bgicon">
|
<div class="bgicon">
|
||||||
<img src="{{pluResPath}}img/icon/neteaseRank.png" alt="">
|
<img src="{{pluResPath}}img/icon/neteaseRank.png" alt="">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="footer">Created By Yunzai-Bot & R-Plugin</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
@ -9,3 +9,15 @@ export function formatTime(timestamp) {
|
|||||||
|
|
||||||
return `${formattedMinutes}:${formattedSeconds}`;
|
return `${formattedMinutes}:${formattedSeconds}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function toGBorTB(Bytes) {
|
||||||
|
const GB = 1024 ** 3;
|
||||||
|
let sizeInGB = Bytes / GB;
|
||||||
|
let unit = "GB";
|
||||||
|
if (sizeInGB > 1024) {
|
||||||
|
sizeInGB /= 1024;
|
||||||
|
unit = "TB";
|
||||||
|
}
|
||||||
|
sizeInGB = sizeInGB % 1 === 0 ? sizeInGB.toString() : sizeInGB.toFixed(2);
|
||||||
|
return sizeInGB + unit;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user