Authored by huangyi

Merge remote-tracking branch 'origin/feature/wheel-surf' into feature/wheel-surf

# Conflicts:
#	utils/validator.js
@@ -20,7 +20,7 @@ const whSurfController = { @@ -20,7 +20,7 @@ const whSurfController = {
20 page: 'wheel-surf' 20 page: 'wheel-surf'
21 }); 21 });
22 }, 22 },
23 - async create(req, res) { 23 + async actCreate(req, res) {
24 const title = req.body.title; 24 const title = req.body.title;
25 const startTime = req.body.startTime; 25 const startTime = req.body.startTime;
26 const endTime = req.body.endTime; 26 const endTime = req.body.endTime;
@@ -40,20 +40,39 @@ const whSurfController = { @@ -40,20 +40,39 @@ const whSurfController = {
40 type 40 type
41 }; 41 };
42 42
43 - const result = await req.ctx(wheelSurfModel).create(params); 43 + try {
  44 + const result = await req.ctx(wheelSurfModel).create(params);
  45 +
  46 + return res.json({ code: 200, data: result});
  47 + } catch (err) {
  48 + res.json(err);
  49 + }
44 50
45 - return res.json({  
46 - code: 200,  
47 - data: result  
48 - });  
49 }, 51 },
50 - async list(req, res) {  
51 - const result = await req.ctx(wheelSurfModel).list(); 52 + async actDelete(req, res) {
  53 + const id = req.body.id;
52 54
53 - return res.json({  
54 - code: 200,  
55 - data: result  
56 - }); 55 + try {
  56 + const result = await req.ctx(wheelSurfModel).actDelete(id);
  57 +
  58 + return res.json({ code: 200, data: result});
  59 +
  60 + } catch (err) {
  61 + res.json(err);
  62 + }
  63 +
  64 + },
  65 + async actList(req, res) {
  66 + try {
  67 + const result = await req.ctx(wheelSurfModel).list();
  68 +
  69 + return res.json({
  70 + code: 200,
  71 + data: result
  72 + });
  73 + } catch (err) {
  74 + res.json(err);
  75 + }
57 }, 76 },
58 77
59 getConfigList: async function(req, res) { 78 getConfigList: async function(req, res) {
@@ -7,12 +7,16 @@ class ActWheelSurfModel extends global.yoho.BaseModel { @@ -7,12 +7,16 @@ class ActWheelSurfModel extends global.yoho.BaseModel {
7 } 7 }
8 8
9 list() { 9 list() {
10 - return Activity.findAll({where: {type: 1}}); 10 + return Activity.findAll({where: {type: 1}})
11 } 11 }
12 -  
13 create(data) { 12 create(data) {
14 return Activity.create(data); 13 return Activity.create(data);
15 } 14 }
  15 + actDelete(id) {
  16 + return Activity.findOne({where: {id}}).then(activity => {
  17 + return activity.destroy();
  18 + });
  19 + }
16 20
17 21
18 configModify(obj) { 22 configModify(obj) {
@@ -94,8 +94,9 @@ router.get('/api/user/exportInfoUserList', user.exportInfoUserList); @@ -94,8 +94,9 @@ router.get('/api/user/exportInfoUserList', user.exportInfoUserList);
94 // 大转盘活动管理 94 // 大转盘活动管理
95 router.get('/wheelSurf', wheelSurf.entry); 95 router.get('/wheelSurf', wheelSurf.entry);
96 96
97 -router.post('/wheelSurf/api/create', wheelSurf.create);  
98 -router.get('/wheelSurf/api/list', wheelSurf.list); 97 +router.post('/wheelSurf/api/create', wheelSurf.actCreate);
  98 +router.post('/wheelSurf/api/delete', wheelSurf.actDelete);
  99 +router.get('/wheelSurf/api/list', wheelSurf.actList);
99 100
100 router.get('/wheelSurf/api/config/list', wheelSurf.getConfigList); 101 router.get('/wheelSurf/api/config/list', wheelSurf.getConfigList);
101 router.post('/wheelSurf/api/config/modify', wheelSurf.configModify); 102 router.post('/wheelSurf/api/config/modify', wheelSurf.configModify);
@@ -40,8 +40,6 @@ @@ -40,8 +40,6 @@
40 <a class="btn btn-info" href="/admin/activity/article?actId={{id}}">文章列表</a> 40 <a class="btn btn-info" href="/admin/activity/article?actId={{id}}">文章列表</a>
41 <a class="btn btn-primary" href="/admin/activity/createArticle?actId={{id}}"> 41 <a class="btn btn-primary" href="/admin/activity/createArticle?actId={{id}}">
42 创建文章</a> 42 创建文章</a>
43 - <a class="btn btn-primary" href="/admin/wheelSurf/decor?actId={{id}}">  
44 - 大转盘活动配置</a>  
45 <button class="btn btn-danger btn-delete" data-id="{{id}}">删除活动 43 <button class="btn btn-danger btn-delete" data-id="{{id}}">删除活动
46 </button> 44 </button>
47 </td> 45 </td>
1 <!-- page content --> 1 <!-- page content -->
2 -<div class="right_col" role="main">  
3 - <div id="app">  
4 - <App></App>  
5 - </div> 2 +<div class="vue-app-container">
  3 + <App></App>
6 </div> 4 </div>
7 <!-- /page content --> 5 <!-- /page content -->
@@ -2,7 +2,7 @@ import Vue from 'vue'; @@ -2,7 +2,7 @@ import Vue from 'vue';
2 import VueRouter from 'vue-router'; 2 import VueRouter from 'vue-router';
3 import iView from 'iview'; 3 import iView from 'iview';
4 import App from 'vue@/App.vue'; 4 import App from 'vue@/App.vue';
5 -import {create, list, decor} from 'vue@/wheel-surf'; 5 +import {create, list, conf} from 'vue@/wheel-surf';
6 6
7 import 'admin/wheel-surf.page.css'; 7 import 'admin/wheel-surf.page.css';
8 import 'iview/dist/styles/iview.css'; 8 import 'iview/dist/styles/iview.css';
@@ -13,14 +13,14 @@ Vue.use(iView); @@ -13,14 +13,14 @@ Vue.use(iView);
13 const router = new VueRouter({ 13 const router = new VueRouter({
14 routes: [ 14 routes: [
15 {path: '/admin/wheelSurf', name: 'list', component: list}, 15 {path: '/admin/wheelSurf', name: 'list', component: list},
16 - {path: '/admin/wheelSurf/decor', name: 'decor', component: decor}, 16 + {path: '/admin/wheelSurf/conf', name: 'conf', component: conf},
17 {path: '/admin/wheelSurf/create', name: 'create', component: create} 17 {path: '/admin/wheelSurf/create', name: 'create', component: create}
18 ], 18 ],
19 mode: 'history' 19 mode: 'history'
20 }); 20 });
21 21
22 new Vue({ 22 new Vue({
23 - el: '#app', 23 + el: '.vue-app-container',
24 components: { 24 components: {
25 App 25 App
26 }, 26 },
@@ -220,6 +220,23 @@ body .container.body .right_col { @@ -220,6 +220,23 @@ body .container.body .right_col {
220 border-radius: 0; 220 border-radius: 0;
221 height: 57px; 221 height: 57px;
222 } 222 }
  223 +
  224 +.nav-md .vue-app-container {
  225 + position: absolute;
  226 + left: 230px;
  227 + top: 68px;
  228 + right: 0;
  229 + bottom: 0;
  230 +}
  231 +
  232 +.nav-sm .vue-app-container {
  233 + position: absolute;
  234 + left: 70px;
  235 + top: 68px;
  236 + right: 0;
  237 + bottom: 0;
  238 +
  239 +}
223 @media (max-width: 991px) { 240 @media (max-width: 991px) {
224 .nav-md .container.body .right_col, .nav-md .container.body .top_nav { 241 .nav-md .container.body .right_col, .nav-md .container.body .top_nav {
225 width: 100%; 242 width: 100%;
@@ -235,6 +252,14 @@ body .container.body .right_col { @@ -235,6 +252,14 @@ body .container.body .right_col {
235 .right_col { 252 .right_col {
236 padding: 10px !important; 253 padding: 10px !important;
237 } 254 }
  255 +
  256 + .nav-md .vue-app-container {
  257 + position: absolute;
  258 + left: 0;
  259 + top: 68px;
  260 + right: 0;
  261 + bottom: 0;
  262 + }
238 } 263 }
239 @media (max-width: 1200px) { 264 @media (max-width: 1200px) {
240 .x_title h2 { 265 .x_title h2 {
1 <template> 1 <template>
2 - <router-view></router-view> 2 + <div class="vue-app-inner-view">
  3 + <router-view></router-view>
  4 + </div>
3 </template> 5 </template>
4 6
5 <script> 7 <script>
@@ -9,5 +11,25 @@ @@ -9,5 +11,25 @@
9 </script> 11 </script>
10 12
11 <style> 13 <style>
  14 + .vue-app-container {
  15 + overflow: auto;
  16 + }
12 17
  18 + .nav_menu {
  19 + margin-bottom: 0;
  20 + }
  21 +
  22 + .container, .main_container {
  23 + height: 100%;
  24 + }
  25 +
  26 + footer {
  27 + display: none;
  28 + bottom: 10px;
  29 + right: 10px;
  30 + }
  31 +
  32 + .vue-app-inner-view {
  33 + padding: 0 10px 60px 10px;
  34 + }
13 </style> 35 </style>
  1 +<template>
  2 + <Tabs size="small">
  3 + <TabPane label="基础配置">
  4 + <Form ref="formValidate" :model="formValidate" :rules="ruleValidate" :label-width="120">
  5 + <FormItem label="活动规则" required>
  6 + <Input type="textarea" :autosize="{minRows: 2,maxRows: 30}"
  7 + placeholder="请输入活动规则" :maxlength="2000"></Input>
  8 + </FormItem>
  9 + <FormItem label="分享链接" required>
  10 + <Input type="text"
  11 + placeholder="活动分享链接"></Input>
  12 + </FormItem>
  13 + <FormItem label="提示文案(上)" required>
  14 + <Input type="text"
  15 + placeholder="提示文案(上)"></Input>
  16 + </FormItem>
  17 + <FormItem label="提示文案(下)" required>
  18 + <Input type="text"
  19 + placeholder="提示文案(下)"></Input>
  20 + </FormItem>
  21 + <FormItem label="跳转链接(左)" required>
  22 + <Input type="text"
  23 + placeholder="活动底部链接(左)"></Input>
  24 + </FormItem>
  25 + <FormItem label="跳转链接(右)" required>
  26 + <Input type="text"
  27 + placeholder="活动底部链接(右)"></Input>
  28 + </FormItem>
  29 + <FormItem label="活动最大参与次数" required>
  30 + <Input type="text"
  31 + placeholder="活动最大参与次数"></Input>
  32 + </FormItem>
  33 + <FormItem label="每天最大抽奖次数" required>
  34 + <Input type="text"
  35 + placeholder="每天最大抽奖次数"></Input>
  36 + </FormItem>
  37 + <FormItem>
  38 + <Button type="primary" @click="handleSubmit('formValidate')">保存</Button>
  39 + <Button type="warning" @click="handleSubmit('formValidate')">预览</Button>
  40 + </FormItem>
  41 + </Form>
  42 + </TabPane>
  43 + <TabPane label="奖品配置">标签二的内容</TabPane>
  44 + </Tabs>
  45 +</template>
  46 +<script>
  47 + export default {
  48 + data () {
  49 + return {
  50 + formValidate: {
  51 + name: '',
  52 + mail: '',
  53 + city: '',
  54 + gender: '',
  55 + interest: [],
  56 + date: '',
  57 + time: '',
  58 + desc: ''
  59 + },
  60 + ruleValidate: {
  61 + name: [
  62 + { required: true, message: 'The name cannot be empty', trigger: 'blur' }
  63 + ],
  64 + mail: [
  65 + { required: true, message: 'Mailbox cannot be empty', trigger: 'blur' },
  66 + { type: 'email', message: 'Incorrect email format', trigger: 'blur' }
  67 + ],
  68 + city: [
  69 + { required: true, message: 'Please select the city', trigger: 'change' }
  70 + ],
  71 + gender: [
  72 + { required: true, message: 'Please select gender', trigger: 'change' }
  73 + ],
  74 + interest: [
  75 + { required: true, type: 'array', min: 1, message: 'Choose at least one hobby', trigger: 'change' },
  76 + { type: 'array', max: 2, message: 'Choose two hobbies at best', trigger: 'change' }
  77 + ],
  78 + date: [
  79 + { required: true, type: 'date', message: 'Please select the date', trigger: 'change' }
  80 + ],
  81 + time: [
  82 + { required: true, type: 'string', message: 'Please select time', trigger: 'change' }
  83 + ],
  84 + desc: [
  85 + { required: true, message: 'Please enter a personal introduction', trigger: 'blur' },
  86 + { type: 'string', min: 20, message: 'Introduce no less than 20 words', trigger: 'blur' }
  87 + ]
  88 + }
  89 + }
  90 + },
  91 + methods: {
  92 + handleSubmit (name) {
  93 + this.$refs[name].validate((valid) => {
  94 + if (valid) {
  95 + this.$Message.success('Success!');
  96 + } else {
  97 + this.$Message.error('Fail!');
  98 + }
  99 + })
  100 + },
  101 + handleReset (name) {
  102 + this.$refs[name].resetFields();
  103 + }
  104 + }
  105 + }
  106 +</script>
  107 +<style lang="scss">
  108 + .ivu-form-item {
  109 + margin-bottom: 10px;
  110 + }
  111 +
  112 +</style>
  113 +
  114 +
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 <div class="col-md-12 col-sm-12 col-xs-12"> 4 <div class="col-md-12 col-sm-12 col-xs-12">
5 <div class="x_panel"> 5 <div class="x_panel">
6 <div class="x_title"> 6 <div class="x_title">
7 - <h2>大转盘活动创建</h2> 7 + <h2>活动创建</h2>
8 <div class="clearfix"></div> 8 <div class="clearfix"></div>
9 </div> 9 </div>
10 <div class="x_content"> 10 <div class="x_content">
1 -<template>  
2 - <div class="decor">  
3 - 活动配置  
4 - <div>  
5 - <button class="btn btn-info">预览</button>  
6 - <button class="btn btn-primary">保存</button>  
7 - </div>  
8 - </div>  
9 -</template>  
10 -<script>  
11 - module.exports = {  
12 - data() {  
13 - return {  
14 - actId: 0  
15 - };  
16 - },  
17 - created() {  
18 - this.actId = this.$route.query.actId;  
19 - },  
20 - methods: {  
21 - create() {  
22 - this.$router.push({name: 'create'});  
23 - }  
24 - }  
25 - }  
26 -</script>  
27 -<style>  
28 -  
29 -</style>  
1 import list from './list'; 1 import list from './list';
2 -import decor from './decor'; 2 +import conf from './conf';
3 import create from './create'; 3 import create from './create';
4 4
5 export { 5 export {
6 list, 6 list,
7 - decor, 7 + conf,
8 create 8 create
9 } 9 }
1 <template> 1 <template>
2 <div class="list"> 2 <div class="list">
3 - <button class="btn btn-primary" @click="toCreate">创建新活动</button> 3 + <Button type="primary" class="create-btn" @click="toCreate">创建新活动</Button>
4 <div class="activity-list"> 4 <div class="activity-list">
5 <Table :columns="columns1" :data="data"></Table> 5 <Table :columns="columns1" :data="data"></Table>
6 </div> 6 </div>
@@ -22,6 +22,38 @@ @@ -22,6 +22,38 @@
22 { 22 {
23 title: '结束时间', 23 title: '结束时间',
24 key: 'endTime' 24 key: 'endTime'
  25 + },
  26 + {
  27 + title: '操作',
  28 + render: (h, {row}) => {
  29 + return h('div', [
  30 + h('Button', {
  31 + props: {
  32 + type: 'primary',
  33 + size: 'small'
  34 + },
  35 + style: {
  36 + marginRight: '5px'
  37 + },
  38 + on: {
  39 + click: () => {
  40 + this.conf(row.id)
  41 + }
  42 + }
  43 + }, '配置'),
  44 + h('Button', {
  45 + props: {
  46 + type: 'error',
  47 + size: 'small'
  48 + },
  49 + on: {
  50 + click: () => {
  51 + this.delete(row.id)
  52 + }
  53 + }
  54 + }, '删除'),
  55 + ])
  56 + }
25 } 57 }
26 ], 58 ],
27 data: [] 59 data: []
@@ -30,20 +62,43 @@ @@ -30,20 +62,43 @@
30 methods: { 62 methods: {
31 toCreate() { 63 toCreate() {
32 this.$router.push({name: 'create'}); 64 this.$router.push({name: 'create'});
  65 + },
  66 + conf(actId) {
  67 + this.$router.push({name: 'conf', query: {actId}});
  68 + },
  69 + delete(id) {
  70 + this.$Modal.warning({
  71 + content: '删除后不可恢复,确认删除?',
  72 + onOk: () => {
  73 + $.ajax({
  74 + method: 'post',
  75 + url: '/admin/wheelSurf/api/delete',
  76 + data: {id}
  77 + }).then(() => {
  78 + this.list();
  79 + });
  80 + }
  81 + });
  82 + },
  83 + list() {
  84 + $.ajax({
  85 + url: '/admin/wheelSurf/api/list',
  86 + }).then(res => {
  87 + this.data = res.data;
  88 + });
33 } 89 }
34 }, 90 },
35 created() { 91 created() {
36 - $.ajax({  
37 - url: '/admin/wheelSurf/api/list',  
38 - }).then(res => {  
39 - this.data = res.data;  
40 - }); 92 + this.list();
41 } 93 }
42 } 94 }
43 </script> 95 </script>
44 <style lang="scss"> 96 <style lang="scss">
45 .activity-list { 97 .activity-list {
46 - height: 600px; 98 + }
  99 +
  100 + .create-btn {
  101 + margin-bottom: 10px;
47 } 102 }
48 103
49 </style> 104 </style>