文章目录
- 1、前端代码
- 2、后端代码
本文Node搭建的服务器是基于egg框架搭建,如果使用其他服务器端框架,可参考部分代码,不保证所有框架都能实现
实现效果:
1、前端代码
前端部分vue利用的element-ui文件上传组件,相关属性api请参考element-ui官方文档
index.vue
<template>
<div class="body-class">
<el-form v-show="!isEdit && !isEditAccount" ref="userInfo" label-width="120px" :model="user" label-position="left"
class="ruleForm">
<el-form-item label="简历">
<el-upload class="upload-demo" ref="upload" :action="fileUrl" :on-preview="handlePreview"
:on-remove="handleRemove" :file-list="fileList" :auto-upload="false" :before-upload="beforeUpload" :limit="1"
:on-exceed="handleExceed" :on-success="handleResumeSuccess" >
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
<el-button style="margin-left: 10px;" size="small" type="warning" @click="submitUpload">上传</el-button>
<el-button style="margin-left: 10px;" size="small" v-if="file.resumead" type="primary" @click="downloadResume">
下载简历
</el-button>
<div slot="tip" class="el-upload__tip">只能上传doc/pdf文件,且不超过2MB</div>
</el-upload>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { del } from '@/request/http';
import axios from 'axios';
import { updateStudent, updateAccount, getInfoByToken, deleteResume, getResumeByStudentId, saveOrUpdateResume } from '@/request/api';
export default {
name: "StudentInfo",
data () {
return {
fileList: [],//保存上传的文件
basePath: "http://127.0.0.1:7003/",
fileUrl: "http://127.0.0.1:7003/resume/fileUpload",//上传文件路径
bool:true,//保存是否允许上传的文件类型
file: {
resumead: ""
},
},
methods: {
handlePreview (file) {
console.log(file, 3);
},
// 删除文件
async handleRemove (file, fileList) {
// console.log(file, fileList);
//获取文件名
if (file.response || file.url) {
let f;
if (file.response) {
let arr = file.response.data.split("\\");
f = arr[arr.length - 1];
} else {
let arr = file.url.split("/");
let arr2 = arr[arr.length - 1].split("\\");
f = arr2[arr2.length - 1];
}
this.fileList.pop();
try {
let res = await del(`/resume/deleteFile/${f}`);
if (res) {
const x = await deleteResume({ id: this.file.id })
// conole.log(x)
if (x) {
this.file = {};
this.$message.success("删除成功")
}
}
} catch (error) {
console.log(error)
}
}
},
//文件上传前的操作
beforeUpload (file) {
console.log(file,1)
//判断文件类型
const isWORD = file.type === 'application/msword' || file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
const isPDF = file.type === 'application/pdf';
const isLt2M = file.size / 1024 / 1024 < 2;
console.log(isWORD, isPDF)
let bool=isWORD||isPDF
if (!bool) {
this.$message.error('上传文件只能是doc或pdf格式!');
}
if (!isLt2M) {
this.$message.error('上传文件大小不能超过 2MB!');
}
this.bool = (isWORD || isPDF) && isLt2M;
return (isWORD || isPDF) && isLt2M;
},
handleExceed (files, fileList) {
this.$message.warning(`当前限制上传 1 个文件`);
},
//文件上传成功后
async handleResumeSuccess (res, file) {
console.log(file)
//获取文件名
this.file.resumead = this.basePath + file.response.data.replace(/\\\\/g, "/");
if (this.bool) {
try {
let res = await saveOrUpdateResume({ resumead: this.file.resumead, student_id: this.user.id, filename: file.name, is_effect: 1 })
if (res) {
this.$message.success("上传成功");
this.getFile();
}
} catch (error) {
console.log(error)
}
}
},
//执行上传操作
submitUpload () {
this.$refs.upload.submit();
},
//下载文件
async downloadResume () {
const loding = this.$message({
message: '文件下载中,请稍后...',
duration: 0,
iconClass: 'el-icon-loading'
})
try {
let res = await axios.get(this.file.resumead, {
timeout: 10000,
headers: {
responseType: 'arraybuffer'
}
});
console.log(res)
if (res) {
const a = document.createElement('a')
a.href = window.URL.createObjectURL(new Blob([res.data]))
a.download = "我的简历.pdf"
a.click();
loding.close()
this.$message.success('文件下载完成!')
}
} catch (error) {
console.log(error)
}
},
//获取文件
async getFile () {
try {
//调用获取文件的接口
let res = await getResumeByStudentId({ student_id: this.user.id });
// console.log(res);
if (res.data.length>0) {
this.fileList = [{ name: res.data[0].filename, url: res.data[0].resumead }];
this.file = res.data[0];
}
} catch (error) {
console.log(error)
}
},
},
}
</script>
调用文件上传接口
调用存储简历的接口,将返回的文件路径和文件名保存到表中
读取简历信息,显示到页面中
2、后端代码
router.js
后端路由配置
module.exports = (app) => {
const { router, controller, jwt } = app;
router.post('/resume/fileUpload', controller.resume.fileUpload);//上传文件
router.get('/app/resume/:file', controller.resume.getFile);//获取文件
router.delete('/resume/deleteFile/:file', controller.resume.deleteFile);//删除文件
};
app/controller/resume.js
下图为上传文件保存的路径
const Controller = require('egg').Controller;
const Response = require('../utils/Response');
const fs = require('fs');
const path = require('path');
/**
* @Controller ResumeController:公司模块
*/
class ResumeController extends Controller {
//上传文件***
async fileUpload() {
const { ctx, config } = this;
try {
// 获取文件
const file = ctx.request.files[0];
console.log('获取文件', file);
// ctx.request.files[0] 表示获取第一个文件,若前端上传多个文件则可以遍历这个数组对象
//读取文件
const fileData = fs.readFileSync(file.filepath);
// console.log('fileData', fileData);
const date = Date.now(); // 毫秒数
//设置文件保存路径
const tempDir = path.join(
'app/resume',
date + path.extname(file.filename)
); // 返回文件保存的路径
// console.log('毫秒数 extname', date, path.extname(file.filename));
console.log('返回文件保存的路径', tempDir);
// 写入文件夹
fs.writeFileSync(tempDir, fileData);
ctx.body = {
status: 200,
desc: '上传成功',
data: tempDir,
};
} catch (error) {
console.log('error', error); // 错误处理程序或处理器,比如打开文件错误,文件名
ctx.body = {
status: 500,
desc: '上传失败',
data: null,
};
}
}
//删除文件
async deleteFile() {
// 删除图片文件夹中的所有文件和图片 /delete/img/filename.png 或 delete/img/filename.png
const { ctx } = this;
console.log(ctx.params.file); // 获取删除文件的条目的唯一标志
const fileDelete = `app/resume/${ctx.params.file}`; // 这里写一个例子 app/resume/filename.png
const fileDeleteExists = fs.existsSync(fileDelete); // 检查文件是否存在
console.log(fileDeleteExists); // 获取删除文件条目的唯一标志
if (fileDeleteExists) {
// 如果文件存在 执行删除操作 delete/img/filename.png
fs.unlinkSync(fileDelete);
ctx.body = { status: 200, desc: '文件删除成功', data: null };
}
}
//获取文件
async getFile() {
const { ctx } = this;
ctx.body = fs.readFileSync(`app/resume/${ctx.params.file}`);
}
}
module.exports = ResumeController; // 自动挂载类 到 基类
上传文件后接口输出
保存简历路径到表中接口返回数据
config.default.js
egg配置文件,必须要配,之前没配一直上传不了。。。
config.multipart = {
// mode: "file",
// fileSize: '100mb',
mode: 'file',
cleanSchedule: {
cron: '0 0 4 * * *',
},
whitelist() {
return true;
}
};