Merge branch 'feature/upsinglefile' into 'master'
Feature/upsinglefile See merge request !17
Showing
7 changed files
with
161 additions
and
23 deletions
1 | 'use strict'; | 1 | 'use strict'; |
2 | 2 | ||
3 | +const CDNCONFIG = require('../../../config/cdn_config'); | ||
3 | const _ = require('lodash'); | 4 | const _ = require('lodash'); |
4 | const moment = require('moment'); | 5 | const moment = require('moment'); |
5 | const Router = require('koa-router'); | 6 | const Router = require('koa-router'); |
7 | +const fs = require('fs'); | ||
8 | +const path = require('path'); | ||
6 | const router = new Router(); | 9 | const router = new Router(); |
7 | const FileApi = require('../../ci/file'); | 10 | const FileApi = require('../../ci/file'); |
8 | -const CDNCONFIG = require('../../../config/cdn_config'); | ||
9 | -const qn = require('../../../lib/qiniu')(CDNCONFIG.feature); | 11 | +const qnFeature = require('../../../lib/qiniu')(CDNCONFIG.feature); |
10 | 12 | ||
11 | /** | 13 | /** |
12 | * 处理列表数据 | 14 | * 处理列表数据 |
@@ -18,25 +20,18 @@ const _handleListItems = items => { | @@ -18,25 +20,18 @@ const _handleListItems = items => { | ||
18 | let dateTime = _.parseInt(perFile.putTime.toString().substring(0, 13)); | 20 | let dateTime = _.parseInt(perFile.putTime.toString().substring(0, 13)); |
19 | 21 | ||
20 | perFile.putTimeFormat = moment(dateTime).format('YYYY-MM-DD HH:mm'); | 22 | perFile.putTimeFormat = moment(dateTime).format('YYYY-MM-DD HH:mm'); |
21 | - perFile.link = _.get(CDNCONFIG, 'feature.origin') + '/' + perFile.key; | 23 | + perFile.link = _.get(CDNCONFIG.feature, 'origin') + '/' + perFile.key; |
22 | }); | 24 | }); |
23 | 25 | ||
24 | return items; | 26 | return items; |
25 | }; | 27 | }; |
26 | 28 | ||
27 | -/** | ||
28 | - * 校验是否是允许上传的文件包 | ||
29 | - */ | ||
30 | -const _verifyFiles = filesList => { | ||
31 | - return true; | ||
32 | -}; | ||
33 | - | ||
34 | const file = { | 29 | const file = { |
35 | /** | 30 | /** |
36 | * 文件管理页面 | 31 | * 文件管理页面 |
37 | */ | 32 | */ |
38 | page: async(ctx) => { | 33 | page: async(ctx) => { |
39 | - await ctx.render('/action/file_page', {domain: _.get(CDNCONFIG, 'feature.origin')}); | 34 | + await ctx.render('/action/file_page', {domain: _.get(CDNCONFIG.feature, 'origin')}); |
40 | }, | 35 | }, |
41 | 36 | ||
42 | /** | 37 | /** |
@@ -68,7 +63,7 @@ const file = { | @@ -68,7 +63,7 @@ const file = { | ||
68 | params.marker = ctx.query.marker; | 63 | params.marker = ctx.query.marker; |
69 | } | 64 | } |
70 | 65 | ||
71 | - let result = await qn.listAsync(params); | 66 | + let result = await qnFeature.listAsync(params); |
72 | let finalResult = { | 67 | let finalResult = { |
73 | items: _handleListItems(result.items) | 68 | items: _handleListItems(result.items) |
74 | }; | 69 | }; |
@@ -116,6 +111,59 @@ const file = { | @@ -116,6 +111,59 @@ const file = { | ||
116 | message: '处理完毕', | 111 | message: '处理完毕', |
117 | data: {} | 112 | data: {} |
118 | }; | 113 | }; |
114 | + }, | ||
115 | + | ||
116 | + /** | ||
117 | + * 单文件上传页面 | ||
118 | + */ | ||
119 | + singleFile: async(ctx) => { | ||
120 | + await ctx.render('/action/single_file_page', {domain: _.get(CDNCONFIG.main, 'origin')}); | ||
121 | + }, | ||
122 | + | ||
123 | + /** | ||
124 | + * 单文件上传处理 | ||
125 | + */ | ||
126 | + singleFileUpload: async(ctx, next) => { | ||
127 | + if ('POST' !== ctx.method) return await next(); | ||
128 | + | ||
129 | + let file = _.get(ctx, 'request.body._files.file'); | ||
130 | + let actPath = _.get(ctx, 'request.body.actPath') || 'uploads/' + moment(); | ||
131 | + let cover = _.get(ctx, 'request.body.cover') === 'yes'; // 是否覆盖 | ||
132 | + let filePath = path.join(actPath, _.get(file, 'name')); | ||
133 | + | ||
134 | + if (!file) { | ||
135 | + return ctx.body = { | ||
136 | + code: 400, | ||
137 | + message: '没有接收到上传的文件' | ||
138 | + }; | ||
139 | + } | ||
140 | + | ||
141 | + let readable = fs.createReadStream(file.path); | ||
142 | + let config = CDNCONFIG.main; | ||
143 | + | ||
144 | + if (cover) { | ||
145 | + _.assign(CDNCONFIG.main, { | ||
146 | + key: filePath | ||
147 | + }); | ||
148 | + } | ||
149 | + | ||
150 | + let qnMain = require('../../../lib/qiniu')(config); | ||
151 | + let upResult = await qnMain.uploadAsync(readable, {key: filePath}); | ||
152 | + | ||
153 | + if (upResult && upResult.url) { | ||
154 | + return ctx.body = { | ||
155 | + code: 200, | ||
156 | + message: '上传完毕', | ||
157 | + data: { | ||
158 | + url: upResult.url | ||
159 | + } | ||
160 | + }; | ||
161 | + } else { | ||
162 | + return ctx.body = { | ||
163 | + code: 400, | ||
164 | + message: '上传失败,请重试' | ||
165 | + }; | ||
166 | + } | ||
119 | } | 167 | } |
120 | } | 168 | } |
121 | 169 | ||
@@ -123,5 +171,7 @@ router.get('/page', file.page); | @@ -123,5 +171,7 @@ router.get('/page', file.page); | ||
123 | router.get('/listlogs', file.listLogs); | 171 | router.get('/listlogs', file.listLogs); |
124 | router.get('/listfiles', file.listFiles); | 172 | router.get('/listfiles', file.listFiles); |
125 | router.post('/upload', file.upload); | 173 | router.post('/upload', file.upload); |
174 | +router.get('/single-file', file.singleFile); | ||
175 | +router.post('/single-file-upload', file.singleFileUpload); | ||
126 | 176 | ||
127 | module.exports = router; | 177 | module.exports = router; |
@@ -79,6 +79,9 @@ | @@ -79,6 +79,9 @@ | ||
79 | if (!$('#actPath').val()) { | 79 | if (!$('#actPath').val()) { |
80 | $('.logs').prepend('<p>state: 请输入上传地址!</p>'); | 80 | $('.logs').prepend('<p>state: 请输入上传地址!</p>'); |
81 | return false; | 81 | return false; |
82 | + } else { | ||
83 | + $(this).attr('disabled', 'disabled'); | ||
84 | + $(this).text('上传中...'); | ||
82 | } | 85 | } |
83 | actPath = `/${actPath}`; | 86 | actPath = `/${actPath}`; |
84 | formData.append('file', file); | 87 | formData.append('file', file); |
@@ -98,8 +101,12 @@ | @@ -98,8 +101,12 @@ | ||
98 | $('#upload-list tr[class!=title]').remove(); | 101 | $('#upload-list tr[class!=title]').remove(); |
99 | page = 1; | 102 | page = 1; |
100 | getList(); | 103 | getList(); |
104 | + $('#upload').removeAttr('disabled'); | ||
105 | + $('#upload').text('上传'); | ||
101 | } else if (result.code === 400) { | 106 | } else if (result.code === 400) { |
102 | $('.logs').prepend('<p>state: 请选择上传文件!</p>'); | 107 | $('.logs').prepend('<p>state: 请选择上传文件!</p>'); |
108 | + $('#upload').removeAttr('disabled'); | ||
109 | + $('#upload').text('上传'); | ||
103 | } | 110 | } |
104 | } else { | 111 | } else { |
105 | $('.logs').prepend('<p>state: 请稍后再试!</p>'); | 112 | $('.logs').prepend('<p>state: 请稍后再试!</p>'); |
@@ -125,7 +132,7 @@ | @@ -125,7 +132,7 @@ | ||
125 | result.data.forEach(function(item){ | 132 | result.data.forEach(function(item){ |
126 | $uploadList.append(` | 133 | $uploadList.append(` |
127 | <tr> | 134 | <tr> |
128 | - <td><a href="${item.link}">${item.actPath}</a></td> | 135 | + <td><a target="_blank" href="${item.link}">${item.actPath}</a></td> |
129 | <td style="text-align:center;">${item.fileName}</td> | 136 | <td style="text-align:center;">${item.fileName}</td> |
130 | <td style="text-align:center;">${item.date}</td> | 137 | <td style="text-align:center;">${item.date}</td> |
131 | <td style="text-align:center;">${item.username}</td> | 138 | <td style="text-align:center;">${item.username}</td> |
@@ -180,7 +187,7 @@ | @@ -180,7 +187,7 @@ | ||
180 | $this.parents('td').find('.get-more').attr('data-marker', result.data.marker); | 187 | $this.parents('td').find('.get-more').attr('data-marker', result.data.marker); |
181 | result.data.items.forEach(function(item){ | 188 | result.data.items.forEach(function(item){ |
182 | detail += `<tr class="detail-list"> | 189 | detail += `<tr class="detail-list"> |
183 | - <td><a href="${item.link}">${item.key}</a></td> | 190 | + <td><a target="_blank" href="${item.link}">${item.key}</a></td> |
184 | <td style="text-align:center;">${item.fsizekb}</td> | 191 | <td style="text-align:center;">${item.fsizekb}</td> |
185 | <td style="text-align:center;">${item.mimeType}</td> | 192 | <td style="text-align:center;">${item.mimeType}</td> |
186 | <td style="text-align:center;">${item.putTimeFormat}</td> | 193 | <td style="text-align:center;">${item.putTimeFormat}</td> |
apps/web/views/action/single_file_page.hbs
0 → 100644
1 | +<div class="pageheader"> | ||
2 | + <div class="media"> | ||
3 | + <div class="pageicon pull-left"> | ||
4 | + <i class="fa fa-th-list"></i> | ||
5 | + </div> | ||
6 | + <div class="media-body"> | ||
7 | + <ul class="breadcrumb"> | ||
8 | + <li><a href=""><i class="glyphicon glyphicon-home"></i></a></li> | ||
9 | + <li>静态资源</li> | ||
10 | + </ul> | ||
11 | + <h4>单文件上传</h4> | ||
12 | + </div> | ||
13 | + </div> | ||
14 | + <!-- media --> | ||
15 | +</div> | ||
16 | +<!-- pageheader --> | ||
17 | +<div class="contentpanel"> | ||
18 | + <div class="form"> | ||
19 | + <div class="form-group"> | ||
20 | + <label for=""></label> | ||
21 | + <div class="input-group"> | ||
22 | + <span class="input-group-addon">{{domain}}/</span> | ||
23 | + <input type="text" class="form-control" id="actPath" aria-describedby="basic-addon3" placeholder="请输入文件路径,例:20171030/v2.4.8"> | ||
24 | + </div> | ||
25 | + </div> | ||
26 | + <div class="form-group"> | ||
27 | + <label for="file">选择文件</label> | ||
28 | + <input type="file" class="form-control" name="file" id="fileInput"> | ||
29 | + </div> | ||
30 | + <input type="hidden" id="cover" name="cover"> | ||
31 | + <div class="form-group"> | ||
32 | + <button class="btn btn-default" id="upLoadBtn">上传</button> | ||
33 | + <span id="resultMsg"></span> | ||
34 | + </div> | ||
35 | + </div> | ||
36 | +</div> | ||
37 | + | ||
38 | +<script> | ||
39 | + $('#upLoadBtn').on('click', function(){ | ||
40 | + $('#upLoadBtn').attr('disabled', 'disabled'); | ||
41 | + | ||
42 | + var file = $('#fileInput').prop('files')[0]; | ||
43 | + var actPath = $('#actPath').val(); | ||
44 | + var formData = new FormData(); | ||
45 | + var cover = $('#cover').val(); | ||
46 | + | ||
47 | + formData.append('file', file); | ||
48 | + formData.append('actPath', actPath); | ||
49 | + formData.append('cover', cover); | ||
50 | + | ||
51 | + $.ajax({ | ||
52 | + type: 'POST', | ||
53 | + url: '/files/single-file-upload', | ||
54 | + cache: false, | ||
55 | + data: formData, | ||
56 | + dataType: 'json', | ||
57 | + processData: false, | ||
58 | + contentType: false, | ||
59 | + complete: function() { | ||
60 | + $('#upLoadBtn').removeAttr('disabled'); | ||
61 | + }, | ||
62 | + success: function(result) { | ||
63 | + if (result.code === 200) { | ||
64 | + $('#resultMsg').html(`<a target="_blank" href="${result.data.url}">${result.data.url}</a>`); | ||
65 | + } else { | ||
66 | + $('#resultMsg').html(result.message); | ||
67 | + } | ||
68 | + } | ||
69 | + }); | ||
70 | + }); | ||
71 | +</script> |
@@ -65,6 +65,7 @@ | @@ -65,6 +65,7 @@ | ||
65 | <ul class="children"> | 65 | <ul class="children"> |
66 | <li><a href="/check/list">代码检查</a></li> | 66 | <li><a href="/check/list">代码检查</a></li> |
67 | <li><a href="/files/page">活动上传</a></li> | 67 | <li><a href="/files/page">活动上传</a></li> |
68 | + <li><a href="/files/single-file">单文件上传</a></li> | ||
68 | </ul> | 69 | </ul> |
69 | </li> | 70 | </li> |
70 | 71 |
@@ -3,6 +3,13 @@ | @@ -3,6 +3,13 @@ | ||
3 | */ | 3 | */ |
4 | 4 | ||
5 | const CDNCONFIG = { | 5 | const CDNCONFIG = { |
6 | + main: { | ||
7 | + accessKey: 'cY9B5ZgON_7McTS5zV5nTeRyQ98MOcVD7W4eGVbE', | ||
8 | + secretKey: 'RduqgmK7cAtaQvdIa1ax_zzmMsnv9ac-Ka0uF6wG', | ||
9 | + origin: 'https://cdn.yoho.cn', | ||
10 | + bucket: 'yohocdn' | ||
11 | + }, | ||
12 | + | ||
6 | feature: { | 13 | feature: { |
7 | origin: 'https://feature.yoho.cn', | 14 | origin: 'https://feature.yoho.cn', |
8 | bucket: 'yohogirlzine' | 15 | bucket: 'yohogirlzine' |
@@ -6,22 +6,21 @@ | @@ -6,22 +6,21 @@ | ||
6 | 6 | ||
7 | 'use strict'; | 7 | 'use strict'; |
8 | 8 | ||
9 | +const CDNCONFIG = require('../config/cdn_config'); | ||
9 | const qn = require('qn'); | 10 | const qn = require('qn'); |
10 | const Promise = require('bluebird'); | 11 | const Promise = require('bluebird'); |
11 | const _ = require('lodash'); | 12 | const _ = require('lodash'); |
12 | 13 | ||
13 | -const config = { | ||
14 | - accessKey: 'cY9B5ZgON_7McTS5zV5nTeRyQ98MOcVD7W4eGVbE', | ||
15 | - secretKey: 'RduqgmK7cAtaQvdIa1ax_zzmMsnv9ac-Ka0uF6wG', | ||
16 | - origin: 'http://cdn.yoho.cn', | ||
17 | - bucket: 'yohocdn' | ||
18 | -}; | ||
19 | - | ||
20 | const _default = (params) => { | 14 | const _default = (params) => { |
21 | - let finalConfig = config; | 15 | + let finalConfig = _.cloneDeep(CDNCONFIG.main); |
22 | 16 | ||
23 | if (params) { | 17 | if (params) { |
24 | _.assign(finalConfig, params); | 18 | _.assign(finalConfig, params); |
19 | + | ||
20 | + // 传 key 强制覆盖 | ||
21 | + if (params.key) { | ||
22 | + finalConfig.bucket = params.bucket + ':' + params.key; | ||
23 | + } | ||
25 | } | 24 | } |
26 | 25 | ||
27 | return Promise.promisifyAll( | 26 | return Promise.promisifyAll( |
@@ -29,8 +28,11 @@ const _default = (params) => { | @@ -29,8 +28,11 @@ const _default = (params) => { | ||
29 | ); | 28 | ); |
30 | } | 29 | } |
31 | 30 | ||
31 | +/** | ||
32 | + * 兼容旧的强制覆盖逻辑,新功能开发弃用 | ||
33 | + */ | ||
32 | _default.key = function(key) { | 34 | _default.key = function(key) { |
33 | - let _conifg = _.clone(config); | 35 | + let _conifg = _.clone(CDNCONFIG.main); |
34 | _conifg.bucket = _conifg.bucket + ":" + key; | 36 | _conifg.bucket = _conifg.bucket + ":" + key; |
35 | return Promise.promisifyAll(qn.create(_conifg)); | 37 | return Promise.promisifyAll(qn.create(_conifg)); |
36 | }; | 38 | }; |
This diff could not be displayed because it is too large.
-
Please register or login to post a comment