张延森 před 4 roky
rodič
revize
96287fa247

+ 23
- 0
src/api/activity.js Zobrazit soubor

@@ -31,3 +31,26 @@ export function saveActivity(data) {
31 31
     data
32 32
   }))
33 33
 }
34
+
35
+export function getEnrollList(params) {
36
+  return pureResponseData(request({
37
+    url: `/api/admin/activityEnroll`,
38
+    method: 'get',
39
+    params
40
+  }))
41
+}
42
+
43
+export function getVoteItems(activityId) {
44
+  return pureResponseData(request({
45
+    url: `/api/admin/activity/${activityId}/voteitem`,
46
+    method: 'get'
47
+  }))
48
+}
49
+
50
+export function saveVoteItems(activityId, data) {
51
+  return pureResponseData(request({
52
+    url: `/api/admin/activity/${activityId}/voteitem`,
53
+    method: 'post',
54
+    data
55
+  }))
56
+}

+ 62
- 0
src/components/FloatAction/index.vue Zobrazit soubor

@@ -0,0 +1,62 @@
1
+<template>
2
+  <div class="floatting-action" :style="style">
3
+    <slot></slot>
4
+  </div>
5
+</template>
6
+
7
+<script>
8
+export default {
9
+  props: {
10
+    left: {
11
+      type: Number,
12
+      default: undefined
13
+    },
14
+    right: {
15
+      type: Number,
16
+      default: undefined
17
+    },
18
+    top: {
19
+      type: Number,
20
+      default: undefined
21
+    },
22
+    bottom: {
23
+      type: Number,
24
+      default: undefined
25
+    }
26
+  },
27
+
28
+  computed: {
29
+    style() {
30
+      const ds = []
31
+
32
+      if (this.left !== undefined && this.left !== null) {
33
+        ds.push(`left: ${this.left}px`)
34
+      }
35
+      if (this.right !== undefined && this.right !== null) {
36
+        ds.push(`right: ${this.right}px`)
37
+      }
38
+      if (this.top !== undefined && this.top !== null) {
39
+        ds.push(`top: ${this.top}px`)
40
+      }
41
+      if (this.bottom !== undefined && this.bottom !== null) {
42
+        ds.push(`bottom: ${this.bottom}px`)
43
+      }
44
+
45
+      return ds.join(';')
46
+    }
47
+  }
48
+}
49
+</script>
50
+
51
+<style lang="scss" scoped>
52
+.floatting-action {
53
+  position: fixed;
54
+  display: flex;
55
+  align-items: center;
56
+  justify-content: center;
57
+  cursor: pointer;
58
+  z-index: 5;
59
+  right: 100px;
60
+  bottom: 150px;
61
+}
62
+</style>

+ 37
- 0
src/components/PAInput/index.vue Zobrazit soubor

@@ -0,0 +1,37 @@
1
+<template>
2
+  <el-input placeholder="请输入内容" v-model="val">
3
+    <template slot="prepend">{{prefix}}</template>
4
+    <el-button slot="append" :icon="icon" @click="handleBtnClick"></el-button>
5
+  </el-input>
6
+</template>
7
+
8
+<script>
9
+export default {
10
+  props: {
11
+    value: String,
12
+    prefix: String,
13
+    icon: String
14
+  },
15
+
16
+  data() {
17
+    return {}
18
+  },
19
+
20
+  computed: {
21
+    val: {
22
+      get() {
23
+        return this.value
24
+      },
25
+      set(v) {
26
+        this.$emit('input', v)
27
+      }
28
+    }
29
+  },
30
+
31
+  methods: {
32
+    handleBtnClick() {
33
+      this.$emit('click')
34
+    }
35
+  }
36
+}
37
+</script>

+ 44
- 9
src/router/index.js Zobrazit soubor

@@ -65,34 +65,55 @@ export const constantRoutes = [
65 65
       {
66 66
         path: 'warm',
67 67
         name: 'warm',
68
-        component: () => import('@/views/life/Warm'),
68
+        component: () => import('@/views/life/warm'),
69 69
         meta: { title: '暖场活动', icon: 'el-icon-position' }
70 70
       },
71 71
       {
72 72
         path: 'warm/detail',
73 73
         name: 'warm.detail',
74
-        hidden: true,
75
-        component: () => import('@/views/life/Warm/Detail'),
76
-        meta: { title: '活动详情' }
74
+        component: () => import('@/views/life/warm/Detail'),
75
+        meta: { title: '暖场活动详情' },
76
+        hidden: true
77 77
       },
78 78
       {
79 79
         path: 'travel',
80 80
         name: 'travel',
81
-        component: () => import('@/views/tree/index'),
81
+        component: () => import('@/views/life/travel'),
82 82
         meta: { title: '美好出游季', icon: 'el-icon-bicycle' }
83 83
       },
84
+      {
85
+        path: 'travel/detail',
86
+        name: 'travel.detail',
87
+        component: () => import('@/views/life/travel/Detail'),
88
+        meta: { title: '美好出游季详情' },
89
+        hidden: true
90
+      },
84 91
       {
85 92
         path: 'school',
86 93
         name: 'school',
87
-        component: () => import('@/views/tree/index'),
94
+        component: () => import('@/views/life/school'),
88 95
         meta: { title: '六点半学堂', icon: 'el-icon-school' }
89 96
       },
97
+      {
98
+        path: 'school/detail',
99
+        name: 'school.detail',
100
+        component: () => import('@/views/life/school/Detail'),
101
+        meta: { title: '六点半学堂详情' },
102
+        hidden: true
103
+      },
90 104
       {
91 105
         path: 'sport',
92 106
         name: 'sport',
93
-        component: () => import('@/views/tree/index'),
107
+        component: () => import('@/views/life/sport'),
94 108
         meta: { title: '夜跑行动', icon: 'el-icon-moon' }
95 109
       },
110
+      {
111
+        path: 'sport/detail',
112
+        name: 'sport.detail',
113
+        component: () => import('@/views/life/sport/Detail'),
114
+        meta: { title: '夜跑行动详情' },
115
+        hidden: true
116
+      },
96 117
       {
97 118
         path: 'warm-history',
98 119
         name: 'warm-history',
@@ -134,14 +155,28 @@ export const constantRoutes = [
134 155
       {
135 156
         path: 'clothes',
136 157
         name: 'clothes',
137
-        component: () => import('@/views/table/index'),
158
+        component: () => import('@/views/love/clothes'),
138 159
         meta: { title: '旧衣飞行', icon: 'el-icon-aim' }
139 160
       },
161
+      {
162
+        path: 'clothes/detail',
163
+        name: 'clothes.detail',
164
+        component: () => import('@/views/love/clothes/Detail'),
165
+        meta: { title: '旧衣飞行详情' },
166
+        hidden: true
167
+      },
140 168
       {
141 169
         path: 'help',
142 170
         name: 'help',
143
-        component: () => import('@/views/tree/index'),
171
+        component: () => import('@/views/love/help'),
144 172
         meta: { title: '丽园助农', icon: 'el-icon-bangzhu' }
173
+      },
174
+      {
175
+        path: 'help/detail',
176
+        name: 'help.detail',
177
+        component: () => import('@/views/love/help/Detail'),
178
+        meta: { title: '丽园助农详情' },
179
+        hidden: true
145 180
       }
146 181
     ]
147 182
   },

+ 71
- 0
src/views/activity/Detail.vue Zobrazit soubor

@@ -0,0 +1,71 @@
1
+<template>
2
+  <div class="app-container">
3
+    <el-tabs v-model="currentTab" type="card">
4
+      <el-tab-pane label="活动详情" name="detail">
5
+        <div style="max-width: 60vw">
6
+          <activity :type-id="typeId" :dataset="detail" @submit="handleSubmit" @cancel="handleCancel" />
7
+        </div>
8
+      </el-tab-pane>
9
+      <el-tab-pane v-if="detail && detail.isEnroll" label="报名详情" name="enroll">
10
+        <enroll-list :activity-id="detail.activityId" />
11
+      </el-tab-pane>
12
+      <el-tab-pane label="投票设置" name="vote">
13
+        <voteedit :activity-id="detail.activityId" />
14
+      </el-tab-pane>
15
+    </el-tabs>
16
+  </div>
17
+</template>
18
+
19
+<script>
20
+import { getActivity, updateActivity, saveActivity } from '@/api/activity'
21
+
22
+export default {
23
+  components: {
24
+    activity: () => import('./components/Detail'),
25
+    enrollList: () => import('./components/EnrollList'),
26
+    voteedit: () => import('./components/VoteEdit')
27
+  },
28
+
29
+  props: {
30
+    typeId: {
31
+      type: Number,
32
+      default: 0
33
+    }
34
+  },
35
+
36
+  data() {
37
+    return {
38
+      id: null,
39
+      detail: null,
40
+      currentTab: 'detail'
41
+    }
42
+  },
43
+
44
+  created() {
45
+    const { id } = this.$route.query
46
+    if (id) {
47
+      this.id = id
48
+      // eslint-disable-next-line no-return-assign
49
+      getActivity(id).then(res => this.detail = res)
50
+    }
51
+  },
52
+
53
+  methods: {
54
+    handleSubmit(data) {
55
+      if (this.id) {
56
+        updateActivity(data).then(() => {
57
+          this.$message({ type: 'success', message: '更新成功' })
58
+        })
59
+      } else {
60
+        saveActivity(data).then(res => {
61
+          this.$router.replace({ name: this.$route.name, params: { typeId: this.typeId }, query: { id: res.activityId }})
62
+        })
63
+      }
64
+    },
65
+
66
+    handleCancel() {
67
+      this.$router.go(-1)
68
+    }
69
+  }
70
+}
71
+</script>

+ 185
- 0
src/views/activity/List.vue Zobrazit soubor

@@ -0,0 +1,185 @@
1
+<template>
2
+  <div class="app-container">
3
+    <div class="activity-header">
4
+      <FilterForm @search="handleSearch" @reset="handleSearch" />
5
+      <el-tooltip content="新增活动" placement="top">
6
+        <el-button type="primary" icon="el-icon-plus" @click="handleAdd" />
7
+      </el-tooltip>
8
+    </div>
9
+    <el-table
10
+      v-loading="listLoading"
11
+      :data="list"
12
+      element-loading-text="Loading"
13
+      border
14
+      fit
15
+      highlight-current-row
16
+      stripe
17
+    >
18
+      <el-table-column align="center" label="ID" width="100" prop="activityId" />
19
+      <el-table-column label="活动时间">
20
+        <template slot-scope="scope">
21
+          {{ scope.row.startDate | toDayMini }} - {{ scope.row.endDate | toDayMini }}
22
+        </template>
23
+      </el-table-column>
24
+      <el-table-column label="活动名称" prop="name" />
25
+      <el-table-column label="活动状态" align="center" width="200">
26
+        <template slot-scope="scope">
27
+          <el-tag
28
+            :type="scope.row.status | statusTagFormat"
29
+            disable-transitions
30
+          >{{ scope.row.status | statusFormat }}</el-tag>
31
+        </template>
32
+      </el-table-column>
33
+      <el-table-column label="操作" align="center" width="200">
34
+        <template slot-scope="scope">
35
+          <el-button size="mini" type="primary" plain @click="handleEdit(scope.row)">编辑</el-button>
36
+        </template>
37
+      </el-table-column>
38
+    </el-table>
39
+    <div class="pagination">
40
+      <el-pagination
41
+        :current-page="pagination.current"
42
+        :page-size="pagination.size"
43
+        :total="pagination.total"
44
+        :page-sizes="[10, 20, 50, 100]"
45
+        layout="total, sizes, prev, pager, next"
46
+        @size-change="handleSizeChange"
47
+        @current-change="handleCurrentChange"
48
+      />
49
+    </div>
50
+  </div>
51
+</template>
52
+
53
+<script>
54
+import { getActivityList } from '@/api/activity'
55
+
56
+export default {
57
+  components: {
58
+    FilterForm: () => import('./components/FilterForm')
59
+  },
60
+
61
+  filters: {
62
+    statusFormat(status) {
63
+      if (status === null || status === undefined) {
64
+        return undefined
65
+      }
66
+
67
+      const statusMap = [
68
+        '未发布',
69
+        '已发布',
70
+        '已过期'
71
+      ]
72
+      return statusMap[status]
73
+    },
74
+
75
+    statusTagFormat(status) {
76
+      if (status === null || status === undefined) {
77
+        return undefined
78
+      }
79
+
80
+      const statusMap = [
81
+        'warning',
82
+        'success',
83
+        'info'
84
+      ]
85
+      return statusMap[status]
86
+    }
87
+  },
88
+
89
+  props: {
90
+    typeId: {
91
+      type: Number,
92
+      default: 0
93
+    }
94
+  },
95
+
96
+  data() {
97
+    return {
98
+      list: null,
99
+      listLoading: true,
100
+      detailRouter: null,
101
+      pagination: {
102
+        total: 0,
103
+        size: 10,
104
+        current: 1
105
+      },
106
+      filters: {
107
+        pageNum: 1,
108
+        pageSize: 10
109
+      }
110
+    }
111
+  },
112
+  created() {
113
+    this.fetchData()
114
+    this.detailRouter = `${this.$route.name}.detail`
115
+  },
116
+  methods: {
117
+    fetchData() {
118
+      this.listLoading = true
119
+      getActivityList({
120
+        ...this.filters,
121
+        typeId: this.typeId,
122
+        pageNum: this.pagination.current,
123
+        pageSize: this.pagination.size
124
+      }).then(res => {
125
+        this.list = res.records
126
+        this.pagination = {
127
+          total: res.total,
128
+          size: res.size,
129
+          current: res.current
130
+        }
131
+        this.listLoading = false
132
+      })
133
+    },
134
+
135
+    handleAdd() {
136
+      this.$router.push({
137
+        name: this.detailRouter,
138
+        params: { typeId: this.typeId }
139
+      })
140
+    },
141
+
142
+    handleEdit(row) {
143
+      this.$router.push({
144
+        name: this.detailRouter,
145
+        params: { typeId: this.typeId },
146
+        query: { id: row.activityId }
147
+      })
148
+    },
149
+
150
+    handleSizeChange(size) {
151
+      this.pagination.size = size
152
+    },
153
+
154
+    handleCurrentChange(current) {
155
+      this.pagination.current = current
156
+      this.fetchData()
157
+    },
158
+
159
+    handleSearch(searchParams) {
160
+      this.filters = {
161
+        ...this.filters,
162
+        ...searchParams,
163
+        pageNum: 1
164
+      }
165
+
166
+      this.fetchData()
167
+    }
168
+  }
169
+}
170
+</script>
171
+
172
+<style lang="scss" scoped>
173
+.activity-header {
174
+  display: flex;
175
+  justify-content: space-between;
176
+  align-items: center;
177
+}
178
+
179
+.pagination {
180
+  padding: 16px;
181
+  & > div {
182
+    float: right;
183
+  }
184
+}
185
+</style>

src/views/components/Activity/index.vue → src/views/activity/components/Detail.vue Zobrazit soubor

@@ -3,7 +3,7 @@
3 3
     <el-form-item label="活动名称" prop="name">
4 4
       <el-input v-model="form.name" />
5 5
     </el-form-item>
6
-    <el-form-item label="活动时间" required="">
6
+    <el-form-item label="活动时间" required>
7 7
       <el-date-picker
8 8
         v-model="dtRange1"
9 9
         type="daterange"
@@ -26,8 +26,11 @@
26 26
     <el-form-item label="活动地点" prop="address">
27 27
       <el-input v-model="form.address" />
28 28
     </el-form-item>
29
-    <template v-if="enroll">
30
-      <el-form-item label="报名时间">
29
+    <template v-if="!isWarm">
30
+      <el-form-item label="允许报名" prop="isEnroll">
31
+        <el-switch v-model="form.isEnroll" />
32
+      </el-form-item>
33
+      <el-form-item label="报名时间" v-if="form.isEnroll">
31 34
         <el-date-picker
32 35
           v-model="dtRange2"
33 36
           type="daterange"
@@ -35,24 +38,28 @@
35 38
           end-placeholder="结束日期"
36 39
           style="width: 100%;" />
37 40
       </el-form-item>
41
+      <el-form-item label="当前报名" v-if="form.isEnroll">
42
+        <el-input v-model="form.enrollNum">
43
+          <template slot="append">人</template>
44
+        </el-input>
45
+      </el-form-item>
38 46
     </template>
39
-    <template v-if="type == 2">
40
-      <el-form-item label="是否投票" prop="is_vote">
41
-        <el-switch v-model="form.is_vote" />
47
+    <el-form-item label="活动详情" prop="detail">
48
+      <markdown v-model="form.detail" />
49
+    </el-form-item>
50
+    <template v-if="isWarm">
51
+      <el-form-item label="参与投票" prop="isVote">
52
+        <el-switch v-model="form.isVote" />
42 53
       </el-form-item>
43
-      <el-form-item label="投票时间">
54
+      <el-form-item label="投票时间" v-if="form.isVote">
44 55
         <el-date-picker
45 56
           v-model="dtRange3"
46
-          :disabled="!form.is_vote"
47 57
           type="daterange"
48 58
           start-placeholder="开始日期"
49 59
           end-placeholder="结束日期"
50 60
           style="width: 100%;" />
51 61
       </el-form-item>
52 62
     </template>
53
-    <el-form-item label="活动详情" prop="detail">
54
-      <markdown v-model="form.detail" />
55
-    </el-form-item>
56 63
     <el-form-item label="活动状态" prop="status">
57 64
       <el-select v-model="form.status" placeholder="请选择">
58 65
         <el-option label="未发布" :value="0" />
@@ -94,16 +101,14 @@ export default {
94 101
   },
95 102
 
96 103
   props: {
97
-    type: {
98
-      type: String,
99
-      required: true
104
+    typeId: {
105
+      type: Number,
106
+      default: 0
100 107
     },
101 108
     dataset: {
102 109
       type: Object,
103 110
       default: undefined
104
-    },
105
-    enroll: Boolean,
106
-    vote: Boolean
111
+    }
107 112
   },
108 113
 
109 114
   data() {
@@ -134,6 +139,7 @@ export default {
134 139
         isWarm: false,
135 140
         isVote: false,
136 141
         voteNum: null,
142
+        isEnroll: false,
137 143
         enrollNum: null,
138 144
         shareImg: null,
139 145
         shareTitle: null,
@@ -151,6 +157,10 @@ export default {
151 157
   },
152 158
 
153 159
   computed: {
160
+    isWarm() {
161
+      return this.type === 1
162
+    },
163
+
154 164
     dtRange1: {
155 165
       get() {
156 166
         return [this.form.startDate, this.form.endDate]
@@ -196,7 +206,7 @@ export default {
196 206
     },
197 207
 
198 208
     dataset(val) {
199
-      if (val && !this.formDataInited) {
209
+      if (val && val.activityId && !this.formDataInited) {
200 210
         this.form = val
201 211
         this.formDataInited = true
202 212
       }
@@ -204,7 +214,7 @@ export default {
204 214
   },
205 215
 
206 216
   mounted() {
207
-    if (this.dataset) {
217
+    if (this.dataset && this.dataset.activityId) {
208 218
       this.form = this.dataset
209 219
       this.formDataInited = true
210 220
     }
@@ -216,12 +226,8 @@ export default {
216 226
         if (valid) {
217 227
           const data = {
218 228
             ...this.form,
219
-            typeId: this.type
220
-          }
221
-
222
-          // eslint-disable-next-line
223
-          if (this.type == 2) {
224
-            data.isWarm = true
229
+            typeId: this.typeId,
230
+            isWarm: this.isWarm
225 231
           }
226 232
 
227 233
           const [dt1, dt2] = transferBeginEndDay(data.startDate, data.endDate)

+ 106
- 0
src/views/activity/components/EnrollList.vue Zobrazit soubor

@@ -0,0 +1,106 @@
1
+<template>
2
+  <div>
3
+    <el-table
4
+      v-loading="listLoading"
5
+      :data="list"
6
+      element-loading-text="Loading"
7
+      border
8
+      fit
9
+      highlight-current-row
10
+      stripe
11
+    >
12
+      <el-table-column
13
+        type="index"
14
+        width="50">
15
+      </el-table-column>
16
+      <el-table-column label="报名时间">
17
+        <template slot-scope="scope">
18
+          {{ scope.row.createDate | toDayMini }}
19
+        </template>
20
+      </el-table-column>
21
+      <el-table-column label="头像">
22
+        <template slot-scope="scope">
23
+          <img :src="scope.row.personAvatar" width="64" alt="">
24
+        </template>
25
+      </el-table-column>
26
+      <el-table-column label="报名人" prop="personName" />
27
+      <el-table-column label="昵称" prop="personNickname" />
28
+      <el-table-column label="电话" prop="phone" />
29
+    </el-table>
30
+    <div class="pagination">
31
+      <el-pagination
32
+        :current-page="pagination.current"
33
+        :page-size="pagination.size"
34
+        :total="pagination.total"
35
+        :page-sizes="[10, 20, 50, 100]"
36
+        layout="total, sizes, prev, pager, next"
37
+        @size-change="handleSizeChange"
38
+        @current-change="handleCurrentChange"
39
+      />
40
+    </div>
41
+  </div>
42
+</template>
43
+
44
+<script>
45
+import { getEnrollList } from '@/api/activity'
46
+
47
+export default {
48
+  props: {
49
+    activityId: Number
50
+  },
51
+  data() {
52
+    return {
53
+      list: null,
54
+      listLoading: true,
55
+      pagination: {
56
+        total: 0,
57
+        size: 10,
58
+        current: 1
59
+      }
60
+    }
61
+  },
62
+  created() {
63
+    this.fetchData()
64
+  },
65
+  methods: {
66
+    fetchData() {
67
+      if (!this.activityId) {
68
+        return
69
+      }
70
+
71
+      this.listLoading = true
72
+      getEnrollList({
73
+        activityId: this.activityId,
74
+        pageNum: this.pagination.current,
75
+        pageSize: this.pagination.size
76
+      }).then(res => {
77
+        this.list = res.records
78
+        this.pagination = {
79
+          total: res.total,
80
+          size: res.size,
81
+          current: res.current
82
+        }
83
+        this.listLoading = false
84
+      })
85
+    },
86
+
87
+    handleSizeChange(size) {
88
+      this.pagination.size = size
89
+    },
90
+
91
+    handleCurrentChange(current) {
92
+      this.pagination.current = current
93
+      this.fetchData()
94
+    }
95
+  }
96
+}
97
+</script>
98
+
99
+<style lang="scss" scoped>
100
+.pagination {
101
+  padding: 16px;
102
+  & > div {
103
+    float: right;
104
+  }
105
+}
106
+</style>

src/views/components/Activity/FilterForm.vue → src/views/activity/components/FilterForm.vue Zobrazit soubor


+ 131
- 0
src/views/activity/components/VoteEdit.vue Zobrazit soubor

@@ -0,0 +1,131 @@
1
+<template>
2
+  <div>
3
+    <floataction>
4
+      <el-tooltip content="新增投票项目" placement="top-start">
5
+        <el-button type="danger" icon="el-icon-plus" @click="addItem" circle></el-button>
6
+      </el-tooltip>
7
+    </floataction>
8
+    <ul class="vote-list" v-loading="loading">
9
+      <li v-for="(item, index) in voteItems" :key="index">
10
+        <painput :prefix="`${index + 1}.`" icon="el-icon-close" v-model="list[index].name" @click="deleteItem(item, index)" />
11
+      </li>
12
+    </ul>
13
+
14
+    <div>
15
+      <el-button type="primary" icon="" @click="saveItems">保 存</el-button>
16
+    </div>
17
+  </div>
18
+</template>
19
+
20
+<script>
21
+import { getVoteItems, saveVoteItems } from '@/api/activity'
22
+
23
+const VOTE_ITEM = {
24
+  name: undefined,
25
+  sortNo: 0
26
+}
27
+
28
+export default {
29
+  components: {
30
+    floataction: () => import('@/components/FloatAction'),
31
+    painput: () => import('@/components/PAInput')
32
+  },
33
+
34
+  props: {
35
+    activityId: {
36
+      type: Number,
37
+      default: 0
38
+    }
39
+  },
40
+
41
+  data() {
42
+    return {
43
+      loading: false,
44
+      list: null
45
+    }
46
+  },
47
+
48
+  computed: {
49
+    voteItems() {
50
+      return this.list || []
51
+    }
52
+  },
53
+
54
+  created() {
55
+    this.getItems()
56
+  },
57
+
58
+  watch: {
59
+    activityId(nw, od) {
60
+      if (nw && !od) {
61
+        this.getItems(nw)
62
+      }
63
+    }
64
+  },
65
+
66
+  methods: {
67
+    getItems(id) {
68
+      if (id || this.activityId) {
69
+        this.loading = true
70
+        getVoteItems(id || this.activityId).then(res => {
71
+          this.loading = false
72
+          this.list = res
73
+        })
74
+      }
75
+    },
76
+
77
+    addItem() {
78
+      if (this.hasEmpty()) {
79
+        return
80
+      }
81
+
82
+      const list = this.list || []
83
+      this.list = list.concat({
84
+        ...VOTE_ITEM,
85
+        sortNo: list.length + 1
86
+      })
87
+    },
88
+
89
+    deleteItem(row, index) {
90
+      this.removeListItem(index)
91
+    },
92
+
93
+    removeListItem(index) {
94
+      this.list = this.list.slice(0, index).concat(this.list.slice(index + 1))
95
+    },
96
+
97
+    saveItems() {
98
+      if (this.hasEmpty()) {
99
+        this.$message({ type: 'error', message: '请删除空白内容' })
100
+        return
101
+      }
102
+
103
+      if (this.activityId && this.list) {
104
+        this.loading = true
105
+        const list = this.list.filter(x => x.name)
106
+        saveVoteItems(this.activityId, list).then(res => {
107
+          this.loading = false
108
+          this.list = res
109
+        })
110
+      }
111
+    },
112
+
113
+    hasEmpty() {
114
+      return (this.list || []).filter(x => !x.name).length > 0
115
+    }
116
+
117
+  }
118
+}
119
+</script>
120
+
121
+<style lang="scss" scoped>
122
+.vote-list {
123
+  list-style: none;
124
+
125
+  li {
126
+    & + li {
127
+      margin-top: 12px;
128
+    }
129
+  }
130
+}
131
+</style>

+ 2
- 42
src/views/life/Warm/Detail.vue Zobrazit soubor

@@ -1,51 +1,11 @@
1 1
 <template>
2
-  <div class="app-container">
3
-    <div style="max-width: 60vw">
4
-      <activity type="2" :dataset="detail" @submit="handleSubmit" @cancel="handleCancel" />
5
-    </div>
6
-  </div>
2
+  <detail :type-id="1" />
7 3
 </template>
8 4
 
9 5
 <script>
10
-import { getActivity, updateActivity, saveActivity } from '@/api/activity'
11
-
12 6
 export default {
13 7
   components: {
14
-    activity: () => import('@/views/components/Activity')
15
-  },
16
-
17
-  data() {
18
-    return {
19
-      id: null,
20
-      detail: null
21
-    }
22
-  },
23
-
24
-  mounted() {
25
-    const { id } = this.$route.query
26
-    if (id) {
27
-      this.id = id
28
-      // eslint-disable-next-line no-return-assign
29
-      getActivity(id).then(res => this.detail = res)
30
-    }
31
-  },
32
-
33
-  methods: {
34
-    handleSubmit(data) {
35
-      if (this.id) {
36
-        updateActivity(data).then(() => {
37
-          this.$message({ type: 'success', message: '更新成功' })
38
-        })
39
-      } else {
40
-        saveActivity(data).then(res => {
41
-          this.$router.push({ name: 'warm.detail', query: { id: res.activityId }})
42
-        })
43
-      }
44
-    },
45
-
46
-    handleCancel() {
47
-      this.$router.go(-1)
48
-    }
8
+    detail: () => import('@/views/activity/Detail')
49 9
   }
50 10
 }
51 11
 </script>

+ 2
- 159
src/views/life/Warm/index.vue Zobrazit soubor

@@ -1,168 +1,11 @@
1 1
 <template>
2
-  <div class="app-container">
3
-    <div class="activity-header">
4
-      <FilterForm @search="handleSearch" @reset="handleSearch" />
5
-      <el-tooltip content="新增活动" placement="top">
6
-        <el-button type="primary" icon="el-icon-plus" @click="handleAdd" />
7
-      </el-tooltip>
8
-    </div>
9
-    <el-table
10
-      v-loading="listLoading"
11
-      :data="list"
12
-      element-loading-text="Loading"
13
-      border
14
-      fit
15
-      highlight-current-row
16
-      stripe
17
-    >
18
-      <el-table-column align="center" label="ID" width="100" prop="activityId" />
19
-      <el-table-column label="活动时间">
20
-        <template slot-scope="scope">
21
-          {{ scope.row.startDate | toDayMini }} - {{ scope.row.endDate | toDayMini }}
22
-        </template>
23
-      </el-table-column>
24
-      <el-table-column label="活动名称" prop="name" />
25
-      <el-table-column label="活动状态" align="center" width="200">
26
-        <template slot-scope="scope">
27
-          <el-tag
28
-            :type="scope.row.status | statusTagFormat"
29
-            disable-transitions
30
-          >{{ scope.row.status | statusFormat }}</el-tag>
31
-        </template>
32
-      </el-table-column>
33
-      <el-table-column label="操作" align="center" width="200">
34
-        <template slot-scope="scope">
35
-          <el-button size="mini" type="primary" plain @click="handleEdit(scope.row)">编辑</el-button>
36
-        </template>
37
-      </el-table-column>
38
-    </el-table>
39
-    <div class="pagination">
40
-      <el-pagination
41
-        :current-page="pagination.current"
42
-        :page-size="pagination.size"
43
-        :total="pagination.total"
44
-        :page-sizes="[10, 20, 50, 100]"
45
-        layout="total, sizes, prev, pager, next"
46
-        @size-change="handleSizeChange"
47
-        @current-change="handleCurrentChange"
48
-      />
49
-    </div>
50
-  </div>
2
+  <list :type-id="1" />
51 3
 </template>
52 4
 
53 5
 <script>
54
-import { getActivityList } from '@/api/activity'
55
-
56 6
 export default {
57 7
   components: {
58
-    FilterForm: () => import('../../components/Activity/FilterForm')
59
-  },
60
-
61
-  filters: {
62
-    statusFormat(status) {
63
-      if (status === null || status === undefined) {
64
-        return undefined
65
-      }
66
-
67
-      const statusMap = [
68
-        '未发布',
69
-        '已发布',
70
-        '已过期'
71
-      ]
72
-      return statusMap[status]
73
-    },
74
-
75
-    statusTagFormat(status) {
76
-      if (status === null || status === undefined) {
77
-        return undefined
78
-      }
79
-
80
-      const statusMap = [
81
-        'warning',
82
-        'success',
83
-        'info'
84
-      ]
85
-      return statusMap[status]
86
-    }
87
-  },
88
-  data() {
89
-    return {
90
-      list: null,
91
-      listLoading: true,
92
-      pagination: {
93
-        total: 0,
94
-        size: 10,
95
-        current: 1
96
-      },
97
-      filters: {
98
-        pageNum: 1,
99
-        pageSize: 10,
100
-        typeId: 2
101
-      }
102
-    }
103
-  },
104
-  created() {
105
-    this.fetchData()
106
-  },
107
-  methods: {
108
-    fetchData() {
109
-      this.listLoading = true
110
-      getActivityList({
111
-        ...this.filters,
112
-        pageNum: this.pagination.current,
113
-        pageSize: this.pagination.size
114
-      }).then(res => {
115
-        this.list = res.records
116
-        this.pagination = {
117
-          total: res.total,
118
-          size: res.size,
119
-          current: res.current
120
-        }
121
-        this.listLoading = false
122
-      })
123
-    },
124
-
125
-    handleAdd() {
126
-      this.$router.push({ name: 'warm.detail' })
127
-    },
128
-
129
-    handleEdit(row) {
130
-      this.$router.push({ name: 'warm.detail', query: { id: row.activityId }})
131
-    },
132
-
133
-    handleSizeChange(size) {
134
-      this.pagination.size = size
135
-    },
136
-
137
-    handleCurrentChange(current) {
138
-      this.pagination.current = current
139
-      this.fetchData()
140
-    },
141
-
142
-    handleSearch(searchParams) {
143
-      this.filters = {
144
-        ...this.filters,
145
-        ...searchParams,
146
-        pageNum: 1
147
-      }
148
-
149
-      this.fetchData()
150
-    }
8
+    list: () => import('@/views/activity/List')
151 9
   }
152 10
 }
153 11
 </script>
154
-
155
-<style lang="scss" scoped>
156
-.activity-header {
157
-  display: flex;
158
-  justify-content: space-between;
159
-  align-items: center;
160
-}
161
-
162
-.pagination {
163
-  padding: 16px;
164
-  & > div {
165
-    float: right;
166
-  }
167
-}
168
-</style>

+ 11
- 0
src/views/life/school/Detail.vue Zobrazit soubor

@@ -0,0 +1,11 @@
1
+<template>
2
+  <detail :type-id="2" />
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  components: {
8
+    detail: () => import('@/views/activity/Detail')
9
+  }
10
+}
11
+</script>

+ 11
- 0
src/views/life/school/index.vue Zobrazit soubor

@@ -0,0 +1,11 @@
1
+<template>
2
+  <list :type-id="2" />
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  components: {
8
+    list: () => import('@/views/activity/List')
9
+  }
10
+}
11
+</script>

+ 11
- 0
src/views/life/sport/Detail.vue Zobrazit soubor

@@ -0,0 +1,11 @@
1
+<template>
2
+  <detail :type-id="3" />
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  components: {
8
+    detail: () => import('@/views/activity/Detail')
9
+  }
10
+}
11
+</script>

+ 11
- 0
src/views/life/sport/index.vue Zobrazit soubor

@@ -0,0 +1,11 @@
1
+<template>
2
+  <list :type-id="3" />
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  components: {
8
+    list: () => import('@/views/activity/List')
9
+  }
10
+}
11
+</script>

+ 11
- 0
src/views/life/travel/Detail.vue Zobrazit soubor

@@ -0,0 +1,11 @@
1
+<template>
2
+  <detail :type-id="4" />
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  components: {
8
+    detail: () => import('@/views/activity/Detail')
9
+  }
10
+}
11
+</script>

+ 11
- 0
src/views/life/travel/index.vue Zobrazit soubor

@@ -0,0 +1,11 @@
1
+<template>
2
+  <list :type-id="4" />
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  components: {
8
+    list: () => import('@/views/activity/List')
9
+  }
10
+}
11
+</script>

+ 11
- 0
src/views/love/clothes/Detail.vue Zobrazit soubor

@@ -0,0 +1,11 @@
1
+<template>
2
+  <detail :type-id="5" />
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  components: {
8
+    detail: () => import('@/views/activity/Detail')
9
+  }
10
+}
11
+</script>

+ 11
- 0
src/views/love/clothes/index.vue Zobrazit soubor

@@ -0,0 +1,11 @@
1
+<template>
2
+  <list :type-id="5" />
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  components: {
8
+    list: () => import('@/views/activity/List')
9
+  }
10
+}
11
+</script>

+ 11
- 0
src/views/love/help/Detail.vue Zobrazit soubor

@@ -0,0 +1,11 @@
1
+<template>
2
+  <detail :type-id="6" />
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  components: {
8
+    detail: () => import('@/views/activity/Detail')
9
+  }
10
+}
11
+</script>

+ 11
- 0
src/views/love/help/index.vue Zobrazit soubor

@@ -0,0 +1,11 @@
1
+<template>
2
+  <list :type-id="6" />
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  components: {
8
+    list: () => import('@/views/activity/List')
9
+  }
10
+}
11
+</script>