Authored by yyq

image upload

@@ -44,6 +44,7 @@ app.use(convert(body({ @@ -44,6 +44,7 @@ app.use(convert(body({
44 formLimit: '10mb', 44 formLimit: '10mb',
45 textLimit: '10mb', 45 textLimit: '10mb',
46 formidable: { 46 formidable: {
  47 + keepExtensions: true,
47 maxFieldsSize: 10 * 1024 * 1024 48 maxFieldsSize: 10 * 1024 * 1024
48 } 49 }
49 }))); 50 })));
  1 +
  2 +'use strict';
  3 +const _ = require('lodash');
  4 +const Router = require('koa-router');
  5 +const rp = require('request-promise');
  6 +const multiparty = require('koa2-multiparty');
  7 +const fs = require('fs');
  8 +
  9 +const r = new Router();
  10 +
  11 +const bucket = 'goodsimg';
  12 +
  13 +const _getUploadImgAbsoluteUrl = (url, bucket) => {
  14 + if (!url) {
  15 + return null;
  16 + }
  17 +
  18 + let urlArr = url.split('/'),
  19 + stag = urlArr[urlArr.length - 1].substr(0, 2),
  20 + domain = `static.yhbimg.com/${bucket}`;
  21 +
  22 + url = domain + url;
  23 + if (stag === '01') {
  24 + return `//img11.${url}`;
  25 + } else if (stag === '03') {
  26 + return `//flv01.${url}`;
  27 + } else {
  28 + return `//img12.${url}`;
  29 + }
  30 +};
  31 +
  32 +const upload = {
  33 + async image(ctx) {
  34 + let files = _.get(ctx, 'request.body._files.file');
  35 + let errTip;
  36 +
  37 + if (!_.isArray(files)) {
  38 + files = [files];
  39 + }
  40 +
  41 + const renderFiles = [];
  42 + files.forEach(file => {
  43 +
  44 + let types = file.type.split('/');
  45 +
  46 + if (!types || types[0] !== 'image') {
  47 + errTip = '上传文件格式不正确!';
  48 + }
  49 +
  50 + if (file.size > 10 * 1024 * 1024) {
  51 + errTip = '上传文件尺寸太大!';
  52 + }
  53 +
  54 + renderFiles.push(fs.createReadStream(file.path));
  55 + renderFiles.push(file.name);
  56 + });
  57 +
  58 + await rp({
  59 + method: 'post',
  60 + url: 'http://upload.static.yohobuy.com',
  61 + formData: {
  62 + fileData: renderFiles,
  63 + project: bucket
  64 + },
  65 + json: true
  66 + }).then(function(result) {
  67 +
  68 + if (result && result.code === 200) {
  69 + result.data = result.data || {};
  70 + result.data.images = _.map(_.get(result, 'data.imagesList'), (it) => {
  71 + return _getUploadImgAbsoluteUrl(it, bucket);
  72 + });
  73 + }
  74 +
  75 + ctx.response.body = result;
  76 + });
  77 + }
  78 +};
  79 +
  80 +r.post('/image', upload.image);
  81 +
  82 +module.exports = r;
@@ -31,6 +31,7 @@ const file = require('./actions/file'); @@ -31,6 +31,7 @@ const file = require('./actions/file');
31 const riskManagement = require('./actions/risk_management'); 31 const riskManagement = require('./actions/risk_management');
32 const logs = require('./actions/logs'); 32 const logs = require('./actions/logs');
33 const spa = require('./actions/spa'); 33 const spa = require('./actions/spa');
  34 +const upload = require('./actions/upload');
34 35
35 36
36 module.exports = function(app) { 37 module.exports = function(app) {
@@ -80,6 +81,7 @@ module.exports = function(app) { @@ -80,6 +81,7 @@ module.exports = function(app) {
80 // base.use('', index.routes(), index.allowedMethods()); 81 // base.use('', index.routes(), index.allowedMethods());
81 base.use('/risk_management', riskManagement.routes(), riskManagement.allowedMethods()); 82 base.use('/risk_management', riskManagement.routes(), riskManagement.allowedMethods());
82 base.use('/logs', logs.routes(), logs.allowedMethods()); 83 base.use('/logs', logs.routes(), logs.allowedMethods());
  84 + base.use('/upload', upload.routes(), upload.allowedMethods());
83 base.use('', spa.routes(), spa.allowedMethods()); 85 base.use('', spa.routes(), spa.allowedMethods());
84 86
85 app.use(base.routes(), base.allowedMethods()); 87 app.use(base.routes(), base.allowedMethods());
@@ -127,20 +127,34 @@ class OptionModal extends React.Component { @@ -127,20 +127,34 @@ class OptionModal extends React.Component {
127 this.renderData.misort = select[1]; 127 this.renderData.misort = select[1];
128 this.renderData.sort_id = select[2]; 128 this.renderData.sort_id = select[2];
129 } 129 }
130 - handleImageChange() {  
131 - // this.renderData.goods_img = select[2]; 130 + handleImageChange(info) {
  131 + const status = info.file.status;
  132 +
  133 + if (status === 'uploading') {
  134 + this.setState({ loading: true });
  135 + return;
  136 + } else if (status === 'done') {
  137 + const result = info.file.response;
  138 + let state = { loading: false };
  139 +
  140 + if (result.code === 200) {
  141 + this.renderData.goods_img = result.data.images[0];
  142 + }
  143 +
  144 + this.setState(state);
  145 + }
132 } 146 }
133 beforeUpload(file) { 147 beforeUpload(file) {
134 - const isJPG = file.type === 'image/jpeg'; 148 + const isImage = file.type.indexOf('image') > -1;
135 const isLt2M = file.size / 1024 / 1024 < 2; 149 const isLt2M = file.size / 1024 / 1024 < 2;
136 150
137 - if (!isJPG) {  
138 - message.error('You can only upload JPG file!'); 151 + if (!isImage) {
  152 + message.error('请上传图片!');
139 } else if (!isLt2M) { 153 } else if (!isLt2M) {
140 - message.error('Image must smaller than 2MB!'); 154 + message.error('图片大小需小于 2MB!');
141 } 155 }
142 156
143 - return isJPG && isLt2M; 157 + return isImage && isLt2M;
144 } 158 }
145 loadSortData(selectedOptions) { 159 loadSortData(selectedOptions) {
146 const targetOption = selectedOptions[selectedOptions.length - 1]; 160 const targetOption = selectedOptions[selectedOptions.length - 1];
@@ -218,11 +232,11 @@ class OptionModal extends React.Component { @@ -218,11 +232,11 @@ class OptionModal extends React.Component {
218 listType="picture-card" 232 listType="picture-card"
219 className="avatar-uploader" 233 className="avatar-uploader"
220 showUploadList={false} 234 showUploadList={false}
221 - action="//jsonplaceholder.typicode.com/posts/" 235 + action="/upload/image"
  236 + name="file"
222 beforeUpload={this.beforeUpload} 237 beforeUpload={this.beforeUpload}
223 - onChange={this.handleImageChange}  
224 - style={{ width: 600 }}>  
225 - {imageUrl ? <img src={imageUrl} alt="" /> : this.uploadButton(this.state.loading)} 238 + onChange={this.handleImageChange}>
  239 + {record.goods_img ? <img src={record.goods_img} style={{maxWidth: 200}} /> : this.uploadButton(this.state.loading)}
226 </Upload> 240 </Upload>
227 </div> 241 </div>
228 <div style={{ paddingBottom: 10 }}> 242 <div style={{ paddingBottom: 10 }}>
@@ -345,7 +359,7 @@ class HotKeywords extends React.Component { @@ -345,7 +359,7 @@ class HotKeywords extends React.Component {
345 const rowKey = record => { 359 const rowKey = record => {
346 record.callbackFn = this.showOptionModal.bind(this); 360 record.callbackFn = this.showOptionModal.bind(this);
347 361
348 - return record.id 362 + return record.id;
349 } 363 }
350 364
351 return ( 365 return (
@@ -11,7 +11,6 @@ export default class extends Service { @@ -11,7 +11,6 @@ export default class extends Service {
11 return this.post('/keywords/expand/del', {ids}); 11 return this.post('/keywords/expand/del', {ids});
12 } 12 }
13 saveHotKeywords(info) { 13 saveHotKeywords(info) {
14 - console.log(info);  
15 let params = { 14 let params = {
16 keywords: info.keyword, 15 keywords: info.keyword,
17 msort: info.msort, 16 msort: info.msort,