From a09f126ab2e7bb3bbbd2abd73ad7e8ff0ce178ab Mon Sep 17 00:00:00 2001 From: LaoShui <79132480+laoshuikaixue@users.noreply.github.com> Date: Wed, 18 Feb 2026 19:09:15 +0800 Subject: [PATCH] =?UTF-8?q?fix(upload):=20=E4=BF=AE=E5=A4=8D=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E4=B8=8A=E4=BC=A0=E5=8A=9F=E8=83=BD=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E6=9B=BF=E6=8D=A2=E5=92=8C=E4=B8=B4=E6=97=B6?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将单个斜杠替换改为全局正则替换以正确处理所有路径分隔符 - 移除未使用的 crypto 模块引入 - 添加对临时文件上传的支持,使用 fs 模块读取临时文件 - 动态设置 Content-Type 头部,优先使用文件的 mimetype 属性 - 重构多处文件上传逻辑以支持流式读取大文件 - 优化分片上传时的文件大小获取方式 --- module/cloud_upload_token.js | 5 ++-- module/voice_upload.js | 51 +++++++++++++++++++++++------------- plugins/songUpload.js | 4 +-- plugins/upload.js | 14 ++++++++-- 4 files changed, 49 insertions(+), 25 deletions(-) diff --git a/module/cloud_upload_token.js b/module/cloud_upload_token.js index 4238526..c7ff727 100644 --- a/module/cloud_upload_token.js +++ b/module/cloud_upload_token.js @@ -1,5 +1,5 @@ +const { default: axios } = require('axios') const createOption = require('../util/option.js') -const crypto = require('crypto') module.exports = async (query, request) => { const { md5, fileSize, filename, bitrate = 999000 } = query @@ -55,7 +55,6 @@ module.exports = async (query, request) => { }) } - const { default: axios } = require('axios') let lbs try { lbs = ( @@ -97,7 +96,7 @@ module.exports = async (query, request) => { uploadToken: tokenRes.body.result.token, objectKey: tokenRes.body.result.objectKey, resourceId: tokenRes.body.result.resourceId, - uploadUrl: `${lbs.upload[0]}/${bucket}/${tokenRes.body.result.objectKey.replace('/', '%2F')}?offset=0&complete=true&version=1.0`, + uploadUrl: `${lbs.upload[0]}/${bucket}/${tokenRes.body.result.objectKey.replace(/\//g, '%2F')}?offset=0&complete=true&version=1.0`, bucket: bucket, md5: md5, fileSize: fileSize, diff --git a/module/voice_upload.js b/module/voice_upload.js index dbbd6b7..5b993b8 100644 --- a/module/voice_upload.js +++ b/module/voice_upload.js @@ -1,17 +1,17 @@ const { default: axios } = require('axios') +const fs = require('fs') var xml2js = require('xml2js') const createOption = require('../util/option.js') -var parser = new xml2js.Parser(/* options */) +var parser = new xml2js.Parser() function createDupkey() { - // 格式:3b443c7c-a87f-468d-ba38-46d407aaf23a var s = [] var hexDigits = '0123456789abcdef' for (var i = 0; i < 36; i++) { s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1) } - s[14] = '4' // bits 12-15 of the time_hi_and_version field to 0010 - s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1) // bits 6-7 of the clock_seq_hi_and_reserved to 01 + s[14] = '4' + s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1) s[8] = s[13] = s[18] = s[23] = '-' return s.join('') } @@ -50,43 +50,60 @@ module.exports = async (query, request) => { createOption(query, 'weapi'), ) - const objectKey = tokenRes.body.result.objectKey.replace('/', '%2F') + const objectKey = tokenRes.body.result.objectKey.replace(/\//g, '%2F') const docId = tokenRes.body.result.docId const res = await axios({ method: 'post', url: `https://ymusic.nos-hz.163yun.com/${objectKey}?uploads`, headers: { 'x-nos-token': tokenRes.body.result.token, - 'X-Nos-Meta-Content-Type': 'audio/mpeg', + 'X-Nos-Meta-Content-Type': query.songFile.mimetype || 'audio/mpeg', }, data: null, }) - // return xml + const res2 = await parser.parseStringPromise(res.data) - const fileSize = query.songFile.data.length - const blockSize = 10 * 1024 * 1024 // 10MB + const useTempFile = !!query.songFile.tempFilePath + let fileSize = query.songFile.size + let fileData + + if (useTempFile) { + const stats = await fs.promises.stat(query.songFile.tempFilePath) + fileSize = stats.size + fileData = query.songFile.tempFilePath + } else { + fileSize = query.songFile.data.length + fileData = query.songFile.data + } + + const blockSize = 10 * 1024 * 1024 let offset = 0 let blockIndex = 1 let etags = [] while (offset < fileSize) { - const chunk = query.songFile.data.slice( - offset, - Math.min(offset + blockSize, fileSize), - ) + let chunk + if (useTempFile) { + const fd = await fs.promises.open(query.songFile.tempFilePath, 'r') + const buffer = Buffer.alloc(Math.min(blockSize, fileSize - offset)) + await fd.read(buffer, 0, buffer.length, offset) + await fd.close() + chunk = buffer + } else { + chunk = query.songFile.data.slice(offset, Math.min(offset + blockSize, fileSize)) + } const res3 = await axios({ method: 'put', url: `https://ymusic.nos-hz.163yun.com/${objectKey}?partNumber=${blockIndex}&uploadId=${res2.InitiateMultipartUploadResult.UploadId[0]}`, headers: { 'x-nos-token': tokenRes.body.result.token, - 'Content-Type': 'audio/mpeg', + 'Content-Type': query.songFile.mimetype || 'audio/mpeg', }, data: chunk, }) - // get etag const etag = res3.headers.etag etags.push(etag) offset += blockSize @@ -101,19 +118,17 @@ module.exports = async (query, request) => { } completeStr += '' - // 文件处理 await axios({ method: 'post', url: `https://ymusic.nos-hz.163yun.com/${objectKey}?uploadId=${res2.InitiateMultipartUploadResult.UploadId[0]}`, headers: { 'Content-Type': 'text/plain;charset=UTF-8', - 'X-Nos-Meta-Content-Type': 'audio/mpeg', + 'X-Nos-Meta-Content-Type': query.songFile.mimetype || 'audio/mpeg', 'x-nos-token': tokenRes.body.result.token, }, data: completeStr, }) - // preCheck await request( `/api/voice/workbench/voice/batch/upload/preCheck`, { diff --git a/plugins/songUpload.js b/plugins/songUpload.js index 13c88ac..225b236 100644 --- a/plugins/songUpload.js +++ b/plugins/songUpload.js @@ -38,7 +38,7 @@ module.exports = async (query, request) => { } } - const objectKey = tokenRes.body.result.objectKey.replace('/', '%2F') + const objectKey = tokenRes.body.result.objectKey.replace(/\//g, '%2F') let lbs try { lbs = ( @@ -87,7 +87,7 @@ module.exports = async (query, request) => { headers: { 'x-nos-token': tokenRes.body.result.token, 'Content-MD5': query.songFile.md5, - 'Content-Type': 'audio/mpeg', + 'Content-Type': query.songFile.mimetype || 'audio/mpeg', 'Content-Length': String(query.songFile.size), }, data: uploadData, diff --git a/plugins/upload.js b/plugins/upload.js index dcd3f5b..647004d 100644 --- a/plugins/upload.js +++ b/plugins/upload.js @@ -1,5 +1,7 @@ const { default: axios } = require('axios') +const fs = require('fs') const createOption = require('../util/option.js') + module.exports = async (query, request) => { const data = { bucket: 'yyimgs', @@ -17,14 +19,22 @@ module.exports = async (query, request) => { createOption(query, 'weapi'), ) // 上传图片 + const useTempFile = !!query.imgFile.tempFilePath + let uploadData + if (useTempFile) { + uploadData = fs.createReadStream(query.imgFile.tempFilePath) + } else { + uploadData = query.imgFile.data + } + const res2 = await axios({ method: 'post', url: `https://nosup-hz1.127.net/yyimgs/${res.body.result.objectKey}?offset=0&complete=true&version=1.0`, headers: { 'x-nos-token': res.body.result.token, - 'Content-Type': 'image/jpeg', + 'Content-Type': query.imgFile.mimetype || 'image/jpeg', }, - data: query.imgFile.data, + data: uploadData, }) return {