Showing
11 changed files
with
313 additions
and
1 deletions
apps/models/degrade.js
0 → 100644
1 | +'use strict'; | ||
2 | + | ||
3 | +import Model from './model'; | ||
4 | +import _ from 'lodash'; | ||
5 | + | ||
6 | +const defaultDegrades = [ | ||
7 | + { | ||
8 | + path: '/pc/common/myYohoHover', | ||
9 | + name: '【公共头部】MY有货鼠标移入显示账户信息' | ||
10 | + }, | ||
11 | + { | ||
12 | + path: '/pc/common/cartCountShow', | ||
13 | + name: '【公共头部】购物车图标显示购物车商品数目' | ||
14 | + }, | ||
15 | + { | ||
16 | + path: '/pc/common/cartHover', | ||
17 | + name: '【公共头部】购物车图标鼠标移入请求、显示购物车商品列表' | ||
18 | + }, | ||
19 | + { | ||
20 | + path: '/pc/brandInfoTipSHow', | ||
21 | + name: '【品牌一览】品牌名移入显示品牌简介Tip' | ||
22 | + }, | ||
23 | + { | ||
24 | + path: '/pc/recentViewShow', | ||
25 | + name: '【商品列表/商品详情】显示最近浏览' | ||
26 | + }, | ||
27 | + { | ||
28 | + path: '/pc/guang/hotTagShow', | ||
29 | + name: '【逛】显示热门标签' | ||
30 | + }, | ||
31 | + { | ||
32 | + path: '/pc/guang/adShow', | ||
33 | + name: '【逛】显示广告banner' | ||
34 | + }, | ||
35 | + { | ||
36 | + path: '/pc/guang/itemCommentShow', | ||
37 | + name: '【逛】详情页显示评论' | ||
38 | + }, | ||
39 | + { | ||
40 | + path: '/wap/plustar/collect', | ||
41 | + name: '【Plustar】品牌收藏' | ||
42 | + } | ||
43 | +]; | ||
44 | + | ||
45 | +class Degrade extends Model { | ||
46 | + | ||
47 | + constructor() { | ||
48 | + super('degrade'); | ||
49 | + } | ||
50 | + | ||
51 | + async init() { | ||
52 | + for (let i of defaultDegrades) { | ||
53 | + let count = await this.count({ | ||
54 | + path: i.path | ||
55 | + }); | ||
56 | + | ||
57 | + if (count === 0) { | ||
58 | + await this.insert(i); | ||
59 | + } | ||
60 | + } | ||
61 | + } | ||
62 | +} | ||
63 | + | ||
64 | +export default Degrade; |
@@ -8,6 +8,7 @@ import DeployModel from './deploy'; | @@ -8,6 +8,7 @@ import DeployModel from './deploy'; | ||
8 | import UserModel from './user'; | 8 | import UserModel from './user'; |
9 | import HotfixModel from './hotfix'; | 9 | import HotfixModel from './hotfix'; |
10 | import OperationLoggerModel from './operation_logger'; | 10 | import OperationLoggerModel from './operation_logger'; |
11 | +import DegradeModel from './degrade'; | ||
11 | 12 | ||
12 | shelljs.mkdir('-p', config.dbDir); | 13 | shelljs.mkdir('-p', config.dbDir); |
13 | 14 | ||
@@ -18,9 +19,12 @@ const DeployInfo = new DeployModel(); | @@ -18,9 +19,12 @@ const DeployInfo = new DeployModel(); | ||
18 | const User = new UserModel(); | 19 | const User = new UserModel(); |
19 | const Hotfix = new HotfixModel(); | 20 | const Hotfix = new HotfixModel(); |
20 | const OperationLogger = new OperationLoggerModel(); | 21 | const OperationLogger = new OperationLoggerModel(); |
22 | +const Degrade = new DegradeModel(); | ||
21 | 23 | ||
22 | User.init(); | 24 | User.init(); |
23 | 25 | ||
26 | +Degrade.init(); | ||
27 | + | ||
24 | export { | 28 | export { |
25 | Server, | 29 | Server, |
26 | Building, | 30 | Building, |
@@ -28,5 +32,6 @@ export { | @@ -28,5 +32,6 @@ export { | ||
28 | DeployInfo, | 32 | DeployInfo, |
29 | User, | 33 | User, |
30 | Hotfix, | 34 | Hotfix, |
31 | - OperationLogger | 35 | + OperationLogger, |
36 | + Degrade | ||
32 | }; | 37 | }; |
apps/web/actions/degrade.js
0 → 100644
1 | +'use strict'; | ||
2 | + | ||
3 | +import Router from 'koa-router'; | ||
4 | +import moment from 'moment'; | ||
5 | +import _ from 'lodash'; | ||
6 | + | ||
7 | +import {Degrade} from '../../models'; | ||
8 | + | ||
9 | +import getter from '../../zookeeper/getter'; | ||
10 | +import setter from '../../zookeeper/setter'; | ||
11 | + | ||
12 | +const router = new Router(); | ||
13 | + | ||
14 | +const ctl = { | ||
15 | + async index (ctx) { | ||
16 | + let degrades = await Degrade.findAll(); | ||
17 | + | ||
18 | + for (let i of degrades) { | ||
19 | + i.checked = await getter(i.path); | ||
20 | + } | ||
21 | + | ||
22 | + let pc = _.filter(degrades, o => _.startsWith(o.path, '/pc')); | ||
23 | + let wap = _.filter(degrades, o => _.startsWith(o.path, '/wap')); | ||
24 | + | ||
25 | + await ctx.render('action/degrade', { | ||
26 | + pc: pc, | ||
27 | + wap: wap | ||
28 | + }); | ||
29 | + }, | ||
30 | + async setter(ctx) { | ||
31 | + let {checked, id} = ctx.query; | ||
32 | + | ||
33 | + let theDegrade = await Degrade.findById(id); | ||
34 | + | ||
35 | + let path = theDegrade.path; | ||
36 | + | ||
37 | + await setter(path, checked.toString()); | ||
38 | + | ||
39 | + ctx.body = { | ||
40 | + code: 200, | ||
41 | + message: 'update success' | ||
42 | + }; | ||
43 | + } | ||
44 | +}; | ||
45 | + | ||
46 | +router.get('/', ctl.index); | ||
47 | +router.get('/setter', ctl.setter); | ||
48 | + | ||
49 | +export default router; |
@@ -9,6 +9,7 @@ import monitor from './actions/monitor'; | @@ -9,6 +9,7 @@ import monitor from './actions/monitor'; | ||
9 | import users from './actions/users'; | 9 | import users from './actions/users'; |
10 | import hotfix from './actions/hotfix'; | 10 | import hotfix from './actions/hotfix'; |
11 | import operationLog from './actions/operation_log'; | 11 | import operationLog from './actions/operation_log'; |
12 | +import degrade from './actions/degrade'; | ||
12 | 13 | ||
13 | const noAuth = new Router(); | 14 | const noAuth = new Router(); |
14 | const base = new Router(); | 15 | const base = new Router(); |
@@ -35,6 +36,8 @@ export default function (app) { | @@ -35,6 +36,8 @@ export default function (app) { | ||
35 | base.use('/hotfix', hotfix.routes(), hotfix.allowedMethods()); | 36 | base.use('/hotfix', hotfix.routes(), hotfix.allowedMethods()); |
36 | base.use('/operation', operationLog.routes(), operationLog.allowedMethods()); | 37 | base.use('/operation', operationLog.routes(), operationLog.allowedMethods()); |
37 | 38 | ||
39 | + base.use('/degrade', degrade.routes(), degrade.allowedMethods()); | ||
40 | + | ||
38 | base.use('', index.routes(), index.allowedMethods()); | 41 | base.use('', index.routes(), index.allowedMethods()); |
39 | 42 | ||
40 | app.use(base.routes(), base.allowedMethods()); | 43 | app.use(base.routes(), base.allowedMethods()); |
apps/web/views/action/degrade.hbs
0 → 100644
1 | +<style> | ||
2 | + .degrade-tab li { | ||
3 | + cursor: pointer; | ||
4 | + } | ||
5 | + | ||
6 | + .pc-degrade, | ||
7 | + .wap-degrade { | ||
8 | + list-style: none; | ||
9 | + padding: 20px; | ||
10 | + } | ||
11 | +</style> | ||
12 | +<ul id="degrade-tab" class="nav nav-tabs degrade-tab" role="tablist"> | ||
13 | + <li role="presentation" class="active"> | ||
14 | + <a>PC</a> | ||
15 | + </li> | ||
16 | + <li role="presentation"> | ||
17 | + <a>WAP</a> | ||
18 | + </li> | ||
19 | +</ul> | ||
20 | + | ||
21 | +<ul class="pc-degrade degrade-content"> | ||
22 | + {{#each pc}} | ||
23 | + <li data-id="{{_id}}"> | ||
24 | + <div class="checkbox"> | ||
25 | + <label> | ||
26 | + <input type="checkbox"{{#if checked}} checked{{/if}}> | ||
27 | + {{name}} | ||
28 | + </label> | ||
29 | + </div> | ||
30 | + </li> | ||
31 | + {{/each}} | ||
32 | +</ul> | ||
33 | + | ||
34 | +<ul class="wap-degrade hide"> | ||
35 | + {{#each wap}} | ||
36 | + <li data-id="{{_id}}"> | ||
37 | + <div class="checkbox"> | ||
38 | + <label> | ||
39 | + <input type="checkbox"{{#if checked}} checked{{/if}}> | ||
40 | + {{name}} | ||
41 | + </label> | ||
42 | + </div> | ||
43 | + </li> | ||
44 | + {{/each}} | ||
45 | +</ul> | ||
46 | + | ||
47 | +<script> | ||
48 | + $(function() { | ||
49 | + $('#degrade-tab').on('click', 'li', function() { | ||
50 | + var $this = $(this); | ||
51 | + | ||
52 | + if ($this.hasClass('active')) { | ||
53 | + return; | ||
54 | + } | ||
55 | + | ||
56 | + $('li', $('#degrade-tab')).toggleClass('active'); | ||
57 | + | ||
58 | + var index = $this.index(); | ||
59 | + | ||
60 | + if (index === 0) { | ||
61 | + | ||
62 | + //PC active | ||
63 | + $('.pc-degrade').removeClass('hide'); | ||
64 | + $('.wap-degrade').addClass('hide'); | ||
65 | + } else { | ||
66 | + | ||
67 | + // wap active | ||
68 | + $('.wap-degrade').removeClass('hide'); | ||
69 | + $('.pc-degrade').addClass('hide'); | ||
70 | + } | ||
71 | + }); | ||
72 | + | ||
73 | + // change | ||
74 | + $('.degrade-content input[type="checkbox"]').change(function() { | ||
75 | + var $checkbox = $(this), | ||
76 | + $li = $checkbox.closest('li'); | ||
77 | + | ||
78 | + var checked = $checkbox.prop('checked'); | ||
79 | + | ||
80 | + var id = $li.data('id'); | ||
81 | + | ||
82 | + $.ajax({ | ||
83 | + url: '/degrade/setter', | ||
84 | + data: { | ||
85 | + checked: checked, | ||
86 | + id: id | ||
87 | + } | ||
88 | + }); | ||
89 | + }); | ||
90 | + }) | ||
91 | +</script> |
apps/zookeeper/config.js
0 → 100644
apps/zookeeper/creator.js
0 → 100644
1 | +'use strict'; | ||
2 | + | ||
3 | +import zookeeper from 'node-zookeeper-client'; | ||
4 | +import config from './config'; | ||
5 | + | ||
6 | +module.exports = (path) => { | ||
7 | + const client = zookeeper.createClient(config.server); | ||
8 | + | ||
9 | + client.once('connected', () => { | ||
10 | + client.mkdirp(path, new Buffer('true'), (err, path) => { | ||
11 | + if (err) { | ||
12 | + console.log('Node %s create err', path, err.stack); | ||
13 | + } else { | ||
14 | + console.log('Node %s is created', path); | ||
15 | + } | ||
16 | + | ||
17 | + client.close(); | ||
18 | + }); | ||
19 | + }); | ||
20 | + | ||
21 | + client.connect(); | ||
22 | +}; |
apps/zookeeper/getter.js
0 → 100644
1 | +'usu strict'; | ||
2 | + | ||
3 | +import _ from 'lodash'; | ||
4 | +import zookeeper from 'node-zookeeper-client'; | ||
5 | + | ||
6 | +import config from './config'; | ||
7 | +import creator from './creator'; | ||
8 | + | ||
9 | +const getter = (client, path, resolve, reject) => { | ||
10 | + client.exists(path, (err, stat) => { | ||
11 | + if (err) { | ||
12 | + console.log('path %s exits error', path, err.stack); | ||
13 | + resolve(true); | ||
14 | + return; | ||
15 | + } | ||
16 | + | ||
17 | + if (stat) { | ||
18 | + client.getData( | ||
19 | + path, | ||
20 | + (err, data, stat) => { | ||
21 | + if (err) { | ||
22 | + console.log('Got path %s data error', path, err.stack); | ||
23 | + } | ||
24 | + | ||
25 | + resolve(data ? data.toString('utf8') === 'true' : true); | ||
26 | + client.close(); | ||
27 | + } | ||
28 | + ) | ||
29 | + } else { | ||
30 | + // 不存在的路径 | ||
31 | + console.log('no path %s, we will create it with value "true" automatic', path); | ||
32 | + client.close(); | ||
33 | + | ||
34 | + // create path | ||
35 | + creator(path); | ||
36 | + | ||
37 | + resolve(true); | ||
38 | + } | ||
39 | + }); | ||
40 | + | ||
41 | +}; | ||
42 | + | ||
43 | +module.exports = (path) => new Promise((resolve, reject) => { | ||
44 | + const client = zookeeper.createClient(config.server); | ||
45 | + | ||
46 | + client.once('connected', () => { | ||
47 | + getter(client, path, resolve, reject); | ||
48 | + }); | ||
49 | + | ||
50 | + client.connect(); | ||
51 | +}); |
apps/zookeeper/setter.js
0 → 100644
1 | +'usu strict'; | ||
2 | + | ||
3 | +import _ from 'lodash'; | ||
4 | +import zookeeper from 'node-zookeeper-client'; | ||
5 | + | ||
6 | +import config from './config'; | ||
7 | + | ||
8 | +module.exports = (path, val) => new Promise((resolve, reject) => { | ||
9 | + const client = zookeeper.createClient(config.server); | ||
10 | + | ||
11 | + client.once('connected', function () { | ||
12 | + client.setData(path, new Buffer(val.toString()), function(err, data, stat) { | ||
13 | + console.log('path %s data change to', path, val); | ||
14 | + resolve(); | ||
15 | + client.close(); | ||
16 | + }); | ||
17 | + }); | ||
18 | + | ||
19 | + client.connect(); | ||
20 | +}); |
@@ -54,6 +54,7 @@ | @@ -54,6 +54,7 @@ | ||
54 | "moment": "^2.13.0", | 54 | "moment": "^2.13.0", |
55 | "nedb": "^1.8.0", | 55 | "nedb": "^1.8.0", |
56 | "nedb-promise": "^2.0.0", | 56 | "nedb-promise": "^2.0.0", |
57 | + "node-zookeeper-client": "^0.2.2", | ||
57 | "qn": "^1.3.0", | 58 | "qn": "^1.3.0", |
58 | "qs": "^6.2.0", | 59 | "qs": "^6.2.0", |
59 | "shelljs": "^0.7.0", | 60 | "shelljs": "^0.7.0", |
-
Please register or login to post a comment