张延森 преди 4 години
родител
ревизия
7e4a6461ec
променени са 38 файла, в които са добавени 1120 реда и са изтрити 414 реда
  1. 8
    0
      src/api/activity.js
  2. 10
    0
      src/api/customer.js
  3. 33
    0
      src/api/news.js
  4. 10
    0
      src/api/recommender.js
  5. 1
    1
      src/components/ECharts/index.vue
  6. 1
    1
      src/components/FloatAction/index.vue
  7. 5
    5
      src/components/MarkdownEditor/index.vue
  8. 15
    6
      src/components/PAInput/index.vue
  9. 19
    88
      src/router/index.js
  10. 7
    3
      src/views/activity/Detail.vue
  11. 1
    2
      src/views/activity/List.vue
  12. 15
    10
      src/views/activity/components/Detail.vue
  13. 15
    7
      src/views/activity/components/EnrollList.vue
  14. 0
    0
      src/views/activity/components/VoteDetail.vue
  15. 7
    7
      src/views/activity/components/VoteEdit.vue
  16. 93
    0
      src/views/activity/components/VoteList.vue
  17. 2
    1
      src/views/activity/components/VoteRank.vue
  18. 51
    0
      src/views/customer/components/FilterForm.vue
  19. 148
    0
      src/views/customer/index.vue
  20. 0
    85
      src/views/form/index.vue
  21. 0
    7
      src/views/nested/menu1/index.vue
  22. 0
    7
      src/views/nested/menu1/menu1-1/index.vue
  23. 0
    7
      src/views/nested/menu1/menu1-2/index.vue
  24. 0
    5
      src/views/nested/menu1/menu1-2/menu1-2-1/index.vue
  25. 0
    5
      src/views/nested/menu1/menu1-2/menu1-2-2/index.vue
  26. 0
    5
      src/views/nested/menu1/menu1-3/index.vue
  27. 0
    5
      src/views/nested/menu2/index.vue
  28. 203
    0
      src/views/news/Detail.vue
  29. 171
    0
      src/views/news/List.vue
  30. 53
    0
      src/views/news/components/FilterForm.vue
  31. 64
    0
      src/views/recommender/components/FilterForm.vue
  32. 144
    0
      src/views/recommender/index.vue
  33. 11
    0
      src/views/rights/letter/Detail.vue
  34. 11
    0
      src/views/rights/letter/index.vue
  35. 11
    0
      src/views/rights/seasons/Detail.vue
  36. 11
    0
      src/views/rights/seasons/index.vue
  37. 0
    79
      src/views/table/index.vue
  38. 0
    78
      src/views/tree/index.vue

+ 8
- 0
src/api/activity.js Целия файл

@@ -40,6 +40,14 @@ export function getEnrollList(params) {
40 40
   }))
41 41
 }
42 42
 
43
+export function getVoteList(activityId, params) {
44
+  return pureResponseData(request({
45
+    url: `/api/admin/activity/${activityId}/vote`,
46
+    method: 'get',
47
+    params
48
+  }))
49
+}
50
+
43 51
 export function getVoteItems(activityId) {
44 52
   return pureResponseData(request({
45 53
     url: `/api/admin/activity/${activityId}/voteitem`,

+ 10
- 0
src/api/customer.js Целия файл

@@ -0,0 +1,10 @@
1
+import request from '@/utils/request'
2
+import { pureResponseData } from './utils'
3
+
4
+export function getCustomerList(params) {
5
+  return pureResponseData(request({
6
+    url: `/api/admin/person`,
7
+    method: 'get',
8
+    params
9
+  }))
10
+}

+ 33
- 0
src/api/news.js Целия файл

@@ -0,0 +1,33 @@
1
+import request from '@/utils/request'
2
+import { pureResponseData } from './utils'
3
+
4
+export function getNews(id) {
5
+  return pureResponseData(request({
6
+    url: `/api/admin/news/${id}`,
7
+    method: 'get'
8
+  }))
9
+}
10
+
11
+export function updateNews(data) {
12
+  return pureResponseData(request({
13
+    url: `/api/admin/news/${data.newsId}`,
14
+    method: 'put',
15
+    data
16
+  }))
17
+}
18
+
19
+export function saveNews(data) {
20
+  return pureResponseData(request({
21
+    url: '/api/admin/news',
22
+    method: 'post',
23
+    data
24
+  }))
25
+}
26
+
27
+export function getNewsList(params) {
28
+  return pureResponseData(request({
29
+    url: `/api/admin/news`,
30
+    method: 'get',
31
+    params
32
+  }))
33
+}

+ 10
- 0
src/api/recommender.js Целия файл

@@ -0,0 +1,10 @@
1
+import request from '@/utils/request'
2
+import { pureResponseData } from './utils'
3
+
4
+export function getRecommenderList(params) {
5
+  return pureResponseData(request({
6
+    url: `/api/admin/recommender`,
7
+    method: 'get',
8
+    params
9
+  }))
10
+}

+ 1
- 1
src/components/ECharts/index.vue Целия файл

@@ -1,5 +1,5 @@
1 1
 <template>
2
-  <div ref="echarts"></div>
2
+  <div ref="echarts" />
3 3
 </template>
4 4
 
5 5
 <script>

+ 1
- 1
src/components/FloatAction/index.vue Целия файл

@@ -1,6 +1,6 @@
1 1
 <template>
2 2
   <div class="floatting-action" :style="style">
3
-    <slot></slot>
3
+    <slot />
4 4
   </div>
5 5
 </template>
6 6
 

+ 5
- 5
src/components/MarkdownEditor/index.vue Целия файл

@@ -1,13 +1,13 @@
1 1
 <template>
2 2
   <editor
3
-    :initialValue="value"
4
-    :initialEditType="mode"
3
+    ref="toastuiEditor"
4
+    :initial-value="value"
5
+    :initial-edit-type="mode"
5 6
     :options="options"
6 7
     :height="height"
7
-    previewStyle="vertical"
8
-    ref="toastuiEditor"
8
+    preview-style="vertical"
9 9
     @change="handleEditorChange"
10
-    />
10
+  />
11 11
 </template>
12 12
 
13 13
 <script>

+ 15
- 6
src/components/PAInput/index.vue Целия файл

@@ -1,16 +1,25 @@
1 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>
2
+  <el-input v-model="val" placeholder="请输入内容">
3
+    <template slot="prepend">{{ prefix }}</template>
4
+    <el-button slot="append" :icon="icon" @click="handleBtnClick" />
5 5
   </el-input>
6 6
 </template>
7 7
 
8 8
 <script>
9 9
 export default {
10 10
   props: {
11
-    value: String,
12
-    prefix: String,
13
-    icon: String
11
+    value: {
12
+      type: String,
13
+      default: undefined
14
+    },
15
+    prefix: {
16
+      type: String,
17
+      default: undefined
18
+    },
19
+    icon: {
20
+      type: String,
21
+      default: undefined
22
+    }
14 23
   },
15 24
 
16 25
   data() {

+ 19
- 88
src/router/index.js Целия файл

@@ -117,7 +117,7 @@ export const constantRoutes = [
117 117
       {
118 118
         path: 'warm-history',
119 119
         name: 'warm-history',
120
-        component: () => import('@/views/tree/index'),
120
+        // component: () => import('@/views/tree/index'),
121 121
         meta: { title: '暖场活动回顾', icon: 'tree' }
122 122
       }
123 123
     ]
@@ -133,14 +133,28 @@ export const constantRoutes = [
133 133
       {
134 134
         path: 'seasons',
135 135
         name: 'seasons',
136
-        component: () => import('@/views/table/index'),
136
+        component: () => import('@/views/rights/seasons'),
137 137
         meta: { title: '惊喜四季节', icon: 'el-icon-grape' }
138 138
       },
139
+      {
140
+        path: 'seasons/detail',
141
+        name: 'seasons.detail',
142
+        component: () => import('@/views/rights/seasons/Detail'),
143
+        meta: { title: '惊喜四季节详情' },
144
+        hidden: true
145
+      },
139 146
       {
140 147
         path: 'letter',
141 148
         name: 'letter',
142
-        component: () => import('@/views/tree/index'),
149
+        component: () => import('@/views/rights/letter'),
143 150
         meta: { title: '丽园家书', icon: 'el-icon-notebook-2' }
151
+      },
152
+      {
153
+        path: 'letter/detail',
154
+        name: 'letter.detail',
155
+        component: () => import('@/views/rights/letter/Detail'),
156
+        meta: { title: '丽园家书详情' },
157
+        hidden: true
144 158
       }
145 159
     ]
146 160
   },
@@ -191,101 +205,18 @@ export const constantRoutes = [
191 205
       {
192 206
         path: 'list',
193 207
         name: 'list',
194
-        component: () => import('@/views/table/index'),
208
+        component: () => import('@/views/customer/index'),
195 209
         meta: { title: '信息统计', icon: 'el-icon-data-analysis' }
196 210
       },
197 211
       {
198 212
         path: 'recommender',
199 213
         name: 'recommender',
200
-        component: () => import('@/views/tree/index'),
214
+        component: () => import('@/views/recommender/index'),
201 215
         meta: { title: '推荐记录', icon: 'el-icon-notebook-1' }
202 216
       }
203 217
     ]
204 218
   },
205 219
 
206
-  {
207
-    path: '/form',
208
-    component: Layout,
209
-    children: [
210
-      {
211
-        path: 'index',
212
-        name: 'Form',
213
-        component: () => import('@/views/form/index'),
214
-        meta: { title: 'Form', icon: 'form' }
215
-      }
216
-    ]
217
-  },
218
-
219
-  {
220
-    path: '/nested',
221
-    component: Layout,
222
-    redirect: '/nested/menu1',
223
-    name: 'Nested',
224
-    meta: {
225
-      title: 'Nested',
226
-      icon: 'nested'
227
-    },
228
-    children: [
229
-      {
230
-        path: 'menu1',
231
-        component: () => import('@/views/nested/menu1/index'), // Parent router-view
232
-        name: 'Menu1',
233
-        meta: { title: 'Menu1' },
234
-        children: [
235
-          {
236
-            path: 'menu1-1',
237
-            component: () => import('@/views/nested/menu1/menu1-1'),
238
-            name: 'Menu1-1',
239
-            meta: { title: 'Menu1-1' }
240
-          },
241
-          {
242
-            path: 'menu1-2',
243
-            component: () => import('@/views/nested/menu1/menu1-2'),
244
-            name: 'Menu1-2',
245
-            meta: { title: 'Menu1-2' },
246
-            children: [
247
-              {
248
-                path: 'menu1-2-1',
249
-                component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'),
250
-                name: 'Menu1-2-1',
251
-                meta: { title: 'Menu1-2-1' }
252
-              },
253
-              {
254
-                path: 'menu1-2-2',
255
-                component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'),
256
-                name: 'Menu1-2-2',
257
-                meta: { title: 'Menu1-2-2' }
258
-              }
259
-            ]
260
-          },
261
-          {
262
-            path: 'menu1-3',
263
-            component: () => import('@/views/nested/menu1/menu1-3'),
264
-            name: 'Menu1-3',
265
-            meta: { title: 'Menu1-3' }
266
-          }
267
-        ]
268
-      },
269
-      {
270
-        path: 'menu2',
271
-        component: () => import('@/views/nested/menu2/index'),
272
-        name: 'Menu2',
273
-        meta: { title: 'menu2' }
274
-      }
275
-    ]
276
-  },
277
-
278
-  {
279
-    path: 'external-link',
280
-    component: Layout,
281
-    children: [
282
-      {
283
-        path: 'https://panjiachen.github.io/vue-element-admin-site/#/',
284
-        meta: { title: 'External Link', icon: 'link' }
285
-      }
286
-    ]
287
-  },
288
-
289 220
   // 404 page must be placed at the end !!!
290 221
   { path: '*', redirect: '/404', hidden: true }
291 222
 ]

+ 7
- 3
src/views/activity/Detail.vue Целия файл

@@ -9,11 +9,14 @@
9 9
       <el-tab-pane v-if="detail && detail.isEnroll" label="报名详情" name="enroll">
10 10
         <enroll-list :activity-id="detail.activityId" />
11 11
       </el-tab-pane>
12
-      <el-tab-pane label="投票设置" name="vote">
12
+      <el-tab-pane v-if="detail && detail.isVote" label="投票设置" name="vote">
13 13
         <voteedit :activity-id="detail.activityId" />
14 14
       </el-tab-pane>
15
-      <el-tab-pane label="投票排行" name="rank">
15
+      <el-tab-pane v-if="detail && detail.isVote" label="投票排行" name="rank">
16 16
         <voterank :show="showRank" :activity-id="detail.activityId" style="width: 60vw; min-height: 400px" />
17
+        <div style="margin-top: 48px">
18
+          <votelist :activity-id="detail.activityId" />
19
+        </div>
17 20
       </el-tab-pane>
18 21
     </el-tabs>
19 22
   </div>
@@ -27,7 +30,8 @@ export default {
27 30
     activity: () => import('./components/Detail'),
28 31
     enrollList: () => import('./components/EnrollList'),
29 32
     voteedit: () => import('./components/VoteEdit'),
30
-    voterank: () => import('./components/VoteRank')
33
+    voterank: () => import('./components/VoteRank'),
34
+    votelist: () => import('./components/VoteList')
31 35
   },
32 36
 
33 37
   props: {

+ 1
- 2
src/views/activity/List.vue Целия файл

@@ -41,7 +41,7 @@
41 41
       :size.sync="page.size"
42 42
       :current.sync="page.current"
43 43
       @change="handlePageChange"
44
-    ></pagination>
44
+    />
45 45
   </div>
46 46
 </template>
47 47
 
@@ -50,7 +50,6 @@ import { getActivityList } from '@/api/activity'
50 50
 
51 51
 export default {
52 52
   components: {
53
-    // pagination: () => import('@/components/Pagination'),
54 53
     FilterForm: () => import('./components/FilterForm')
55 54
   },
56 55
 

+ 15
- 10
src/views/activity/components/Detail.vue Целия файл

@@ -9,7 +9,8 @@
9 9
         type="daterange"
10 10
         start-placeholder="开始日期"
11 11
         end-placeholder="结束日期"
12
-        style="width: 100%;" />
12
+        style="width: 100%;"
13
+      />
13 14
     </el-form-item>
14 15
     <el-form-item label="活动封面" prop="thumb">
15 16
       <el-upload
@@ -18,9 +19,10 @@
18 19
         class="activty-uploader"
19 20
         :show-file-list="false"
20 21
         :on-success="handleUploadThumbSuccess"
21
-        :before-upload="beforeThumbUpload">
22
+        :before-upload="beforeThumbUpload"
23
+      >
22 24
         <img v-if="form.thumb" :src="form.thumb" class="activty-thumb">
23
-        <i v-else class="el-icon-plus avatar-uploader-icon"></i>
25
+        <i v-else class="el-icon-plus avatar-uploader-icon" />
24 26
       </el-upload>
25 27
     </el-form-item>
26 28
     <el-form-item label="活动地点" prop="address">
@@ -30,15 +32,16 @@
30 32
       <el-form-item label="允许报名" prop="isEnroll">
31 33
         <el-switch v-model="form.isEnroll" />
32 34
       </el-form-item>
33
-      <el-form-item label="报名时间" v-if="form.isEnroll">
35
+      <el-form-item v-if="form.isEnroll" label="报名时间">
34 36
         <el-date-picker
35 37
           v-model="dtRange2"
36 38
           type="daterange"
37 39
           start-placeholder="开始日期"
38 40
           end-placeholder="结束日期"
39
-          style="width: 100%;" />
41
+          style="width: 100%;"
42
+        />
40 43
       </el-form-item>
41
-      <el-form-item label="当前报名" v-if="form.isEnroll">
44
+      <el-form-item v-if="form.isEnroll" label="当前报名">
42 45
         <el-input v-model="form.enrollNum">
43 46
           <template slot="append">人</template>
44 47
         </el-input>
@@ -51,13 +54,14 @@
51 54
       <el-form-item label="参与投票" prop="isVote">
52 55
         <el-switch v-model="form.isVote" />
53 56
       </el-form-item>
54
-      <el-form-item label="投票时间" v-if="form.isVote">
57
+      <el-form-item v-if="form.isVote" label="投票时间">
55 58
         <el-date-picker
56 59
           v-model="dtRange3"
57 60
           type="daterange"
58 61
           start-placeholder="开始日期"
59 62
           end-placeholder="结束日期"
60
-          style="width: 100%;" />
63
+          style="width: 100%;"
64
+        />
61 65
       </el-form-item>
62 66
     </template>
63 67
     <el-form-item label="活动状态" prop="status">
@@ -78,9 +82,10 @@
78 82
         action=""
79 83
         :show-file-list="false"
80 84
         :on-success="handleShareSuccess"
81
-        :before-upload="beforeShareUpload">
85
+        :before-upload="beforeShareUpload"
86
+      >
82 87
         <img v-if="form.shareImg" :src="form.shareImg" class="activty-thumb">
83
-        <i v-else class="el-icon-plus avatar-uploader-icon"></i>
88
+        <i v-else class="el-icon-plus avatar-uploader-icon" />
84 89
       </el-upload>
85 90
     </el-form-item>
86 91
     <el-form-item>

+ 15
- 7
src/views/activity/components/EnrollList.vue Целия файл

@@ -11,8 +11,8 @@
11 11
     >
12 12
       <el-table-column
13 13
         type="index"
14
-        width="50">
15
-      </el-table-column>
14
+        width="50"
15
+      />
16 16
       <el-table-column label="报名时间">
17 17
         <template slot-scope="scope">
18 18
           {{ scope.row.createDate | toDayMini }}
@@ -32,7 +32,7 @@
32 32
       :size.sync="page.size"
33 33
       :current.sync="page.current"
34 34
       @change="handlePageChange"
35
-    ></pagination>
35
+    />
36 36
   </div>
37 37
 </template>
38 38
 
@@ -41,7 +41,10 @@ import { getEnrollList } from '@/api/activity'
41 41
 
42 42
 export default {
43 43
   props: {
44
-    activityId: Number
44
+    activityId: {
45
+      type: Number,
46
+      default: 0
47
+    }
45 48
   },
46 49
   data() {
47 50
     return {
@@ -54,18 +57,23 @@ export default {
54 57
       }
55 58
     }
56 59
   },
60
+  watch: {
61
+    activityId(nw) {
62
+      this.fetchData(nw)
63
+    }
64
+  },
57 65
   created() {
58 66
     this.fetchData()
59 67
   },
60 68
   methods: {
61
-    fetchData() {
62
-      if (!this.activityId) {
69
+    fetchData(id) {
70
+      if (!id && !this.activityId) {
63 71
         return
64 72
       }
65 73
 
66 74
       this.listLoading = true
67 75
       getEnrollList({
68
-        activityId: this.activityId,
76
+        activityId: id || this.activityId,
69 77
         pageNum: this.page.current,
70 78
         pageSize: this.page.size
71 79
       }).then(res => {

+ 0
- 0
src/views/activity/components/VoteDetail.vue Целия файл


+ 7
- 7
src/views/activity/components/VoteEdit.vue Целия файл

@@ -2,12 +2,12 @@
2 2
   <div>
3 3
     <floataction>
4 4
       <el-tooltip content="新增投票项目" placement="top-start">
5
-        <el-button type="danger" icon="el-icon-plus" @click="addItem" circle></el-button>
5
+        <el-button type="danger" icon="el-icon-plus" circle @click="addItem" />
6 6
       </el-tooltip>
7 7
     </floataction>
8
-    <ul class="vote-list" v-loading="loading">
8
+    <ul v-loading="loading" class="vote-list">
9 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)" />
10
+        <painput v-model="list[index].name" :prefix="`${index + 1}.`" icon="el-icon-close" @click="deleteItem(item, index)" />
11 11
       </li>
12 12
     </ul>
13 13
 
@@ -51,10 +51,6 @@ export default {
51 51
     }
52 52
   },
53 53
 
54
-  created() {
55
-    this.getItems()
56
-  },
57
-
58 54
   watch: {
59 55
     activityId(nw, od) {
60 56
       if (nw && !od) {
@@ -63,6 +59,10 @@ export default {
63 59
     }
64 60
   },
65 61
 
62
+  created() {
63
+    this.getItems()
64
+  },
65
+
66 66
   methods: {
67 67
     getItems(id) {
68 68
       if (id || this.activityId) {

+ 93
- 0
src/views/activity/components/VoteList.vue Целия файл

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

+ 2
- 1
src/views/activity/components/VoteRank.vue Целия файл

@@ -3,7 +3,8 @@
3 3
     :show="show"
4 4
     :options="options"
5 5
     :data-source="source"
6
-    :loading="loading"></echarts>
6
+    :loading="loading"
7
+  />
7 8
 </template>
8 9
 
9 10
 <script>

+ 51
- 0
src/views/customer/components/FilterForm.vue Целия файл

@@ -0,0 +1,51 @@
1
+<template>
2
+  <el-form :inline="true" :model="formData" class="filter-form">
3
+    <el-form-item label="手机">
4
+      <el-input v-model="formData.phone" placeholder="手机" />
5
+    </el-form-item>
6
+    <el-form-item label="名称">
7
+      <el-input v-model="formData.name" placeholder="名称" />
8
+    </el-form-item>
9
+    <el-form-item style="margin-left: 36px">
10
+      <el-button type="primary" @click="handleSubmit">查询</el-button>
11
+      <el-button @click="handleReset">重置</el-button>
12
+    </el-form-item>
13
+  </el-form>
14
+</template>
15
+
16
+<script>
17
+export default {
18
+  data() {
19
+    return {
20
+      formData: {
21
+        phone: undefined,
22
+        name: undefined,
23
+        nickname: undefined
24
+      }
25
+    }
26
+  },
27
+
28
+  methods: {
29
+    handleSubmit() {
30
+      this.$emit('search', this.formData)
31
+    },
32
+
33
+    handleReset() {
34
+      const def = Object.keys(this.formData).reduce((acc, key) => {
35
+        return {
36
+          ...acc,
37
+          [key]: undefined
38
+        }
39
+      }, {})
40
+      this.formData = def
41
+      this.$emit('reset', def)
42
+    }
43
+  }
44
+}
45
+</script>
46
+
47
+<style lang="scss" scoped>
48
+.filter-form {
49
+  padding: 16px 0;
50
+}
51
+</style>

+ 148
- 0
src/views/customer/index.vue Целия файл

@@ -0,0 +1,148 @@
1
+<template>
2
+  <div class="app-container">
3
+    <div class="customer-header">
4
+      <FilterForm @search="handleSearch" @reset="handleSearch" />
5
+      <el-tooltip content="导出" placement="top">
6
+        <el-button type="primary" icon="el-icon-position" @click="handleExport" />
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
19
+        type="index"
20
+        width="50"
21
+      />
22
+      <el-table-column label="头像">
23
+        <template slot-scope="scope">
24
+          <img :src="scope.row.avatar" width="64" alt="">
25
+        </template>
26
+      </el-table-column>
27
+      <el-table-column label="手机" prop="phone" />
28
+      <el-table-column label="名称" prop="name" />
29
+      <el-table-column label="昵称" prop="nickname" />
30
+      <el-table-column label="性别" align="center" width="200">
31
+        <template slot-scope="scope">
32
+          <el-tag
33
+            :type="scope.row.sex | sexTagFormat"
34
+            disable-transitions
35
+          >{{ scope.row.sex | sexFormat }}</el-tag>
36
+        </template>
37
+      </el-table-column>
38
+      <el-table-column label="时间">
39
+        <template slot-scope="scope">
40
+          {{ scope.row.createDate | toDayMini }}
41
+        </template>
42
+      </el-table-column>
43
+    </el-table>
44
+    <pagination
45
+      :total="page.total"
46
+      :size.sync="page.size"
47
+      :current.sync="page.current"
48
+      @change="handlePageChange"
49
+    />
50
+  </div>
51
+</template>
52
+
53
+<script>
54
+import { getCustomerList } from '@/api/customer'
55
+
56
+export default {
57
+  components: {
58
+    FilterForm: () => import('./components/FilterForm')
59
+  },
60
+
61
+  filters: {
62
+    sexFormat(sex) {
63
+      if (sex === null || sex === undefined) {
64
+        return undefined
65
+      }
66
+
67
+      const sexMap = [
68
+        '未知',
69
+        '男',
70
+        '女'
71
+      ]
72
+      return sexMap[sex]
73
+    },
74
+
75
+    sexTagFormat(sex) {
76
+      if (sex === null || sex === undefined) {
77
+        return undefined
78
+      }
79
+
80
+      const sexMap = [
81
+        'info',
82
+        'success',
83
+        'danger'
84
+      ]
85
+      return sexMap[sex]
86
+    }
87
+  },
88
+
89
+  data() {
90
+    return {
91
+      list: null,
92
+      listLoading: true,
93
+      page: {
94
+        total: 0,
95
+        size: 10,
96
+        current: 1
97
+      },
98
+      filters: {
99
+        pageNum: 1,
100
+        pageSize: 10
101
+      }
102
+    }
103
+  },
104
+  created() {
105
+    this.fetchData()
106
+  },
107
+  methods: {
108
+    fetchData() {
109
+      this.listLoading = true
110
+      getCustomerList({
111
+        ...this.filters,
112
+        pageNum: this.page.current,
113
+        pageSize: this.page.size
114
+      }).then(res => {
115
+        this.list = res.records
116
+        this.page.total = res.total
117
+        this.listLoading = false
118
+      })
119
+    },
120
+
121
+    handleExport() {},
122
+
123
+    handlePageChange({ current, size }) {
124
+      this.page.current = current
125
+      this.page.size = size
126
+      this.fetchData()
127
+    },
128
+
129
+    handleSearch(searchParams) {
130
+      this.filters = {
131
+        ...this.filters,
132
+        ...searchParams,
133
+        pageNum: 1
134
+      }
135
+
136
+      this.fetchData()
137
+    }
138
+  }
139
+}
140
+</script>
141
+
142
+<style lang="scss" scoped>
143
+.customer-header {
144
+  display: flex;
145
+  justify-content: space-between;
146
+  align-items: center;
147
+}
148
+</style>

+ 0
- 85
src/views/form/index.vue Целия файл

@@ -1,85 +0,0 @@
1
-<template>
2
-  <div class="app-container">
3
-    <el-form ref="form" :model="form" label-width="120px">
4
-      <el-form-item label="Activity name">
5
-        <el-input v-model="form.name" />
6
-      </el-form-item>
7
-      <el-form-item label="Activity zone">
8
-        <el-select v-model="form.region" placeholder="please select your zone">
9
-          <el-option label="Zone one" value="shanghai" />
10
-          <el-option label="Zone two" value="beijing" />
11
-        </el-select>
12
-      </el-form-item>
13
-      <el-form-item label="Activity time">
14
-        <el-col :span="11">
15
-          <el-date-picker v-model="form.date1" type="date" placeholder="Pick a date" style="width: 100%;" />
16
-        </el-col>
17
-        <el-col :span="2" class="line">-</el-col>
18
-        <el-col :span="11">
19
-          <el-time-picker v-model="form.date2" type="fixed-time" placeholder="Pick a time" style="width: 100%;" />
20
-        </el-col>
21
-      </el-form-item>
22
-      <el-form-item label="Instant delivery">
23
-        <el-switch v-model="form.delivery" />
24
-      </el-form-item>
25
-      <el-form-item label="Activity type">
26
-        <el-checkbox-group v-model="form.type">
27
-          <el-checkbox label="Online activities" name="type" />
28
-          <el-checkbox label="Promotion activities" name="type" />
29
-          <el-checkbox label="Offline activities" name="type" />
30
-          <el-checkbox label="Simple brand exposure" name="type" />
31
-        </el-checkbox-group>
32
-      </el-form-item>
33
-      <el-form-item label="Resources">
34
-        <el-radio-group v-model="form.resource">
35
-          <el-radio label="Sponsor" />
36
-          <el-radio label="Venue" />
37
-        </el-radio-group>
38
-      </el-form-item>
39
-      <el-form-item label="Activity form">
40
-        <el-input v-model="form.desc" type="textarea" />
41
-      </el-form-item>
42
-      <el-form-item>
43
-        <el-button type="primary" @click="onSubmit">Create</el-button>
44
-        <el-button @click="onCancel">Cancel</el-button>
45
-      </el-form-item>
46
-    </el-form>
47
-  </div>
48
-</template>
49
-
50
-<script>
51
-export default {
52
-  data() {
53
-    return {
54
-      form: {
55
-        name: '',
56
-        region: '',
57
-        date1: '',
58
-        date2: '',
59
-        delivery: false,
60
-        type: [],
61
-        resource: '',
62
-        desc: ''
63
-      }
64
-    }
65
-  },
66
-  methods: {
67
-    onSubmit() {
68
-      this.$message('submit!')
69
-    },
70
-    onCancel() {
71
-      this.$message({
72
-        message: 'cancel!',
73
-        type: 'warning'
74
-      })
75
-    }
76
-  }
77
-}
78
-</script>
79
-
80
-<style scoped>
81
-.line{
82
-  text-align: center;
83
-}
84
-</style>
85
-

+ 0
- 7
src/views/nested/menu1/index.vue Целия файл

@@ -1,7 +0,0 @@
1
-<template>
2
-  <div style="padding:30px;">
3
-    <el-alert :closable="false" title="menu 1">
4
-      <router-view />
5
-    </el-alert>
6
-  </div>
7
-</template>

+ 0
- 7
src/views/nested/menu1/menu1-1/index.vue Целия файл

@@ -1,7 +0,0 @@
1
-<template>
2
-  <div style="padding:30px;">
3
-    <el-alert :closable="false" title="menu 1-1" type="success">
4
-      <router-view />
5
-    </el-alert>
6
-  </div>
7
-</template>

+ 0
- 7
src/views/nested/menu1/menu1-2/index.vue Целия файл

@@ -1,7 +0,0 @@
1
-<template>
2
-  <div style="padding:30px;">
3
-    <el-alert :closable="false" title="menu 1-2" type="success">
4
-      <router-view />
5
-    </el-alert>
6
-  </div>
7
-</template>

+ 0
- 5
src/views/nested/menu1/menu1-2/menu1-2-1/index.vue Целия файл

@@ -1,5 +0,0 @@
1
-<template functional>
2
-  <div style="padding:30px;">
3
-    <el-alert :closable="false" title="menu 1-2-1" type="warning" />
4
-  </div>
5
-</template>

+ 0
- 5
src/views/nested/menu1/menu1-2/menu1-2-2/index.vue Целия файл

@@ -1,5 +0,0 @@
1
-<template functional>
2
-  <div style="padding:30px;">
3
-    <el-alert :closable="false" title="menu 1-2-2" type="warning" />
4
-  </div>
5
-</template>

+ 0
- 5
src/views/nested/menu1/menu1-3/index.vue Целия файл

@@ -1,5 +0,0 @@
1
-<template functional>
2
-  <div style="padding:30px;">
3
-    <el-alert :closable="false" title="menu 1-3" type="success" />
4
-  </div>
5
-</template>

+ 0
- 5
src/views/nested/menu2/index.vue Целия файл

@@ -1,5 +0,0 @@
1
-<template>
2
-  <div style="padding:30px;">
3
-    <el-alert :closable="false" title="menu 2" />
4
-  </div>
5
-</template>

+ 203
- 0
src/views/news/Detail.vue Целия файл

@@ -0,0 +1,203 @@
1
+<template>
2
+  <div class="app-container">
3
+    <el-form ref="newsForm" v-loading="loading.form" :model="form" :rules="rules" label-width="120px">
4
+      <el-form-item label="标题" prop="title">
5
+        <el-input v-model="form.title" />
6
+      </el-form-item>
7
+      <el-form-item label="发布人" prop="publisher">
8
+        <el-input v-model="form.publisher" />
9
+      </el-form-item>
10
+      <el-form-item label="发布时间" prop="publishDate">
11
+        <el-input v-model="form.publishDate" />
12
+      </el-form-item>
13
+      <el-form-item label="封面" prop="thumb">
14
+        <el-upload
15
+          v-loading="loading.thumb"
16
+          v-bind="uploadOption"
17
+          class="news-uploader"
18
+          :show-file-list="false"
19
+          :on-success="handleUploadThumbSuccess"
20
+          :before-upload="beforeThumbUpload"
21
+        >
22
+          <img v-if="form.thumb" :src="form.thumb" class="news-thumb">
23
+          <i v-else class="el-icon-plus avatar-uploader-icon" />
24
+        </el-upload>
25
+      </el-form-item>
26
+      <el-form-item label="详情" prop="content">
27
+        <markdown v-model="form.content" />
28
+      </el-form-item>
29
+      <el-form-item label="活动状态" prop="status">
30
+        <el-select v-model="form.status" placeholder="请选择">
31
+          <el-option label="未发布" :value="0" />
32
+          <el-option label="已发布" :value="1" />
33
+        </el-select>
34
+      </el-form-item>
35
+      <el-form-item>
36
+        <el-button type="primary" @click="handleSubmit">保 存</el-button>
37
+        <el-button @click="handleCancel">取 消</el-button>
38
+      </el-form-item>
39
+    </el-form>
40
+  </div>
41
+</template>
42
+
43
+<script>
44
+import dayjs from 'dayjs'
45
+import { Message } from 'element-ui'
46
+import uploadOption from '@/utils/uploadOption'
47
+import { getNews, saveNews, updateNews } from '@/api/news'
48
+
49
+export default {
50
+  components: {
51
+    markdown: () => import('@/components/MarkdownEditor')
52
+  },
53
+
54
+  props: {
55
+    typeId: {
56
+      type: Number,
57
+      default: 0
58
+    }
59
+  },
60
+
61
+  data() {
62
+    return {
63
+      id: null,
64
+      loading: {
65
+        form: false,
66
+        thumb: false
67
+      },
68
+      uploadOption,
69
+      form: {
70
+        newsId: null,
71
+        title: null,
72
+        publisher: null,
73
+        publishDate: dayjs().format('YYYY-MM-DD'),
74
+        thumb: null,
75
+        content: null,
76
+        status: 0,
77
+        weight: 0
78
+      },
79
+      rules: {
80
+        title: [
81
+          { required: true, message: '请输入标题', trigger: 'blur' }
82
+        ],
83
+        publisher: [
84
+          { required: true, message: '请输入发布人', trigger: 'blur' }
85
+        ],
86
+        publishDate: [
87
+          { required: true, message: '请输入发布时间', trigger: 'blur' }
88
+        ]
89
+      }
90
+    }
91
+  },
92
+
93
+  created() {
94
+    const { id } = this.$route.query
95
+    this.id = id
96
+    this.fetchData()
97
+  },
98
+
99
+  methods: {
100
+    fetchData() {
101
+      if (this.id) {
102
+        this.loading.form = true
103
+        getNews(this.id).then(res => {
104
+          this.form = res
105
+          this.loading.form = false
106
+        }).catch(err => {
107
+          console.error(err)
108
+          this.loading.form = false
109
+        })
110
+      }
111
+    },
112
+
113
+    handleSubmit() {
114
+      this.$refs.newsForm.validate(valid => {
115
+        if (valid) {
116
+          const data = {
117
+            ...this.form,
118
+            typeId: this.typeId
119
+          }
120
+
121
+          //
122
+          this.loading.form = true
123
+          if (this.id) {
124
+            updateNews(data).then(() => {
125
+              this.$message({ type: 'success', message: '更新成功' })
126
+              this.loading.form = false
127
+            }).catch(err => {
128
+              console.error(err)
129
+              this.loading.form = false
130
+            })
131
+          } else {
132
+            saveNews(data).then(res => {
133
+              this.$router.replace({ name: this.$route.name, params: { typeId: this.typeId }, query: { id: res.newsId }})
134
+              this.loading.form = false
135
+            }).catch(err => {
136
+              console.error(err)
137
+              this.loading.form = false
138
+            })
139
+          }
140
+        }
141
+      })
142
+    },
143
+
144
+    handleCancel() {
145
+      this.$router.go(-1)
146
+    },
147
+
148
+    beforeThumbUpload(file) {
149
+      // const isJPG = file.type === 'image/jpeg';
150
+      // const isLt2M = file.size / 1024 / 1024 < 2;
151
+
152
+      this.loading.thumb = true
153
+
154
+      return true
155
+    },
156
+
157
+    handleUploadThumbSuccess(res, file) {
158
+      this.loading.thumb = false
159
+
160
+      if (res.code !== 1000) {
161
+        Message({
162
+          message: res.message || 'Error',
163
+          type: 'error',
164
+          duration: 5 * 1000
165
+        })
166
+      } else {
167
+        this.form.thumb = res.data.url
168
+      }
169
+    }
170
+  }
171
+}
172
+</script>
173
+
174
+<style lang="scss">
175
+.news-uploader {
176
+  .el-upload {
177
+    border: 1px dashed #d9d9d9;
178
+    border-radius: 6px;
179
+    cursor: pointer;
180
+    position: relative;
181
+    overflow: hidden;
182
+
183
+    &:hover {
184
+      border-color: #409EFF;
185
+    }
186
+
187
+    .avatar-uploader-icon {
188
+      font-size: 28px;
189
+      color: #8c939d;
190
+      width: 178px;
191
+      height: 178px;
192
+      line-height: 178px;
193
+      text-align: center;
194
+    }
195
+  }
196
+}
197
+
198
+.news-thumb {
199
+  width: 178px;
200
+  height: 178px;
201
+  display: block;
202
+}
203
+</style>

+ 171
- 0
src/views/news/List.vue Целия файл

@@ -0,0 +1,171 @@
1
+<template>
2
+  <div class="app-container">
3
+    <div class="news-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
19
+        type="index"
20
+        width="50"
21
+      />
22
+      <el-table-column label="创建时间">
23
+        <template slot-scope="scope">
24
+          {{ scope.row.createDate | toDayMini }}
25
+        </template>
26
+      </el-table-column>
27
+      <el-table-column label="标题" prop="title" />
28
+      <el-table-column label="封面">
29
+        <template slot-scope="scope">
30
+          <img :src="scope.row.thumb" width="64" alt="">
31
+        </template>
32
+      </el-table-column>
33
+      <el-table-column label="发布人" prop="publisher" />
34
+      <el-table-column label="状态" align="center" width="200">
35
+        <template slot-scope="scope">
36
+          <el-tag
37
+            :type="scope.row.status | statusTagFormat"
38
+            disable-transitions
39
+          >{{ scope.row.status | statusFormat }}</el-tag>
40
+        </template>
41
+      </el-table-column>
42
+      <el-table-column label="操作" align="center" width="200">
43
+        <template slot-scope="scope">
44
+          <el-button size="mini" type="primary" plain @click="handleEdit(scope.row)">编辑</el-button>
45
+        </template>
46
+      </el-table-column>
47
+    </el-table>
48
+    <pagination
49
+      :total="page.total"
50
+      :size.sync="page.size"
51
+      :current.sync="page.current"
52
+      @change="handlePageChange"
53
+    />
54
+  </div>
55
+</template>
56
+
57
+<script>
58
+import { getNewsList } from '@/api/news'
59
+
60
+export default {
61
+  components: {
62
+    FilterForm: () => import('./components/FilterForm')
63
+  },
64
+  filters: {
65
+    statusFormat(status) {
66
+      if (status === null || status === undefined) {
67
+        return undefined
68
+      }
69
+
70
+      const statusMap = [
71
+        '未发布',
72
+        '已发布'
73
+      ]
74
+      return statusMap[status]
75
+    },
76
+
77
+    statusTagFormat(status) {
78
+      if (status === null || status === undefined) {
79
+        return undefined
80
+      }
81
+
82
+      const statusMap = [
83
+        'warning',
84
+        'success'
85
+      ]
86
+      return statusMap[status]
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
+      page: {
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
+      getNewsList({
120
+        ...this.filters,
121
+        typeId: this.typeId,
122
+        pageNum: this.page.current,
123
+        pageSize: this.page.size
124
+      }).then(res => {
125
+        this.list = res.records
126
+        this.page.total = res.total
127
+        this.listLoading = false
128
+      })
129
+    },
130
+
131
+    handlePageChange({ current, size }) {
132
+      this.page.current = current
133
+      this.page.size = size
134
+      this.fetchData()
135
+    },
136
+
137
+    handleAdd() {
138
+      this.$router.push({
139
+        name: this.detailRouter,
140
+        params: { typeId: this.typeId }
141
+      })
142
+    },
143
+
144
+    handleEdit(row) {
145
+      this.$router.push({
146
+        name: this.detailRouter,
147
+        params: { typeId: this.typeId },
148
+        query: { id: row.newsId }
149
+      })
150
+    },
151
+
152
+    handleSearch(searchParams) {
153
+      this.filters = {
154
+        ...this.filters,
155
+        ...searchParams,
156
+        pageNum: 1
157
+      }
158
+
159
+      this.fetchData()
160
+    }
161
+  }
162
+}
163
+</script>
164
+
165
+<style lang="scss" scoped>
166
+.news-header {
167
+  display: flex;
168
+  justify-content: space-between;
169
+  align-items: center;
170
+}
171
+</style>

+ 53
- 0
src/views/news/components/FilterForm.vue Целия файл

@@ -0,0 +1,53 @@
1
+<template>
2
+  <el-form :inline="true" :model="formData" class="filter-form">
3
+    <el-form-item label="标题">
4
+      <el-input v-model="formData.title" placeholder="标题" />
5
+    </el-form-item>
6
+    <el-form-item label="状态">
7
+      <el-select v-model="formData.status" placeholder="请选择状态">
8
+        <el-option label="未发布" :value="0" />
9
+        <el-option label="已发布" :value="1" />
10
+      </el-select>
11
+    </el-form-item>
12
+    <el-form-item style="margin-left: 36px">
13
+      <el-button type="primary" @click="handleSubmit">查询</el-button>
14
+      <el-button @click="handleReset">重置</el-button>
15
+    </el-form-item>
16
+  </el-form>
17
+</template>
18
+
19
+<script>
20
+export default {
21
+  data() {
22
+    return {
23
+      formData: {
24
+        title: undefined,
25
+        status: undefined
26
+      }
27
+    }
28
+  },
29
+
30
+  methods: {
31
+    handleSubmit() {
32
+      this.$emit('search', this.formData)
33
+    },
34
+
35
+    handleReset() {
36
+      const def = Object.keys(this.formData).reduce((acc, key) => {
37
+        return {
38
+          ...acc,
39
+          [key]: undefined
40
+        }
41
+      }, {})
42
+      this.formData = def
43
+      this.$emit('reset', def)
44
+    }
45
+  }
46
+}
47
+</script>
48
+
49
+<style lang="scss" scoped>
50
+.filter-form {
51
+  padding: 16px 0;
52
+}
53
+</style>

+ 64
- 0
src/views/recommender/components/FilterForm.vue Целия файл

@@ -0,0 +1,64 @@
1
+<template>
2
+  <el-form :inline="true" :model="formData" class="filter-form">
3
+    <el-form-item label="日期">
4
+      <el-date-picker v-model="formData.startDate" type="date" placeholder="起始日期" value-format="yyyy-MM-dd" />
5
+    </el-form-item>
6
+    <el-form-item label="-">
7
+      <el-date-picker v-model="formData.endDate" type="date" placeholder="截止日期" value-format="yyyy-MM-dd" />
8
+    </el-form-item>
9
+    <el-form-item label="手机">
10
+      <el-input v-model="formData.phone" placeholder="手机" />
11
+    </el-form-item>
12
+    <el-form-item label="名称">
13
+      <el-input v-model="formData.name" placeholder="名称" />
14
+    </el-form-item>
15
+    <el-form-item label="推荐人手机">
16
+      <el-input v-model="formData.recPhone" placeholder="推荐人手机" />
17
+    </el-form-item>
18
+    <el-form-item label="推荐人名称">
19
+      <el-input v-model="formData.recName" placeholder="推荐人名称" />
20
+    </el-form-item>
21
+    <el-form-item style="margin-left: 36px">
22
+      <el-button type="primary" @click="handleSubmit">查询</el-button>
23
+      <el-button @click="handleReset">重置</el-button>
24
+    </el-form-item>
25
+  </el-form>
26
+</template>
27
+
28
+<script>
29
+export default {
30
+  data() {
31
+    return {
32
+      formData: {
33
+        phone: undefined,
34
+        name: undefined,
35
+        recPhone: undefined,
36
+        recName: undefined
37
+      }
38
+    }
39
+  },
40
+
41
+  methods: {
42
+    handleSubmit() {
43
+      this.$emit('search', this.formData)
44
+    },
45
+
46
+    handleReset() {
47
+      const def = Object.keys(this.formData).reduce((acc, key) => {
48
+        return {
49
+          ...acc,
50
+          [key]: undefined
51
+        }
52
+      }, {})
53
+      this.formData = def
54
+      this.$emit('reset', def)
55
+    }
56
+  }
57
+}
58
+</script>
59
+
60
+<style lang="scss" scoped>
61
+.filter-form {
62
+  padding: 16px 0;
63
+}
64
+</style>

+ 144
- 0
src/views/recommender/index.vue Целия файл

@@ -0,0 +1,144 @@
1
+<template>
2
+  <div class="app-container">
3
+    <div class="recommender-header">
4
+      <FilterForm @search="handleSearch" @reset="handleSearch" />
5
+      <el-tooltip content="导出" placement="top">
6
+        <el-button type="primary" icon="el-icon-position" @click="handleExport" />
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
19
+        type="index"
20
+        width="50"
21
+      />
22
+      <el-table-column label="时间">
23
+        <template slot-scope="scope">
24
+          {{ scope.row.createDate | toDayMini }}
25
+        </template>
26
+      </el-table-column>
27
+      <el-table-column label="手机" prop="phone" />
28
+      <el-table-column label="名称" prop="name" />
29
+      <el-table-column label="性别" align="center" width="200">
30
+        <template slot-scope="scope">
31
+          <el-tag
32
+            :type="scope.row.sex | sexTagFormat"
33
+            disable-transitions
34
+          >{{ scope.row.sex | sexFormat }}</el-tag>
35
+        </template>
36
+      </el-table-column>
37
+      <el-table-column label="推荐人手机" prop="recPhone" />
38
+      <el-table-column label="推荐人名称" prop="recName" />
39
+    </el-table>
40
+    <pagination
41
+      :total="page.total"
42
+      :size.sync="page.size"
43
+      :current.sync="page.current"
44
+      @change="handlePageChange"
45
+    />
46
+  </div>
47
+</template>
48
+
49
+<script>
50
+import { getRecommenderList } from '@/api/recommender'
51
+
52
+export default {
53
+  components: {
54
+    FilterForm: () => import('./components/FilterForm')
55
+  },
56
+
57
+  filters: {
58
+    sexFormat(sex) {
59
+      if (sex === null || sex === undefined) {
60
+        return undefined
61
+      }
62
+
63
+      const sexMap = [
64
+        '未知',
65
+        '男',
66
+        '女'
67
+      ]
68
+      return sexMap[sex]
69
+    },
70
+
71
+    sexTagFormat(sex) {
72
+      if (sex === null || sex === undefined) {
73
+        return undefined
74
+      }
75
+
76
+      const sexMap = [
77
+        'info',
78
+        'success',
79
+        'danger'
80
+      ]
81
+      return sexMap[sex]
82
+    }
83
+  },
84
+
85
+  data() {
86
+    return {
87
+      list: null,
88
+      listLoading: true,
89
+      page: {
90
+        total: 0,
91
+        size: 10,
92
+        current: 1
93
+      },
94
+      filters: {
95
+        pageNum: 1,
96
+        pageSize: 10
97
+      }
98
+    }
99
+  },
100
+  created() {
101
+    this.fetchData()
102
+  },
103
+  methods: {
104
+    fetchData() {
105
+      this.listLoading = true
106
+      getRecommenderList({
107
+        ...this.filters,
108
+        pageNum: this.page.current,
109
+        pageSize: this.page.size
110
+      }).then(res => {
111
+        this.list = res.records
112
+        this.page.total = res.total
113
+        this.listLoading = false
114
+      })
115
+    },
116
+
117
+    handleExport() {},
118
+
119
+    handlePageChange({ current, size }) {
120
+      this.page.current = current
121
+      this.page.size = size
122
+      this.fetchData()
123
+    },
124
+
125
+    handleSearch(searchParams) {
126
+      this.filters = {
127
+        ...this.filters,
128
+        ...searchParams,
129
+        pageNum: 1
130
+      }
131
+
132
+      this.fetchData()
133
+    }
134
+  }
135
+}
136
+</script>
137
+
138
+<style lang="scss" scoped>
139
+.recommender-header {
140
+  display: flex;
141
+  justify-content: space-between;
142
+  align-items: center;
143
+}
144
+</style>

+ 11
- 0
src/views/rights/letter/Detail.vue Целия файл

@@ -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/news/Detail')
9
+  }
10
+}
11
+</script>

+ 11
- 0
src/views/rights/letter/index.vue Целия файл

@@ -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/news/List')
9
+  }
10
+}
11
+</script>

+ 11
- 0
src/views/rights/seasons/Detail.vue Целия файл

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

+ 11
- 0
src/views/rights/seasons/index.vue Целия файл

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

+ 0
- 79
src/views/table/index.vue Целия файл

@@ -1,79 +0,0 @@
1
-<template>
2
-  <div class="app-container">
3
-    <el-table
4
-      v-loading="listLoading"
5
-      :data="list"
6
-      element-loading-text="Loading"
7
-      border
8
-      fit
9
-      highlight-current-row
10
-    >
11
-      <el-table-column align="center" label="ID" width="95">
12
-        <template slot-scope="scope">
13
-          {{ scope.$index }}
14
-        </template>
15
-      </el-table-column>
16
-      <el-table-column label="Title">
17
-        <template slot-scope="scope">
18
-          {{ scope.row.title }}
19
-        </template>
20
-      </el-table-column>
21
-      <el-table-column label="Author" width="110" align="center">
22
-        <template slot-scope="scope">
23
-          <span>{{ scope.row.author }}</span>
24
-        </template>
25
-      </el-table-column>
26
-      <el-table-column label="Pageviews" width="110" align="center">
27
-        <template slot-scope="scope">
28
-          {{ scope.row.pageviews }}
29
-        </template>
30
-      </el-table-column>
31
-      <el-table-column class-name="status-col" label="Status" width="110" align="center">
32
-        <template slot-scope="scope">
33
-          <el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag>
34
-        </template>
35
-      </el-table-column>
36
-      <el-table-column align="center" prop="created_at" label="Display_time" width="200">
37
-        <template slot-scope="scope">
38
-          <i class="el-icon-time" />
39
-          <span>{{ scope.row.display_time }}</span>
40
-        </template>
41
-      </el-table-column>
42
-    </el-table>
43
-  </div>
44
-</template>
45
-
46
-<script>
47
-import { getList } from '@/api/table'
48
-
49
-export default {
50
-  filters: {
51
-    statusFilter(status) {
52
-      const statusMap = {
53
-        published: 'success',
54
-        draft: 'gray',
55
-        deleted: 'danger'
56
-      }
57
-      return statusMap[status]
58
-    }
59
-  },
60
-  data() {
61
-    return {
62
-      list: null,
63
-      listLoading: true
64
-    }
65
-  },
66
-  created() {
67
-    this.fetchData()
68
-  },
69
-  methods: {
70
-    fetchData() {
71
-      this.listLoading = true
72
-      getList().then(response => {
73
-        this.list = response.data.items
74
-        this.listLoading = false
75
-      })
76
-    }
77
-  }
78
-}
79
-</script>

+ 0
- 78
src/views/tree/index.vue Целия файл

@@ -1,78 +0,0 @@
1
-<template>
2
-  <div class="app-container">
3
-    <el-input v-model="filterText" placeholder="Filter keyword" style="margin-bottom:30px;" />
4
-
5
-    <el-tree
6
-      ref="tree2"
7
-      :data="data2"
8
-      :props="defaultProps"
9
-      :filter-node-method="filterNode"
10
-      class="filter-tree"
11
-      default-expand-all
12
-    />
13
-
14
-  </div>
15
-</template>
16
-
17
-<script>
18
-export default {
19
-
20
-  data() {
21
-    return {
22
-      filterText: '',
23
-      data2: [{
24
-        id: 1,
25
-        label: 'Level one 1',
26
-        children: [{
27
-          id: 4,
28
-          label: 'Level two 1-1',
29
-          children: [{
30
-            id: 9,
31
-            label: 'Level three 1-1-1'
32
-          }, {
33
-            id: 10,
34
-            label: 'Level three 1-1-2'
35
-          }]
36
-        }]
37
-      }, {
38
-        id: 2,
39
-        label: 'Level one 2',
40
-        children: [{
41
-          id: 5,
42
-          label: 'Level two 2-1'
43
-        }, {
44
-          id: 6,
45
-          label: 'Level two 2-2'
46
-        }]
47
-      }, {
48
-        id: 3,
49
-        label: 'Level one 3',
50
-        children: [{
51
-          id: 7,
52
-          label: 'Level two 3-1'
53
-        }, {
54
-          id: 8,
55
-          label: 'Level two 3-2'
56
-        }]
57
-      }],
58
-      defaultProps: {
59
-        children: 'children',
60
-        label: 'label'
61
-      }
62
-    }
63
-  },
64
-  watch: {
65
-    filterText(val) {
66
-      this.$refs.tree2.filter(val)
67
-    }
68
-  },
69
-
70
-  methods: {
71
-    filterNode(value, data) {
72
-      if (!value) return true
73
-      return data.label.indexOf(value) !== -1
74
-    }
75
-  }
76
-}
77
-</script>
78
-