import Router from '@koa/router'; import { koaBody } from 'koa-body'; import { copyFile, rm, access, mkdir } from 'node:fs/promises'; import { UPLOAD_DIR, STATIC, SECRET } from '../app.config.mjs'; import jwt from 'jsonwebtoken'; import tokenVerify from '../middlewares/jwt.verify.js'; const router = new Router(); import { createHash } from 'node:crypto'; // 密码加密: md5 属于 hash加密算法 // 通过router实例的一些方法 比如 get、post等去定义 对应请求方法的路由 router .post('/register', async (ctx) => { let { username, password } = ctx.request.body; password = createHash('md5').update(password).digest('hex'); let sql = 'insert into Users(username, password, status, create_time) values(?, ?, 1, NOW());'; try { let res = await ctx.execute(sql, [username, password]); if (res.affectedRows === 1) { ctx.body = { code: 0, message: '注册成功', }; } else { ctx.body = { code: 1, message: '注册失败', }; } } catch (err) { // 执行sql语句发生异常 console.log(err); ctx.body = { code: 1, message: '网络超时', }; } }) .post('/login', async (ctx) => { let { username, password } = ctx.request.body; // 由于用户注册时 密码使用了md5加密 因此 这里 也需要将密码加密后 在去查询 password = createHash('md5').update(password).digest('hex'); let sql = `SELECT * FROM Users WHERE username = ? AND password = ?;`; let res = await ctx.execute(sql, [username, password]); if (res.length > 0) { // 如果认证成功 // 1 制作token // console.log(jwt); const token = jwt.sign(res[0], SECRET, { expiresIn: '1h' }); // 2 将token值和登录用户信息 一同响应给客户端 ctx.body = { code: 0, message: '登录成功', data: { userInfo: res[0], token, }, }; } else { ctx.body = { code: 1, message: '用户名或密码不正确', }; } }) .get('/', tokenVerify({ secret: SECRET }), async (ctx) => { let res = await ctx.execute('select * from users;'); ctx.status = 200; ctx.body = res === false ? { code: 1, message: '请求超时', } : { code: 0, msg: '成功', data: res, }; }) .put( '/upload', tokenVerify({ secret: SECRET }), koaBody({ multipart: true, formidable: { keepExtensions: true, uploadDir: UPLOAD_DIR, // 设置上传文件的最终位置 }, onError(err, ctx) { ctx.body = { code: 1, msg: err, }; }, }), async (ctx) => { let filename = ctx.request.files.file.newFilename; let srcFile = `./${UPLOAD_DIR}/${filename}`; let destFile = srcFile; // 获取 请求体 中 除了file文件之外的其他数据 const { folder } = ctx.request.body; // 如果用户在上传文件时 指定了目标文件夹 if (folder) { // 1 将默认上传位置的文件 拷贝到 目标的文件夹下 destFile = `./${UPLOAD_DIR}/${folder}/${filename}`; try { // 先确保destFile的文件夹都真实存在 let isExist = await access(`./${UPLOAD_DIR}/${folder}`).catch( () => false ); // isExist 就是 undefined 或者 false if (isExist == false) { // 如果不存在 就创建 await mkdir(`./${UPLOAD_DIR}/${folder}`, { recursive: true }); } await copyFile(srcFile, destFile); // 2 成功后 删除默认位置的文件 await rm(srcFile); } catch (error) { console.error(error); } } // 给客户端响应数据 ctx.body = { code: 0, data: { path: `${UPLOAD_DIR.replace(STATIC, '')}/${folder}/${filename}`, filename, }, msg: '上传成功', }; } ); export default router;