Authored by 陈峰

上传文件

// 懒加载vue-quill-editor
// 懒加载VueHtml5Editor
import _ from 'lodash';
const component = function editor(resolve) {
require.ensure([], () => {
const VueHtml5Editor = require('vue-html5-editor');
const editorInstance = new VueHtml5Editor({
hiddenModules: ['info'],
// 配置图片模块
// config image module
image: {
// 文件最大体积,单位字节 max file size
sizeLimit: 512 * 1024,
// 上传参数,默认把图片转为base64而不上传
// upload config,default null and convert image to base64
upload: {
url: null,
url: '/upload/image',
headers: {},
params: {},
fieldName: {}
},
// 压缩参数,默认使用localResizeIMG进行压缩,设置为null禁止压缩
// compression config,default resize image by localResizeIMG (https://github.com/think2011/localResizeIMG)
// set null to disable compression
compress: {
width: 1600,
height: 1600,
quality: 80
params: {
bucket: 'goodsimg'
},
fieldName: 'file'
},
// 响应数据处理,最终返回图片链接
// handle response data,return image url
uploadHandler(responseText){
//default accept json data like {ok:false,msg:'unexpected'} or {ok:true,data:'image url'}
var json = JSON.parse(responseText)
if (!json.ok) {
alert(json.msg)
} else {
return json.data
compress: null,
uploadHandler(responseText) {
let json = JSON.parse(responseText);
if (json.code === 200) {
return _.get(json, 'data.imagesList[0]', '');
}
return json.data;
}
},
language: 'zh-cn',
modules: {
}
modules: {}
});
resolve(editorInstance);
... ...
... ... @@ -2,5 +2,6 @@ import menus from './menus';
import breadcrumb from './breadcrumb';
import userInfo from './user-info';
import editor from './editor';
import yohoUpload from './yoho-upload';
export default [menus, breadcrumb, userInfo, editor];
export default [menus, breadcrumb, userInfo, editor, yohoUpload];
... ...
<template>
<Upload ref="upload"
:action="action"
:data="data"
:accept="accept"
:maxSize="maxSize"
:on-success="success"
:on-error="error"
:before-upload="beforeUpload">
<Button type="ghost" icon="ios-cloud-upload-outline">上传文件</Button>
</Upload>
</template>
<script>
import _ from 'lodash';
export default {
name: 'yoho-upload',
props: {
action: {
type: String,
default: '/upload/image'
},
data: {
type: Object,
default: () => {
return {
bucket: 'goodsimg'
};
}
},
accept: {
type: String,
default: 'image/png,image/jpeg,image/gif,image/jpg'
},
maxSize: {
type: Number,
default: 512 * 1024
}
},
data() {
return {};
},
methods: {
success(response) {
let files = [];
if (_.get(response, 'data.imagesList.length', 0)) {
files = response.data.imagesList;
}
this.$emit('on-success', files);
},
error(error) {
this.$Message.error('上传失败');
this.$emit('on-error', error);
},
beforeUpload() {
this.$refs.upload.clearFiles();
return true;
}
}
};
</script>
... ...
... ... @@ -3,6 +3,7 @@
overview
<editor :content="content" @change="updateData"></editor>
{{content}}
<yoho-upload @on-success="uploadSuccess" @on-error="uploadError"></yoho-upload>
</div>
</template>
... ... @@ -18,6 +19,12 @@ export default {
methods: {
updateData(c) {
this.content = c;
},
uploadSuccess(files) {
console.log(files)
},
uploadError(error) {
console.error(error)
}
}
};
... ...
... ... @@ -18,6 +18,7 @@
"bluebird": "^3.5.0",
"body-parser": "^1.17.1",
"compression": "^1.6.2",
"connect-multiparty": "^2.0.0",
"cookie-parser": "^1.4.3",
"cookie-session": "^2.0.0-beta.1",
"express": "^4.15.2",
... ...
... ... @@ -35,7 +35,19 @@ class Api extends Context {
});
});
}
upload() {
upload(url, formData, headers) {
let defaultHeader = {
'Content-Type': 'application/json'
};
return this.parse(() => {
return request.post({
method: 'post',
url,
formData,
headers: Object.assign(defaultHeader, headers)
});
});
}
download() {
}
... ...
/**
* 文件相关controller
* @author: feng.chen<feng.chen@yoho.cn>
* @date: 2017/04/13
*/
'use strict';
const Context = require('../common/context');
const FileService = require('../service/file-service');
const Api = require('../common/api');
const fs = require('fs');
const _ = require('lodash');
class FileController extends Context {
constructor() {
super();
this.api = this.instance(Api);
this.fileService = this.instance(FileService);
}
uploadImage(req, res, next) {
let files = req.files && req.files.file || [];
let errTip = null;
if (!_.isArray(files)) {
files = [files];
}
req.body.files = [];
_.each(files, file => {
let types = file.type.split('/');
if (!types || types[0] !== 'image') {
errTip = '上传文件格式不正确!';
}
if (file.size > 10 * 1024 * 1024) {
errTip = '上传文件尺寸太大!';
}
req.body.files.push(fs.createReadStream(file.path));
req.body.files.push(file.name);
});
if (errTip) {
return res.status(403).send({
message: errTip
});
}
this.api.upload('http://upload.static.yohobuy.com', {
fileData: req.body.files,
project: req.body.bucket
}).then(result => {
if (result.code === 200 && _.get(result, 'data.imagesList.length', 0)) {
result.data.imagesList = _.map(result.data.imagesList, imgUrl => {
return this.fileService.getAbsoluteUrl(imgUrl, req.body.bucket);
});
}
res.json(result);
}).catch(next);
}
}
module.exports = FileController;
... ...
... ... @@ -8,12 +8,16 @@
const Express = require('express');
const UserController = require('./user');
const FileController = require('./file');
const middleware = require('../common/middleware');
const multipart = require('connect-multiparty');
const multipartMiddleware = multipart();
let router = Express.Router(); // eslint-disable-line
router.post('/login', middleware(UserController, 'login'));
router.post('/logout', middleware(UserController, 'logout'));
router.post('/upload/image', multipartMiddleware, middleware(FileController, 'uploadImage'));
module.exports = router;
... ...
... ... @@ -3,7 +3,10 @@
* @author: feng.chen<feng.chen@yoho.cn>
* @date: 2017/04/13
*/
const logger = global.yoho.logger;
module.exports = (err, req, res, next) => { // eslint-disable-line
logger.error(err);
if (err.code === 401) {
return res.status(401).json({
code: 401,
... ...
const Context = require('../common/context');
class FileService extends Context {
constructor() {
super();
}
getAbsoluteUrl(url, bucket) {
if (!url) {
return null;
}
let urlArr = url.split('/'),
stag = urlArr[urlArr.length - 1].substr(0, 2),
domain = `static.yhbimg.com/${bucket}`;
url = domain + url;
if (stag === '01') {
return `//img11.${url}`;
} else if (stag === '03') {
return `//flv01.${url}`;
} else {
return `//img12.${url}`;
}
}
}
module.exports = FileService;
... ...