Showing
5 changed files
with
111 additions
and
13 deletions
@@ -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 | }))); |
apps/web/actions/upload.js
0 → 100644
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, |
-
Please register or login to post a comment