const {koaBody} = require('koa-body'); const Koa = require('koa'); const fs = require('fs'); const path = require('path'); const { spawn } = require('child_process') const router = require('koa-router')() , os = require('os') , iconv = require("iconv-lite") const moment = require('moment') const { DATABASELIST, SERVER_PORT} = require('./config') // 备份间隔时间 const mintues = 60 * 24;// minute // web服务 function server(){ const app = new Koa(); app.use(koaBody({ multipart: true, // 支持文件上传 formidable: { maxFieldsSize: 500 * 1024 * 1024, // 最大文件为2兆 multipart: true // 是否支持 multipart-formdate 的表单 } })); router.post('/putfile', async ctx => { const fileList = await getFileList() console.log('请求备份', fileList) if(fileList.length == 0){ ctx.body = [{state:false,filename:'无备份文件'}] }else{ const bunneryList = await readFile(fileList) ctx.body = bunneryList deleteFile(fileList) } }); app.use(router.routes(), router.allowedMethods()) app.listen(SERVER_PORT, () => { console.log('=> 备份服务已启动! http://127.0.0.1:' + SERVER_PORT) }); } // 本分服务 function back(){ /** * 数据库备份程序 * */ function backSQL(host, user, passwd, database){ return new Promise(rec => { const cout = os.platform() == 'win32' ? '-r' : '>' , filename = `back/BACKUP_${ database }_${ moment().format("YYYY_MM_DD_HH_mm_ss") }.sql` const backProcess = spawn('mysqldump',['-u'+user, '-p'+passwd, database, cout + filename]); backProcess.stdout.on('data', data => console.log('Data : ', out(data))) backProcess.stderr.on('data', data => console.log('Error: ', out(data))) backProcess.on('close', code => { console.log('Exit :', code.toString()) rec(filename) }) }) } // 开始备份数据库 function startBackSQL(){ // 数据库信息 let host = "localhost" , user = "root" , passwd = "root" , database = "develop" backSQL(host, user, passwd, database) const outTime = getT() - new Date().getTime() for(let item in DATABASELIST){ const i = DATABASELIST[item]; database = i; setTimeout(() => { setInterval(() => { backSQL(host, user, passwd, database) }, 1000 * 60 * mintues) },outTime) } } /** * 根据系统类型,读取编码格式 * */ function out(data){ if(os.platform() == 'win32'){ return iconv.decode(data, 'GBK') }else{ return data } } // 读取文件目录 function getFileList(){ return new Promise((rec, res) => { fs.readdir(__dirname + '/back', (err, fileList) => { if(err){ res(err) }else{ rec(fileList) } }) }) } // 读取文件 function readFile(fileList){ return new Promise(rec => { const list = [] for(let i in fileList){ fs.readFile(__dirname + '/back/' + fileList[i],'utf8',function(err,datastr){ if(err){ list.push({ state:false, filename:fileList[i] }) }else{ list.push({ state:true, filename:fileList[i], file:datastr }) } if(i == fileList.length -1){ rec(list) } }) } }) } // 删除文件 function deleteFile(filelist){ for(let filename of filelist){ fs.unlink(__dirname + '/back/' + filename, (e, data) => { if(e){ console.log('删除文件失败:', filename) }else{ console.log('删除文件成功:', filename) } }) } } // 获取明天凌晨时间 function getT(){ const temore = new Date().getTime() + 1000 * 60 * 60 * 24 const now = new Date(temore) let year = now.getFullYear(); //得到年份 let month = now.getMonth();//得到月份 let date = now.getDate();//得到日期 return new Date(year + "-" + month + "-" + date).getTime() } // 启动本地备份 startBackSQL() } server() back()