Showing
4 changed files
with
221 additions
and
0 deletions
apps/web/actions/client-precache.js
0 → 100644
1 | + | ||
2 | +const Router = require('koa-router'); | ||
3 | +const _ = require('lodash'); | ||
4 | +const md5 = require('md5'); | ||
5 | +const stream = require('stream'); | ||
6 | + | ||
7 | +const CDNCONFIG = require('../../../config/cdn_config'); | ||
8 | + | ||
9 | + | ||
10 | +let r = new Router(); | ||
11 | + | ||
12 | +const manifestPath = 'client/precache/statics/manifest.json'; | ||
13 | + | ||
14 | +const client = { | ||
15 | + index: async(ctx, next) => { | ||
16 | + await ctx.render('action/client-precache', { | ||
17 | + manifestPath | ||
18 | + }); | ||
19 | + }, | ||
20 | + save: async(ctx, next) => { | ||
21 | + let files = ctx.request.body.files; | ||
22 | + let lastRevision = ctx.request.body.lastRevision; | ||
23 | + let trimFiles = []; | ||
24 | + | ||
25 | + _.forEach(files, val => { | ||
26 | + trimFiles.push(_.trim(val)); | ||
27 | + }); | ||
28 | + | ||
29 | + trimFiles = _.compact(trimFiles); | ||
30 | + | ||
31 | + let revision = md5(trimFiles); | ||
32 | + | ||
33 | + if (revision === lastRevision) { | ||
34 | + return ctx.body = { | ||
35 | + code: 400, | ||
36 | + message: '请修改后再保存' | ||
37 | + }; | ||
38 | + } | ||
39 | + | ||
40 | + let ste = new Buffer.from(JSON.stringify({ | ||
41 | + files: trimFiles, | ||
42 | + revision | ||
43 | + })); | ||
44 | + | ||
45 | + const bufferStream = new stream.PassThrough(); | ||
46 | + let readable = bufferStream.end(new Buffer.from(JSON.stringify({ | ||
47 | + files: trimFiles, | ||
48 | + revision | ||
49 | + }))); | ||
50 | + let config = _.cloneDeep(CDNCONFIG.main); | ||
51 | + | ||
52 | + _.assign(config, { | ||
53 | + key: manifestPath | ||
54 | + }); | ||
55 | + | ||
56 | + let qnMain = require('../../../lib/qiniu')(config); | ||
57 | + let upResult = await qnMain.uploadAsync(readable, {key: manifestPath}); | ||
58 | + | ||
59 | + if (upResult && upResult.url) { | ||
60 | + return ctx.body = { | ||
61 | + code: 200, | ||
62 | + message: '修改成功', | ||
63 | + data: { | ||
64 | + url: upResult.url | ||
65 | + } | ||
66 | + }; | ||
67 | + } else { | ||
68 | + return ctx.body = { | ||
69 | + code: 400, | ||
70 | + message: '修改失败' | ||
71 | + }; | ||
72 | + } | ||
73 | + } | ||
74 | +} | ||
75 | + | ||
76 | +r.get('/client', client.index); | ||
77 | +r.post('/client/save', client.save); | ||
78 | + | ||
79 | +module.exports = r; |
@@ -11,6 +11,7 @@ const monitor = require('./actions/monitor'); | @@ -11,6 +11,7 @@ const monitor = require('./actions/monitor'); | ||
11 | const users = require('./actions/users'); | 11 | const users = require('./actions/users'); |
12 | const hotfix = require('./actions/hotfix'); | 12 | const hotfix = require('./actions/hotfix'); |
13 | const operationLog = require('./actions/operation_log'); | 13 | const operationLog = require('./actions/operation_log'); |
14 | +const clientPrecache = require('./actions/client-precache'); | ||
14 | const pageCache = require('./actions/page_cache'); | 15 | const pageCache = require('./actions/page_cache'); |
15 | const cdnCache = require('./actions/cdn_cache'); | 16 | const cdnCache = require('./actions/cdn_cache'); |
16 | const productCache = require('./actions/product_cache'); | 17 | const productCache = require('./actions/product_cache'); |
@@ -57,6 +58,7 @@ module.exports = function(app) { | @@ -57,6 +58,7 @@ module.exports = function(app) { | ||
57 | base.use('/monitor', monitor.routes(), monitor.allowedMethods()); | 58 | base.use('/monitor', monitor.routes(), monitor.allowedMethods()); |
58 | base.use('/users', users.routes(), users.allowedMethods()); | 59 | base.use('/users', users.routes(), users.allowedMethods()); |
59 | // base.use('/hotfix', hotfix.routes(), hotfix.allowedMethods()); | 60 | // base.use('/hotfix', hotfix.routes(), hotfix.allowedMethods()); |
61 | + base.use('/precache', clientPrecache.routes(), clientPrecache.allowedMethods()); | ||
60 | base.use('/operation', operationLog.routes(), operationLog.allowedMethods()); | 62 | base.use('/operation', operationLog.routes(), operationLog.allowedMethods()); |
61 | base.use('/check', checkcode.routes(), checkcode.allowedMethods()); | 63 | base.use('/check', checkcode.routes(), checkcode.allowedMethods()); |
62 | base.use('/page_cache', pageCache.routes(), pageCache.allowedMethods()); | 64 | base.use('/page_cache', pageCache.routes(), pageCache.allowedMethods()); |
apps/web/views/action/client-precache.hbs
0 → 100644
1 | +<style type="text/css"> | ||
2 | +.panel-body-container { | ||
3 | + position: relative; | ||
4 | + min-height: 100px; | ||
5 | +} | ||
6 | + | ||
7 | +.edit-area { | ||
8 | + width: 100%; | ||
9 | + position: absolute; | ||
10 | + left: 0; | ||
11 | + top: 0; | ||
12 | + bottom: 0; | ||
13 | +} | ||
14 | + | ||
15 | +.edit-area > textarea { | ||
16 | + width: 100%; | ||
17 | + height: 100%; | ||
18 | +} | ||
19 | + | ||
20 | +.pannel-option > * { | ||
21 | + margin-left: 10px; | ||
22 | +} | ||
23 | + | ||
24 | +.pannel-option .save, | ||
25 | +.pannel-option .cancle { | ||
26 | + display: none; | ||
27 | +} | ||
28 | + | ||
29 | +.pannel-option.pannel-edit .edit { | ||
30 | + display: none; | ||
31 | +} | ||
32 | + | ||
33 | +.pannel-option.pannel-edit .cancle, | ||
34 | +.pannel-option.pannel-edit .save { | ||
35 | + display: inline; | ||
36 | +} | ||
37 | + | ||
38 | +.edit-area { | ||
39 | + display: none; | ||
40 | +} | ||
41 | +</style> | ||
42 | + | ||
43 | +<div class="pageheader"> | ||
44 | + <div class="media"> | ||
45 | + <div class="pageicon pull-left"> | ||
46 | + <i class="fa fa-th-list"></i> | ||
47 | + </div> | ||
48 | + <div class="media-body"> | ||
49 | + <ul class="breadcrumb"> | ||
50 | + <li><a href="/"><i class="glyphicon glyphicon-home"></i></a></li> | ||
51 | + <li><a href="/servers">Projects</a></li> | ||
52 | + </ul> | ||
53 | + <h4>客户端预加载清单</h4> | ||
54 | + </div> | ||
55 | + </div> | ||
56 | + <!-- media --> | ||
57 | +</div> | ||
58 | + | ||
59 | +<div class="contentpanel task-panel" style="padding-bottom:0;"> | ||
60 | + <!-- pageheader --> | ||
61 | + <div class="panel panel-default"> | ||
62 | + <div class="panel-heading"> | ||
63 | + <div class="pull-right pannel-option"> | ||
64 | + <a href="javascript:;" class="tooltips edit">编辑</a> | ||
65 | + <a href="javascript:;" class="tooltips save">保存</a> | ||
66 | + <a href="javascript:;" class="tooltips cancle">取消</a> | ||
67 | + </div> | ||
68 | + <h4 class="panel-title">预加载清单</h4> | ||
69 | + </div> | ||
70 | + <div class="panel-body"> | ||
71 | + <div class="panel-body-container"> | ||
72 | + <div id="edit-area" class="edit-area"> | ||
73 | + <textarea id="textarea" class="form-control" pleaceholder="支持多条换行输入"></textarea> | ||
74 | + </div> | ||
75 | + <div id="static-list" class="static-list"></div> | ||
76 | + </div> | ||
77 | + </div> | ||
78 | + </div> | ||
79 | +</div> | ||
80 | + | ||
81 | +<script> | ||
82 | + var files = []; | ||
83 | + var revision = '' | ||
84 | + | ||
85 | + function resetManifest(list) { | ||
86 | + files = list || []; | ||
87 | + | ||
88 | + var h = ''; | ||
89 | + | ||
90 | + for (var i = 0; i < files.length; i++) { | ||
91 | + h += '<p>' + files[i] + '</p>'; | ||
92 | + } | ||
93 | + | ||
94 | + $('#static-list').html(h); | ||
95 | + } | ||
96 | + | ||
97 | + function getManifest(file) { | ||
98 | + $.get(file + '?t=' + new Date().getTime(), function(res) { | ||
99 | + if (res && res.files) { | ||
100 | + resetManifest(res.files); | ||
101 | + revision = res.revision; | ||
102 | + }; | ||
103 | + }); | ||
104 | + } | ||
105 | + | ||
106 | + $('.pannel-option').on('click', '.tooltips', function() { | ||
107 | + var $this = $(this), | ||
108 | + $par = $this.parent(), | ||
109 | + $edit = $('#edit-area'); | ||
110 | + | ||
111 | + $par.toggleClass('pannel-edit'); | ||
112 | + | ||
113 | + if ($this.hasClass('save')) { | ||
114 | + var _files = $('#textarea').val().split('\n'); | ||
115 | + $.post('/precache/client/save', { | ||
116 | + files: _files, | ||
117 | + lastRevision: revision | ||
118 | + }, function(res) { | ||
119 | + if (res.code === 200) { | ||
120 | + getManifest(res.data.url); | ||
121 | + $edit.hide(); | ||
122 | + } else { | ||
123 | + $par.addClass('pannel-edit'); | ||
124 | + alert(res.message || '保存失败'); | ||
125 | + } | ||
126 | + }); | ||
127 | + } else if ($this.hasClass('edit')) { | ||
128 | + $('#textarea').val(files.join('\n')); | ||
129 | + $edit.show(); | ||
130 | + } else { | ||
131 | + $edit.hide(); | ||
132 | + } | ||
133 | + }); | ||
134 | + | ||
135 | + getManifest('//cdn.yoho.cn/{{manifestPath}}'); | ||
136 | +</script> |
@@ -26,6 +26,10 @@ const normalMenus = [ | @@ -26,6 +26,10 @@ const normalMenus = [ | ||
26 | title: 'Memcached', | 26 | title: 'Memcached', |
27 | link: '/api_cache', | 27 | link: '/api_cache', |
28 | isClassic: true | 28 | isClassic: true |
29 | + }, { | ||
30 | + title: '客户端预加载', | ||
31 | + link: '/precache/client', | ||
32 | + isClassic: true | ||
29 | }] | 33 | }] |
30 | }, | 34 | }, |
31 | { | 35 | { |
-
Please register or login to post a comment