1.前言
项目需求:前端上传一个算法文件,此算法文件是个tgz压缩包,首先这个tgz文件要上转到ftp服务器,然后需要解压tgz文件,找到里面的desc格式的文件并打开获取里面的算法描述信息,最后把这个算法信息添加数据库里面。看视乎非常简单的需求,如果是zip文件还可以用jszip插件(但是它也读取不了desc格式的文件),想了许久,后面还是node搞。
2. 思路
利用express搭建环境,前端上传压缩文件,后端路由监听完成解压并且重命名desc格式文件为text格式,读取并返回给前端,前端再添加这个算法信息到数据库
前端代码:
<el-upload
class="upload-demo"
ref="uploadDemo"
drag
style="text-align: center"
:limit="1"
:show-file-list="false"
:on-error="uploadError"
:on-success="uploadSuccess"
:before-upload="beforeUpload"
:http-request="submitUpload"
>
//文件上传成功的操作
uploadSuccess(file) {
//获取压缩文件的描述信息
let formData = new FormData();
formData.append("file", file);
this.axios
.post(
//接口
`/test`,
formData,
{
headers: {
"Content-Type": "multipart/form-data"
}
}
)
.then(data => {
if (data.status == 200) {
//上传完成后,获取到算法的描述信息
//模型保存到数据库
//装载post传值
let params = new URLSearchParams();
params.append(
"algorithmName",
file.name.substring(0, file.name.indexOf("."))
);
params.append("algorithmLog", data.data.des);
params.append("algorithmVersion", "0.1");
params.append("algorithmEquipmentType", "camera");
params.append("algorithmLabel", "1");
params.append("modelAndLabelUrl", `${modelFtpUrl}${file.name}`);
this.axios
.post(
//接口
`/algorithm/algorithmAdd`,
params
)
.then(data => {
if (data.data.code == 200) {
//重新获取模型列表
this.getModelList();
this.$message.success("模型添加成功");
//清除已经上传的文件
this.$refs.uploadDemo.clearFiles();
} else {
this.$message.error(data.data.message);
}
})
.catch(error => {
this.uploadError(error);
});
}
})
.catch(error => {
this.$message.error("获取算法描述文件失败");
});
}
后端代码:
package.json
{
"name": "app",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"cookie-parser": "~1.4.4",
"debug": "~2.6.9",
"ejs": "~2.6.1",
"express": "~4.16.1",
"http-errors": "~1.6.3",
"morgan": "~1.9.1",
"compressing": "^1.6.2",
"multer": "^1.4.5-lts.1"
}
}
app.js
let upload = require('./routes/upload'),
express = require('express'),
app = express();
//注册路由
app.use('/test', upload);
module.exports = app;
upload.js
let express = require('express');
router = express.Router(),
compressing = require('compressing'),
fs = require('fs'),
multer = require('multer'),
uploadFolder = './public/upload',
// 使用硬盘存储模式设置存放接收到的文件的路径以及文件名
storage = multer.diskStorage({
destination: function (req, file, cb) {
// 接收到文件后输出的保存路径(若不存在则需要创建)
cb(null, uploadFolder);
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}
}),
// 创建文件夹
createFolder = function (folder) {
try {
// 测试 path 指定的文件或目录的用户权限,我们用来检测文件是否存在
// 如果文件路径不存在将会抛出错误"no such file or directory"
fs.accessSync(folder);
} catch (e) {
// 文件夹不存在,以同步的方式创建文件目录。
fs.mkdirSync(folder);
}
};
//删除文件夹下面所有的文件(包括文件夹)
deleteall = function (path) {
let files = [];
//检测目录是否存在
if (fs.existsSync(path)) {
//读取该目录的所有的文件
files = fs.readdirSync(path);
files.forEach(function (file, index) {
let curPath = path + "/" + file;
//判断是否是文件目录,递归调用
if (fs.statSync(curPath).isDirectory()) { // recurse
deleteall(curPath);
} else { // delete file
//删除文件操作
fs.unlinkSync(curPath);
}
});
}
};
createFolder(uploadFolder);
// 创建 multer 对象
let upload = multer({
storage: storage
})
router.post('/', upload.single('file'), function (req, res, next) {
compressing.tgz.uncompress(`./${req.file.path}`, uploadFolder)
.then(() => {
fs.rename(`${uploadFolder}/algorithm.desc`, `${uploadFolder}/algorithm.text`, () => {
console.log("改名成功")
fs.readFile(`${uploadFolder}/algorithm.text`, 'utf-8', function (err, data) {
if (err) {
console.log(err);
} else {
// 接收文件成功后返回数据给前端
res.send({
des: data
});
deleteall(`${uploadFolder}`);
}
});
});
})
.catch((error) => {
console.log(error);
});
});
module.exports = router;
最后配置一个服务自启动脚本
最终返回的结果如下:
以上部分是代码的核心部分,仅供参考!若有更好的方法可以下面留言,谢谢!