1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
| import Router from 'koa-router' import multiparty from 'multiparty' import path from 'node:path' import {fileURLToPath} from 'node:url'; import fse from 'fs-extra' import fs from 'node:fs' const router = new Router() const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename);
const hash2path = {}
router.get('/checkExists/:hash', async (ctx, next) => { const { hash } = ctx.params if (hash2path[hash]) { console.log('已经上传过了') ctx.body = { success: true, msg: '已经上传过了', code: 1, path: hash2path[hash] } } else { ctx.body = { success: true, msg: '没有上传过', code: 0, path: null } } })
router.post('/upload', async (ctx, next) => { const form = new multiparty.Form() const msg = await writeChunk(form, ctx.req) ctx.body = { success: true, msg, } })
router.get('/mergeFile/:md5/:name', async (ctx, next) => { const {md5, name} = ctx.params const dirPath = path.resolve(__dirname,'chunks/' + md5) const targetDir = path.resolve(__dirname, 'files') if(!fse.existsSync(targetDir)) { await fse.mkdirs(targetDir) } const filePath = path.resolve(targetDir, name) let dests = fse.readdirSync(dirPath) dests = dests.sort((a, b) => { return Number(a) - Number(b) }) await mergeFile(dests, filePath, dirPath) await fse.remove(dirPath) hash2path[md5] = filePath ctx.body = { success: true, msg: 'success', file: filePath } }) function writeChunk(form, req) { return new Promise((resolve, reject) => { form.parse(req, async (err, fields, files) => { if (err) return; const [file] = files.file const [hash] = fields.hash const [start] = fields.start const chunkDir = path.resolve(__dirname, 'chunks/' + hash) if (!fse.existsSync(chunkDir)) { await fse.mkdirs(chunkDir) } if (!fse.existsSync(chunkDir + '/' + start)) { await fse.move(file.path, `${chunkDir}/${start}`) } resolve('上传成功') }) }) }
const mergeFile = async (dests, filePath, dirPath) => { let ws = fs.createWriteStream(filePath) for (let i = 0; i < dests.length; i ++) { const chunkPath = path.resolve(__dirname, dirPath + '/' + dests[i]) await write(ws, chunkPath) } }
const write = (ws, chunkPath) => { return new Promise(resolve => { let rs = fs.createReadStream(chunkPath) rs.pipe(ws, { end: false}) rs.on('end', () => { resolve() }) }) }
export default router
|