Authored by 李奇

活动管理修改

@@ -15,6 +15,7 @@ const bodyParser = require('body-parser'); @@ -15,6 +15,7 @@ const bodyParser = require('body-parser');
15 const compression = require('compression'); 15 const compression = require('compression');
16 const cookieParser = require('cookie-parser'); 16 const cookieParser = require('cookie-parser');
17 const cookieSession = require('cookie-session'); 17 const cookieSession = require('cookie-session');
  18 +const favicon = require('serve-favicon');
18 const moment = require('moment'); 19 const moment = require('moment');
19 const _ = require('lodash'); 20 const _ = require('lodash');
20 const pkg = require('./package.json'); 21 const pkg = require('./package.json');
@@ -36,13 +37,14 @@ global.yoho.utils = { @@ -36,13 +37,14 @@ global.yoho.utils = {
36 mysqlCli: new SqlHelper(config.mysql.database) 37 mysqlCli: new SqlHelper(config.mysql.database)
37 }; 38 };
38 39
39 -app.use(express.static('public'));  
40 app.use(cookieSession({ 40 app.use(cookieSession({
41 name: 'yoho_activity', 41 name: 'yoho_activity',
42 secret: 'activity@yoho', 42 secret: 'activity@yoho',
43 maxAge: 24 * 60 * 60 * 1000 43 maxAge: 24 * 60 * 60 * 1000
44 })); 44 }));
45 app.use(compression()); 45 app.use(compression());
  46 +app.use(favicon(path.join(__dirname, '/favicon.ico')));
  47 +app.use(express.static(path.join(__dirname, 'public')));
46 app.use(bodyParser.json()); 48 app.use(bodyParser.json());
47 app.use(bodyParser.urlencoded({ 49 app.use(bodyParser.urlencoded({
48 extended: false 50 extended: false
@@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
4 * @date: 23/06/2017 4 * @date: 23/06/2017
5 */ 5 */
6 const _ = require('lodash'); 6 const _ = require('lodash');
  7 +const moment = require('moment');
7 const AdminModel = require('../models/admin'); 8 const AdminModel = require('../models/admin');
8 9
9 const POST_SUCCESS = '操作成功'; 10 const POST_SUCCESS = '操作成功';
@@ -110,11 +111,27 @@ const article = { @@ -110,11 +111,27 @@ const article = {
110 * @param next 111 * @param next
111 */ 112 */
112 activityListPage(req, res, next) { 113 activityListPage(req, res, next) {
  114 + const _timeFormat = (time) => {
  115 + if (_.isNumber(time)) {
  116 + time = moment.unix(time);
  117 + }
  118 +
  119 + return moment(time).format('YYYY-MM-DD HH:mm:ss');
  120 + };
  121 +
113 req.ctx(AdminModel).activityList() 122 req.ctx(AdminModel).activityList()
114 .then(result => { 123 .then(result => {
  124 + _.each(result, item => {
  125 + item.endTime = _timeFormat(item.endTime);
  126 + item.startTime = _timeFormat(item.startTime);
  127 + item.createTime = _timeFormat(item.createTime);
  128 + });
  129 +
115 res.render('activity/list', { 130 res.render('activity/list', {
116 bodyClass: 'nav-md', 131 bodyClass: 'nav-md',
117 - activityList: result 132 + activityList: result,
  133 + module: 'admin',
  134 + page: 'activity'
118 }); 135 });
119 }) 136 })
120 .catch(next); 137 .catch(next);
@@ -165,6 +182,32 @@ const article = { @@ -165,6 +182,32 @@ const article = {
165 module: 'admin', 182 module: 'admin',
166 page: 'activity' 183 page: 'activity'
167 }); 184 });
  185 + },
  186 +
  187 + /**
  188 + * 活动删除
  189 + * @param req
  190 + * @param res
  191 + * @param next
  192 + */
  193 + deleteActivity(req, res, next) {
  194 + const id = req.body.id;
  195 +
  196 + if (!id) {
  197 + return res.json({
  198 + code: 400,
  199 + message: INVALID_PARAMS
  200 + });
  201 + }
  202 +
  203 + req.ctx(AdminModel).deleteActivity(id)
  204 + .then(() => {
  205 + return res.json({
  206 + code: 200,
  207 + message: POST_SUCCESS
  208 + });
  209 + })
  210 + .catch(next);
168 } 211 }
169 }; 212 };
170 213
1 /** 1 /**
2 - * 文章model 2 + * 管理model
3 * @author: leo <qi.li@yoho.cn> 3 * @author: leo <qi.li@yoho.cn>
4 * @date: 28/06/2017 4 * @date: 28/06/2017
5 */ 5 */
@@ -37,7 +37,21 @@ class AdminModel extends global.yoho.BaseModel { @@ -37,7 +37,21 @@ class AdminModel extends global.yoho.BaseModel {
37 */ 37 */
38 activityList() { 38 activityList() {
39 return mysqlCli.query( 39 return mysqlCli.query(
40 - `select title, start_time startTime, end_time endTime, create_time createTime from ${TABLE_ACTIVITY};` 40 + `select id, title, start_time startTime, end_time endTime, create_time createTime from ${TABLE_ACTIVITY};`
  41 + );
  42 + }
  43 +
  44 + /**
  45 + * 删除活动
  46 + * @param actId 活动ID
  47 + * @returns {*}
  48 + */
  49 + deleteActivity(actId) {
  50 + return mysqlCli.delete(
  51 + `delete from ${TABLE_ACTIVITY} where id = :actId;`,
  52 + {
  53 + actId
  54 + }
41 ); 55 );
42 } 56 }
43 } 57 }
@@ -19,5 +19,6 @@ router.post('/api/login', admin.login); @@ -19,5 +19,6 @@ router.post('/api/login', admin.login);
19 router.post('/api/logout', admin.logout); 19 router.post('/api/logout', admin.logout);
20 router.post('/api/activity/list', admin.activityList); 20 router.post('/api/activity/list', admin.activityList);
21 router.post('/api/activity/create', admin.createActivity); 21 router.post('/api/activity/create', admin.createActivity);
  22 +router.post('/api/activity/delete', admin.deleteActivity);
22 23
23 module.exports = router; 24 module.exports = router;
@@ -17,31 +17,28 @@ @@ -17,31 +17,28 @@
17 <div class="col-md-6 col-sm-6 col-xs-12"> 17 <div class="col-md-6 col-sm-6 col-xs-12">
18 <input id="actName" class="form-control col-md-7 col-xs-12" 18 <input id="actName" class="form-control col-md-7 col-xs-12"
19 data-validate-length-range="6" data-validate-words="2" name="actName" 19 data-validate-length-range="6" data-validate-words="2" name="actName"
20 - type="text"> 20 + type="text" maxlength="50">
21 </div> 21 </div>
22 </div> 22 </div>
23 <div class="item form-group"> 23 <div class="item form-group">
24 - <label class="control-label col-md-3 col-sm-3 col-xs-12" for="startTime">开始时间<span 24 + <label class="control-label col-md-3 col-sm-3 col-xs-12" for="activityTime">活动时间<span
25 class="required">*</span> 25 class="required">*</span>
26 </label> 26 </label>
27 <div class="col-md-6 col-sm-6 col-xs-12"> 27 <div class="col-md-6 col-sm-6 col-xs-12">
28 - <input type="datetime" id="startTime" name="startTime" required="required"  
29 - class="form-control col-md-7 col-xs-12">  
30 - </div>  
31 - </div>  
32 - <div class="item form-group">  
33 - <label class="control-label col-md-3 col-sm-3 col-xs-12" for="endTime">结束时间<span  
34 - class="required">*</span>  
35 - </label>  
36 - <div class="col-md-6 col-sm-6 col-xs-12">  
37 - <input type="datetime" id="endTime" name="endTime" required="required"  
38 - class="form-control col-md-7 col-xs-12"> 28 + <div class="input-prepend input-group">
  29 + <span class="add-on input-group-addon"><i
  30 + class="glyphicon glyphicon-calendar fa fa-calendar"></i></span>
  31 + <input type="text" name="activityTime" id="activityTime"
  32 + class="form-control col-md-7 col-xs-12"
  33 + placeholder="开始时间 - 结束时间"/>
  34 + </div>
39 </div> 35 </div>
  36 +
40 </div> 37 </div>
41 <div class="ln_solid"></div> 38 <div class="ln_solid"></div>
42 <div class="form-group"> 39 <div class="form-group">
43 <div class="col-md-6 col-md-offset-3"> 40 <div class="col-md-6 col-md-offset-3">
44 - <button class="btn btn-success create-btn">创建活动</button> 41 + <a class="btn btn-success create-btn">创建活动</a>
45 </div> 42 </div>
46 </div> 43 </div>
47 </form> 44 </form>
@@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
19 <th class="column-title">结束时间</th> 19 <th class="column-title">结束时间</th>
20 <th class="column-title">创建时间</th> 20 <th class="column-title">创建时间</th>
21 <th class="column-title">活动状态</th> 21 <th class="column-title">活动状态</th>
  22 + <th class="column-title">操作</th>
22 </tr> 23 </tr>
23 </thead> 24 </thead>
24 25
@@ -30,6 +31,11 @@ @@ -30,6 +31,11 @@
30 <td class=" ">{{endTime}}</td> 31 <td class=" ">{{endTime}}</td>
31 <td class=" ">{{createTime}}</td> 32 <td class=" ">{{createTime}}</td>
32 <td class=" ">未开始</td> 33 <td class=" ">未开始</td>
  34 + <td class=" ">
  35 + <button class="btn btn-info">活动文章</button>
  36 + <button class="btn btn-primary">编辑</button>
  37 + <button class="btn btn-danger btn-delete" data-id="{{id}}">删除</button>
  38 + </td>
33 </tr> 39 </tr>
34 {{/each}} 40 {{/each}}
35 </tbody> 41 </tbody>
@@ -37,7 +37,7 @@ @@ -37,7 +37,7 @@
37 <div class="clearfix"></div> 37 <div class="clearfix"></div>
38 <br/> 38 <br/>
39 <div> 39 <div>
40 - <p>©2017-2020 All Rights Reserved.</p> 40 + <p>YOHO! Activity Platform ©2017-2020 All Rights Reserved.</p>
41 </div> 41 </div>
42 </div> 42 </div>
43 </form> 43 </form>
@@ -47,7 +47,7 @@ const cssLoader = (env, type) => { @@ -47,7 +47,7 @@ const cssLoader = (env, type) => {
47 47
48 const getEntries = () => { 48 const getEntries = () => {
49 const entries = { 49 const entries = {
50 - libs: ['yoho-jquery', path.join(__dirname, '../public/js/global.js')], 50 + libs: ['jquery', path.join(__dirname, '../public/js/global.js')],
51 common: path.join(__dirname, '../public/scss/common.css'), 51 common: path.join(__dirname, '../public/scss/common.css'),
52 }; 52 };
53 53
@@ -114,11 +114,11 @@ module.exports = (env) => { @@ -114,11 +114,11 @@ module.exports = (env) => {
114 filename: 'libs.js' 114 filename: 'libs.js'
115 }), 115 }),
116 new webpack.ProvidePlugin({ 116 new webpack.ProvidePlugin({
117 - $: 'yoho-jquery',  
118 - jQuery: 'yoho-jquery',  
119 - 'window.jQuery': 'yoho-jquery' 117 + $: 'jquery',
  118 + jQuery: 'jquery',
  119 + 'window.jQuery': 'jquery'
120 }), 120 }),
121 // new (require('webpack-bundle-analyzer').BundleAnalyzerPlugin) 121 // new (require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
122 ] 122 ]
123 }; 123 };
124 -};  
  124 +};
@@ -20,5 +20,4 @@ module.exports = app => { @@ -20,5 +20,4 @@ module.exports = app => {
20 20
21 // 文章 21 // 文章
22 app.use('/article', article); 22 app.use('/article', article);
23 -  
24 }; 23 };
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <meta charset="utf-8"> 5 <meta charset="utf-8">
6 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta http-equiv="X-UA-Compatible" content="IE=edge">
7 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 <meta name="viewport" content="width=device-width, initial-scale=1">
8 - <title>YOHO!Activity Admin</title> 8 + <title>YOHO!活动平台</title>
9 9
10 {{#if devEnv}} 10 {{#if devEnv}}
11 <link rel="stylesheet" media="all" href="//{{devHost}}:5001/common.css?t={{startTime}}"> 11 <link rel="stylesheet" media="all" href="//{{devHost}}:5001/common.css?t={{startTime}}">
@@ -31,7 +31,7 @@ @@ -31,7 +31,7 @@
31 <!-- menu profile quick info --> 31 <!-- menu profile quick info -->
32 <div class="profile clearfix"> 32 <div class="profile clearfix">
33 <div class="profile_pic"> 33 <div class="profile_pic">
34 - <img src="/img/admin/admin_avatar.png" alt="..." class="img-circle profile_img"> 34 + <img src="{{imgSrc 'img/admin/admin_avatar.png'}}" alt="..." class="img-circle profile_img">
35 </div> 35 </div>
36 <div class="profile_info"> 36 <div class="profile_info">
37 <span>Welcome,</span> 37 <span>Welcome,</span>
@@ -47,13 +47,6 @@ @@ -47,13 +47,6 @@
47 <div id="sidebar-menu" class="main_menu_side hidden-print main_menu"> 47 <div id="sidebar-menu" class="main_menu_side hidden-print main_menu">
48 <div class="menu_section"> 48 <div class="menu_section">
49 <ul class="nav side-menu"> 49 <ul class="nav side-menu">
50 - <li><a><i class="fa fa-home"></i> Home <span class="fa fa-chevron-down"></span></a>  
51 - <ul class="nav child_menu">  
52 - <li><a href="index.html">Dashboard</a></li>  
53 - <li><a href="index2.html">Dashboard2</a></li>  
54 - <li><a href="index3.html">Dashboard3</a></li>  
55 - </ul>  
56 - </li>  
57 <li><a><i class="fa fa-edit"></i> 活动管理 <span class="fa fa-chevron-down"></span></a> 50 <li><a><i class="fa fa-edit"></i> 活动管理 <span class="fa fa-chevron-down"></span></a>
58 <ul class="nav child_menu"> 51 <ul class="nav child_menu">
59 <li><a href="/admin/activity/list">活动列表</a></li> 52 <li><a href="/admin/activity/list">活动列表</a></li>
@@ -96,7 +89,7 @@ @@ -96,7 +89,7 @@
96 <li class=""> 89 <li class="">
97 <a href="javascript:;" class="user-profile dropdown-toggle" data-toggle="dropdown" 90 <a href="javascript:;" class="user-profile dropdown-toggle" data-toggle="dropdown"
98 aria-expanded="false"> 91 aria-expanded="false">
99 - <img src="/img/admin/admin_avatar.png" alt="">John Doe 92 + <img src="{{imgSrc 'img/admin/admin_avatar.png'}}" alt="">John Doe
100 <span class=" fa fa-angle-down"></span> 93 <span class=" fa fa-angle-down"></span>
101 </a> 94 </a>
102 <ul class="dropdown-menu dropdown-usermenu pull-right"> 95 <ul class="dropdown-menu dropdown-usermenu pull-right">
@@ -121,7 +114,7 @@ @@ -121,7 +114,7 @@
121 <ul id="menu1" class="dropdown-menu list-unstyled msg_list" role="menu"> 114 <ul id="menu1" class="dropdown-menu list-unstyled msg_list" role="menu">
122 <li> 115 <li>
123 <a> 116 <a>
124 - <span class="image"><img src="/img/admin/admin_avatar.png" alt="Profile Image"/></span> 117 + <span class="image"><img src="{{imgSrc 'img/admin/admin_avatar.png'}}" alt="Profile Image"/></span>
125 <span> 118 <span>
126 <span>John Smith</span> 119 <span>John Smith</span>
127 <span class="time">3 mins ago</span> 120 <span class="time">3 mins ago</span>
@@ -133,7 +126,7 @@ @@ -133,7 +126,7 @@
133 </li> 126 </li>
134 <li> 127 <li>
135 <a> 128 <a>
136 - <span class="image"><img src="/img/admin/admin_avatar.png" alt="Profile Image"/></span> 129 + <span class="image"><img src="{{imgSrc 'img/admin/admin_avatar.png'}}" alt="Profile Image"/></span>
137 <span> 130 <span>
138 <span>John Smith</span> 131 <span>John Smith</span>
139 <span class="time">3 mins ago</span> 132 <span class="time">3 mins ago</span>
@@ -145,7 +138,7 @@ @@ -145,7 +138,7 @@
145 </li> 138 </li>
146 <li> 139 <li>
147 <a> 140 <a>
148 - <span class="image"><img src="/img/admin/admin_avatar.png" alt="Profile Image"/></span> 141 + <span class="image"><img src="{{imgSrc 'img/admin/admin_avatar.png'}}" alt="Profile Image"/></span>
149 <span> 142 <span>
150 <span>John Smith</span> 143 <span>John Smith</span>
151 <span class="time">3 mins ago</span> 144 <span class="time">3 mins ago</span>
@@ -157,7 +150,7 @@ @@ -157,7 +150,7 @@
157 </li> 150 </li>
158 <li> 151 <li>
159 <a> 152 <a>
160 - <span class="image"><img src="/img/admin/admin_avatar.png" alt="Profile Image"/></span> 153 + <span class="image"><img src="{{imgSrc 'img/admin/admin_avatar.png'}}" alt="Profile Image"/></span>
161 <span> 154 <span>
162 <span>John Smith</span> 155 <span>John Smith</span>
163 <span class="time">3 mins ago</span> 156 <span class="time">3 mins ago</span>
No preview for this file type
@@ -48,7 +48,6 @@ @@ -48,7 +48,6 @@
48 "fast-safe-stringify": "^1.2.0", 48 "fast-safe-stringify": "^1.2.0",
49 "feed": "^1.1.0", 49 "feed": "^1.1.0",
50 "geetest": "^4.1.2", 50 "geetest": "^4.1.2",
51 - "jquery": "^3.2.1",  
52 "lodash": "^4.17.4", 51 "lodash": "^4.17.4",
53 "memory-cache": "^0.1.6", 52 "memory-cache": "^0.1.6",
54 "moment": "^2.18.1", 53 "moment": "^2.18.1",
@@ -63,6 +62,7 @@ @@ -63,6 +62,7 @@
63 "request": "^2.81.0", 62 "request": "^2.81.0",
64 "request-promise": "^4.2.1", 63 "request-promise": "^4.2.1",
65 "semver": "^5.3.0", 64 "semver": "^5.3.0",
  65 + "serve-favicon": "^2.4.3",
66 "sitemap": "^1.12.0", 66 "sitemap": "^1.12.0",
67 "uuid": "^3.0.1", 67 "uuid": "^3.0.1",
68 "yoho-md5": "^2.0.0", 68 "yoho-md5": "^2.0.0",
@@ -82,6 +82,7 @@ @@ -82,6 +82,7 @@
82 "babel-preset-es2015": "^6.24.1", 82 "babel-preset-es2015": "^6.24.1",
83 "babel-register": "^6.22.0", 83 "babel-register": "^6.22.0",
84 "bootstrap": "^3.3.7", 84 "bootstrap": "^3.3.7",
  85 + "bootstrap-daterangepicker": "^2.1.25",
85 "css-loader": "^0.28.4", 86 "css-loader": "^0.28.4",
86 "eslint": "^3.19.0", 87 "eslint": "^3.19.0",
87 "eslint-config-yoho": "^1.0.1", 88 "eslint-config-yoho": "^1.0.1",
@@ -101,6 +102,8 @@ @@ -101,6 +102,8 @@
101 "happypack": "^3.1.0", 102 "happypack": "^3.1.0",
102 "husky": "^0.13.4", 103 "husky": "^0.13.4",
103 "install": "^0.10.1", 104 "install": "^0.10.1",
  105 + "jquery": "^3.2.1",
  106 + "moment": "^2.18.1",
104 "nodemon": "^1.11.0", 107 "nodemon": "^1.11.0",
105 "npm": "^5.0.4", 108 "npm": "^5.0.4",
106 "nprogress": "^0.2.0", 109 "nprogress": "^0.2.0",
@@ -137,7 +140,6 @@ @@ -137,7 +140,6 @@
137 "yoho-fastclick": "^1.0.6", 140 "yoho-fastclick": "^1.0.6",
138 "yoho-hammer": "^2.0.7", 141 "yoho-hammer": "^2.0.7",
139 "yoho-iscroll": "^5.2.0", 142 "yoho-iscroll": "^5.2.0",
140 - "yoho-jquery": "^2.2.4",  
141 "yoho-jquery-lazyload": "^1.9.12", 143 "yoho-jquery-lazyload": "^1.9.12",
142 "yoho-jquery-qrcode": "^0.14.0", 144 "yoho-jquery-qrcode": "^0.14.0",
143 "yoho-lint": "^1.0.1", 145 "yoho-lint": "^1.0.1",
1 require('admin/activity.page.css'); 1 require('admin/activity.page.css');
2 -let $ = require('yoho-jquery');  
3 -  
4 -const createFn = function() {  
5 - const $form = $('#createForm');  
6 - const actName = $form.find('#actName').val();  
7 - const startTime = $form.find('#startTime').val();  
8 - const endTime = $form.find('#endTime').val();  
9 -  
10 - $.ajax({  
11 - method: 'post',  
12 - url: '/admin/api/activity/create',  
13 - data: {  
14 - startTime,  
15 - endTime,  
16 - title: actName  
17 - }  
18 - })  
19 - .then(result => {  
20 - if (result.code !== 200) {  
21 - return;  
22 - } 2 +require('bootstrap-daterangepicker');
23 3
24 - location.href = '/admin/activity/list';  
25 - }); 4 +const moment = require('moment');
  5 +const toUnixTimestamp = function(time) {
  6 + return moment(time).format('X');
26 }; 7 };
27 8
28 -$('.create-btn').on('click', createFn); 9 +function bind_date_picker() {
  10 + if (typeof ($.fn.daterangepicker) === 'undefined') {
  11 + return;
  12 + }
  13 +
  14 + $('#activityTime').daterangepicker({
  15 + timePicker: true,
  16 + timePickerIncrement: 30,
  17 + locale: {
  18 + format: 'YYYY-MM-DD HH:mm:ss'
  19 + }
  20 + });
  21 +}
  22 +
  23 +function bind_create_act() {
  24 + const createFn = function() {
  25 + const $form = $('#createForm');
  26 + const actName = $form.find('#actName').val();
  27 + const actTime = $form.find('#activityTime').val();
  28 + const timeArray = actTime.split(' - ');
  29 + const startTime = toUnixTimestamp(timeArray[0]);
  30 + const endTime = toUnixTimestamp(timeArray[1]);
  31 +
  32 + $.ajax({
  33 + method: 'post',
  34 + url: '/admin/api/activity/create',
  35 + data: {
  36 + startTime,
  37 + endTime,
  38 + title: actName
  39 + }
  40 + })
  41 + .then(result => {
  42 + if (result.code !== 200) {
  43 + return;
  44 + }
  45 +
  46 + location.href = '/admin/activity/list';
  47 + });
  48 + };
  49 +
  50 + $('.create-btn').on('click', createFn);
  51 +}
  52 +
  53 +function bind_delete_act() {
  54 + const deleteFn = function() {
  55 + const id = $(this).data('id');
  56 +
  57 + $.ajax({
  58 + method: 'post',
  59 + url: '/admin/api/activity/delete',
  60 + data: {
  61 + id
  62 + }
  63 + })
  64 + .then(() => {
  65 + location.href = '/admin/activity/list';
  66 + });
  67 + };
  68 +
  69 + $('.btn-delete').on('click', deleteFn);
  70 +}
  71 +
  72 +(function() {
  73 + bind_date_picker();
  74 + bind_create_act();
  75 + bind_delete_act();
  76 +}());
29 77
30 78
1 require('admin/login.page.css'); 1 require('admin/login.page.css');
2 -let $ = require('yoho-jquery');  
3 2
4 const loginFn = function() { 3 const loginFn = function() {
5 const $form = $('#loginForm'); 4 const $form = $('#loginForm');
This diff could not be displayed because it is too large.
1 -@import 'login/login'; 1 +@import '~bootstrap-daterangepicker';