1. 定义模板文件
代码语言:javascript复制<form action="/admin/focus/doAdd?_csrf=<%=csrf%>" method="post" enctype="multipart/form-data">
<ul>
<li> 分类:<select name="type" id="type" style="width:300px;height:26px">
<option value="1">网站</option>
<option value="2">APP</option>
<option value="3">小程序</option>
</select>
</li>
<li>名称:<input type="text" name="title" style="width:300px;height:26px" /></li>
<li>链接:<input type="text" name="link" style="width:300px;height:26px" /></li>
<li>上传:<input type="file" name="focus_img" style="width:300px;height:26px;" /></li>
<li>排序:<input type="text" name="sort" value="1000" style="width:300px;height:26px" /></li>
<li style="display:flex;flex-direction:row;">
状态:
<input type="radio" name="status" checked value="1" id="a" style="margin-right:10px" ; />
<label for="a" style="margin-right:10px">显示</label>
<input type="radio" name="status" value="0" id="b" style="margin-right:10px" />
<label for="b" style="margin-right:10px">隐藏</label>
</li>
<li>
<button type="submit" class="btn btn-primary">提交</button>
</li>
</ul>
</form>
2. 定义上传图片数据库的model
代码语言:javascript复制// app/model/focus.js
module.exports = app => {
const mongoose = app.mongoose;
const Schema = mongoose.Schema;
// 配置轮播图和Schema
const now = (new Date()).getTime();
const FocusSchema = new Schema({
title: { type: String },
type: { type: Number },
focus_img: { type: String },
link: { type: String },
sort: { type: Number },
status: { type: Number, default: 1 },
add_time: {
type: Number,
default: now
}
});
return mongoose.model('Focus', FocusSchema, 'focus');
}
3. 配置上传路由
代码语言:javascript复制// router.js
'use strict';
module.exports = app => {
const { router, controller } = app;
router.post('/admin/focus/doAdd',controller.admin.focus.doAdd);
};
4. 配置上传地址、格式及大小设置
代码语言:javascript复制// config/config.default.js
'use strict';
module.exports = appInfo => {
const config = exports = {};
// use for cookie sign key, should change to your own and keep security
config.keys = appInfo.name '_1585450669767_9677';
// 上传文件存放的全局地址
config.uploadDir = 'app/public/admin/upload';
// 上传文件的配置
// https://github.com/eggjs/egg-multipart
config.multipart = {
// 允许上传的图片格式
whitelist:['.png','.jpg','.jpeg'],
// 文件允许大小
fileSize:'50mb'
}
// 配置两种模板引擎(参考官方文档)
config.view = {
mapping: {
'.html': 'ejs',
'.nj': 'nunjucks'
}
}
return config
};
5. 定义控制器
代码语言:javascript复制// app/controller/admin/focus.js
'use strict';
const Fs = require('fs');
// cnpm i mz-modules --save
// 此模块解决上传卡死
const Pump = require('mz-modules/pump');
const Controller = require('egg').Controller;
class FocusController extends Controller {
// 添加轮播图提交
async doAdd() {
// autoFields: true 表示除了文件的其它字段
let parts = this.ctx.multipart({ autoFields: true });
let files = {}, stream;
// 循环获取数据流
while ((stream = await parts()) != null) {
if (!stream.filename) {
// 多文件上传时,只能break,不能return
break;
}
// 文件表单的name
let fieldname = stream.fieldname;
// 获取上传文件路径与入库保存路径
let dir = await this.service.tools.getUploadFile(stream.filename);
// 上传路径
let target = dir.uploadDir;
// 写入上传文件
let writeStream = Fs.createWriteStream(target);
await Pump(stream, writeStream);
// 将多个上传图片统一拼接为一个对象,便于访问
files = Object.assign(files, {
[fieldname]: dir.saveDir
})
// 生成缩略图 target为图片地址
this.service.tools.jimpImg(target);
}
// 将上传的图片与提交的其它字段合并
let focus = new this.ctx.model.Focus(Object.assign(files, parts.field));
let result = await focus.save();
// 对result做出结果判断(略)
this.ctx.body={
"message":"上传图片成功",
"success":true
}
}
}
module.exports = FocusController;
6. 在控制器中需要调用的服务中的方法
代码语言:javascript复制// app/service/tools.js
'use strict';
const Path = require('path');
const Service = require('egg').Service;
// 引入格式化时间模块
// cnpm i silly-datetime --save
const Sd = require('silly-datetime');
// 引入模块智能生成上传文件夹
// cnpm i mz-modules --save
const Mkdirp = require('mz-modules/mkdirp');
// 引入生成缩略图的模块
// cnpm install jimp --save
// https://github.com/oliver-moran/jimp/tree/master/packages/jimp
const Jimp = require('jimp');
class ToolService extends Service {
// 获取当前时间戳
async getTime(){
let now = new Date();
return now.getTime();
}
// 处理要上传的文件名
async getUploadFile(filename){
// 获取当前日期
let now = Sd.format(new Date(),'YYYYMMDD');
// 创建文件目录(将存放地址与日期进行拼接);
let dir = Path.join(this.config.uploadDir,now);
// 按dir去创建文件夹,如果没有则生成,如果有则忽略
await Mkdirp(dir);
// 以时间戳命名文件
let timestamp = await this.getTime();
// 图片的保存路径(文件夹 时间戳 后辍名)
let uploadDir = Path.join(dir,timestamp Path.extname(filename));
return{
// 上传的地址
uploadDir:uploadDir,
// 保存在数据库的地址
saveDir:uploadDir.slice(3).replace(/\/g,'/')
}
}
// 生成缩略图方法
async jimpImg(target){
Jimp.read(target, (err, lenna) => {
if (err) throw err;
// 生成200乘以200大小,品质为90,并重命名文件
lenna.resize(200,200).quality(90).write(target '_200x200' Path.extname(target));
})
}
}
module.exports = ToolService;