Commit 8a0e4eede07d9836ba6ec1ead345155edcab531d

Authored by BigBoss
1 parent fc0d443bb7
Exists in master

产品列表页

1 import Mock from 'mockjs' 1 import Mock from 'mockjs'
2 // import logoPath from "~@/assets/img/yp_logo.jpeg" 2 // import logoPath from "~@/assets/img/yp_logo.jpeg"
3 3
4 const List = [] 4 const List = []
5 const count = 100 5 const count = 50
6 6
7 const baseContent = '<p>I am testing data, I am testing data.</p><p></p>' 7 const baseContent = '<p>I am testing data, I am testing data.</p><p></p>'
8 // const image_uri = logoPath 8 // const image_uri = logoPath
9 const image_uri = 'https://wpimg.wallstcn.com/360e4842-4db5-42d0-b078-f9a84a825546.gif' 9 const image_uri = 'https://wpimg.wallstcn.com/360e4842-4db5-42d0-b078-f9a84a825546.gif'
10 10
11 for (let i = 0; i < count; i++) { 11 for (let i = 0; i < count; i++) {
12 List.push(Mock.mock({ 12 List.push(Mock.mock({
13 id: '@increment', 13 id: '@increment',
14 timestamp: +Mock.Random.date('T'), 14 timestamp: +Mock.Random.date('T'),
15 author: '@first', 15 author: '@first',
16 reviewer: '@first', 16 reviewer: '@first',
17 title: '@title(5, 10)', 17 title: '@title(5, 10)',
18 content_short: 'mock data', 18 content_short: 'mock data',
19 content: baseContent, 19 content: baseContent,
20 forecast: '@float(0, 100, 2, 2)', 20 forecast: '@float(0, 100, 2, 2)',
21 importance: '@integer(1, 3)', 21 importance: '@integer(1, 3)',
22 'type|1': ['CN', 'US', 'JP', 'EU'], 22 'type|1': ['CN', 'US', 'JP', 'EU'],
23 'status|1': ['published', 'draft'], 23 'status|1': ['published', 'draft'],
24 display_time: '@datetime', 24 display_time: '@datetime',
25 comment_disabled: true, 25 comment_disabled: true,
26 pageviews: '@integer(300, 5000)', 26 pageviews: '@integer(300, 5000)',
27 image_uri, 27 image_uri,
28 platforms: ['a-platform'] 28 platforms: ['a-platform']
29 })) 29 }))
30 } 30 }
31 31
32 export default [{ 32 export default [{
33 url: '/yp/article/list', 33 url: '/yp/article/list',
34 type: 'get', 34 type: 'get',
35 response: config => { 35 response: config => {
36 const { 36 const {
37 importance, 37 importance,
38 type, 38 type,
39 title, 39 title,
40 page = 1, 40 page = 1,
41 limit = 20, 41 limit = 20,
42 sort 42 sort
43 } = config.query 43 } = config.query
44 44
45 let mockList = List.filter(item => { 45 let mockList = List.filter(item => {
46 if (importance && item.importance !== +importance) return false 46 if (importance && item.importance !== +importance) return false
47 if (type && item.type !== type) return false 47 if (type && item.type !== type) return false
48 if (title && item.title.indexOf(title) < 0) return false 48 if (title && item.title.indexOf(title) < 0) return false
49 return true 49 return true
50 }) 50 })
51 51
52 if (sort === '-id') { 52 if (sort === '-id') {
53 mockList = mockList.reverse() 53 mockList = mockList.reverse()
54 } 54 }
55 55
56 const pageList = mockList.filter((item, index) => index < limit * page && index >= limit * (page - 1)) 56 const pageList = mockList.filter((item, index) => index < limit * page && index >= limit * (page - 1))
57 57
58 return { 58 return {
59 code: 20000, 59 code: 20000,
60 data: { 60 data: {
61 total: mockList.length, 61 total: mockList.length,
62 items: pageList 62 items: pageList
63 } 63 }
64 } 64 }
65 } 65 }
66 }, 66 },
67 67
68 { 68 {
69 url: '/yp/article/detail', 69 url: '/yp/article/detail',
70 type: 'get', 70 type: 'get',
71 response: config => { 71 response: config => {
72 const { 72 const {
73 id 73 id
74 } = config.query 74 } = config.query
75 for (const article of List) { 75 for (const article of List) {
76 if (article.id === +id) { 76 if (article.id === +id) {
77 return { 77 return {
78 code: 20000, 78 code: 20000,
79 data: article 79 data: article
80 } 80 }
81 } 81 }
82 } 82 }
83 } 83 }
84 }, 84 },
85 85
86 { 86 {
87 url: '/yp/article/pv', 87 url: '/yp/article/pv',
88 type: 'get', 88 type: 'get',
89 response: _ => { 89 response: _ => {
90 return { 90 return {
91 code: 20000, 91 code: 20000,
92 data: { 92 data: {
93 pvData: [{ 93 pvData: [{
94 key: 'PC', 94 key: 'PC',
95 pv: 1024 95 pv: 1024
96 }, 96 },
97 { 97 {
98 key: 'mobile', 98 key: 'mobile',
99 pv: 1024 99 pv: 1024
100 }, 100 },
101 { 101 {
102 key: 'ios', 102 key: 'ios',
103 pv: 1024 103 pv: 1024
104 }, 104 },
105 { 105 {
106 key: 'android', 106 key: 'android',
107 pv: 1024 107 pv: 1024
108 } 108 }
109 ] 109 ]
110 } 110 }
111 } 111 }
112 } 112 }
113 }, 113 },
114 114
115 { 115 {
116 url: '/yp/article/create', 116 url: '/yp/article/create',
117 type: 'post', 117 type: 'post',
118 response: _ => { 118 response: _ => {
119 return { 119 return {
120 code: 20000, 120 code: 20000,
121 data: 'success' 121 data: 'success'
122 } 122 }
123 } 123 }
124 }, 124 },
125 125
126 { 126 {
127 url: '/yp/article/update', 127 url: '/yp/article/update',
128 type: 'post', 128 type: 'post',
129 response: _ => { 129 response: _ => {
130 return { 130 return {
131 code: 20000, 131 code: 20000,
132 data: 'success' 132 data: 'success'
133 } 133 }
134 } 134 }
135 } 135 }
136 ] 136 ]
137 137
src/views/application/appList.vue
1 <template> 1 <template>
2 <el-container style="height: 853px; border: 1px solid #eee"> 2 <el-container style="height: 853px; border: 1px solid #eee">
3 <el-aside width="250px" style="background-color: rgb(238, 241, 246)"> 3 <el-aside width="250px" style="background-color: rgb(238, 241, 246)">
4 <el-menu :default-openeds="['1','2', '3']"> 4 <el-menu :default-openeds="['1','2', '3']">
5 <el-submenu index="1"> 5 <el-submenu index="1">
6 <template slot="title"><i class="el-icon-message" />非常戴镜</template> 6 <template slot="title"><i class="el-icon-message" />非常戴镜</template>
7 <el-menu-item v-for="(item,i) in nav_menu_data" :key="i" :index="item.name">{{ item.title }}</el-menu-item> 7 <el-menu-item v-for="(item,i) in nav_menu_data" :key="i" :index="item.name">{{ item.title }}</el-menu-item>
8 </el-submenu> 8 </el-submenu>
9 <el-submenu index="2"> 9 <el-submenu index="2">
10 <template slot="title"><i class="el-icon-menu" />亚当光学</template> 10 <template slot="title"><i class="el-icon-menu" />亚当光学</template>
11 <el-menu-item index="2-1">产品列表</el-menu-item> 11 <el-menu-item index="2-1">产品列表</el-menu-item>
12 <el-menu-item index="2-2">订单列表</el-menu-item> 12 <el-menu-item index="2-2">订单列表</el-menu-item>
13 <el-menu-item index="2-3">用户列表</el-menu-item> 13 <el-menu-item index="2-3">用户列表</el-menu-item>
14 <el-menu-item index="2-4">运行分析</el-menu-item> 14 <el-menu-item index="2-4">运行分析</el-menu-item>
15 </el-submenu> 15 </el-submenu>
16 <el-submenu index="3"> 16 <el-submenu index="3">
17 <template slot="title"><i class="el-icon-setting" />秀野光学</template> 17 <template slot="title"><i class="el-icon-setting" />秀野光学</template>
18 <el-menu-item index="3-1">产品列表</el-menu-item> 18 <el-menu-item index="3-1">产品列表</el-menu-item>
19 <el-menu-item index="3-2">订单列表</el-menu-item> 19 <el-menu-item index="3-2">订单列表</el-menu-item>
20 <el-menu-item index="3-3">用户列表</el-menu-item> 20 <el-menu-item index="3-3">用户列表</el-menu-item>
21 <el-menu-item index="3-4">运行分析</el-menu-item> 21 <el-menu-item index="3-4">运行分析</el-menu-item>
22 </el-submenu> 22 </el-submenu>
23 </el-menu> 23 </el-menu>
24 </el-aside> 24 </el-aside>
25 25
26 <el-container> 26 <el-container>
27 <el-header style="text-align: center; font-size: 24px"> 27 <el-header style="text-align: center; font-size: 24px">
28 <span>这里的title</span> 28 <span>这里的title</span>
29 </el-header> 29 </el-header>
30 30
31 <el-main> 31 <el-main>
32 <el-tabs v-model="activeName" tab-position="top" @tab-click="handleClick"> 32 <el-tabs v-model="activeName" tab-position="top" @tab-click="handleClick">
33 <el-tab-pane label="产品列表" name="first"> 33 <el-tab-pane label="产品列表" name="first">
34 <el-table :data="prodListTableData" stripe> 34 <el-table :data="prodListTableData" stripe>
35 <el-table-column prop="prodInfo" label="产品信息" width="340" /> 35 <el-table-column prop="prodInfo" label="产品信息" width="340" />
36 <el-table-column prop="prodTag" label="产品标签" width="340" /> 36 <el-table-column prop="prodTag" label="产品标签" width="340" />
37 <el-table-column prop="stock" label="库存" width="340" /> 37 <el-table-column prop="stock" label="库存" width="340" />
38 <el-table-column label="操作"> 38 <el-table-column label="操作">
39 <el-button type="text">从应用中删除</el-button> 39 <el-button type="text">从应用中删除</el-button>
40 </el-table-column> 40 </el-table-column>
41 </el-table> 41 </el-table>
42 </el-tab-pane> 42 </el-tab-pane>
43 <el-tab-pane label="订单列表" name="second"> 43 <el-tab-pane label="订单列表" name="second">
44 <el-table :data="prodListTableData" stripe> 44 <el-table :data="prodListTableData" stripe>
45 <el-table-column prop="prodInfo" label="下单时间" width="220" /> 45 <el-table-column prop="prodInfo" label="下单时间" width="220" />
46 <el-table-column prop="prodTag" label="金额" width="220" /> 46 <el-table-column prop="prodTag" label="金额" width="220" />
47 <el-table-column prop="stock" label="产品id" width="220" /> 47 <el-table-column prop="stock" label="产品id" width="220" />
48 <el-table-column prop="stock" label="订单号" width="220" /> 48 <el-table-column prop="stock" label="订单号" width="220" />
49 <el-table-column prop="stock" label="状态" width="220" /> 49 <el-table-column prop="stock" label="状态" width="220" />
50 <el-table-column label="操作"> 50 <el-table-column label="操作">
51 <el-button type="text">从应用中删除</el-button> 51 <el-button type="text">从应用中删除</el-button>
52 </el-table-column> 52 </el-table-column>
53 </el-table> 53 </el-table>
54 </el-tab-pane> 54 </el-tab-pane>
55 <el-tab-pane label="用户列表" name="third"> 55 <el-tab-pane label="用户列表" name="third">
56 <el-table :data="prodListTableData" stripe> 56 <el-table :data="prodListTableData" stripe>
57 <el-table-column prop="prodInfo" label="用户id" width="180" /> 57 <el-table-column prop="prodInfo" label="用户id" width="180" />
58 <el-table-column prop="prodTag" label="加入时间" width="180" /> 58 <el-table-column prop="prodTag" label="加入时间" width="180" />
59 <el-table-column prop="stock" label="引流人" width="180" /> 59 <el-table-column prop="stock" label="引流人" width="180" />
60 <el-table-column prop="stock" label="引流渠道" width="180" /> 60 <el-table-column prop="stock" label="引流渠道" width="180" />
61 <el-table-column prop="stock" label="消费额度" width="180" /> 61 <el-table-column prop="stock" label="消费额度" width="180" />
62 <el-table-column prop="stock" label="访问时长" width="180" /> 62 <el-table-column prop="stock" label="访问时长" width="180" />
63 <el-table-column prop="stock" label="带来流量" width="180" /> 63 <el-table-column prop="stock" label="带来流量" width="180" />
64 <el-table-column label="操作"> 64 <el-table-column label="操作">
65 <el-button type="text">从应用中删除</el-button> 65 <el-button type="text">从应用中删除</el-button>
66 </el-table-column> 66 </el-table-column>
67 </el-table> 67 </el-table>
68 </el-tab-pane> 68 </el-tab-pane>
69 <el-tab-pane label="运营分析" name="fourth"> 69 <el-tab-pane label="运营分析" name="fourth">
70 <el-table :data="prodListTableData" stripe> 70 <el-table :data="prodListTableData" stripe>
71 <el-table-column prop="prodInfo" label="产品信息" width="340" /> 71 <el-table-column prop="prodInfo" label="产品信息" width="340" />
72 <el-table-column prop="prodTag" label="产品标签" width="340" /> 72 <el-table-column prop="prodTag" label="产品标签" width="340" />
73 <el-table-column prop="stock" label="库存" width="340" /> 73 <el-table-column prop="stock" label="库存" width="340" />
74 <el-table-column label="操作"> 74 <el-table-column label="操作">
75 <el-button type="text">从应用中删除</el-button> 75 <el-button type="text">从应用中删除</el-button>
76 </el-table-column> 76 </el-table-column>
77 </el-table> 77 </el-table>
78 </el-tab-pane> 78 </el-tab-pane>
79 </el-tabs> 79 </el-tabs>
80 </el-main> 80 </el-main>
81 </el-container> 81 </el-container>
82 </el-container> 82 </el-container>
83 83
84 </template> 84 </template>
85 85
86 <script> 86 <script>
87 export default { 87 export default {
88 data() { 88 data() {
89 return { 89 return {
90 activeName: 'second', 90 activeName: 'second',
91 path: '', 91 path: '',
92 nav_menu_data: [{ 92 nav_menu_data: [{
93 title: '产品列表', 93 title: '产品列表',
94 path: '/Menu/appList' 94 name: 'appList'
95 }, { 95 }, {
96 title: '订单列表', 96 title: '订单列表',
97 path: '/Menu/orderList' 97 name: 'orderList'
98 }, { 98 }, {
99 title: '用户列表', 99 title: '用户列表',
100 path: '/Menu/userList' 100 name: 'userList'
101 }, { 101 }, {
102 title: '运营分析', 102 title: '运营分析',
103 path: '/Menu/analys' 103 name: 'analys'
104 }], 104 }],
105 prodListTableData: [{ 105 prodListTableData: [{
106 prodInfo: 'pic', 106 prodInfo: 'pic',
107 prodTag: '非常带劲', 107 prodTag: '非常带劲',
108 stock: '102' 108 stock: '102'
109 }, 109 },
110 { 110 {
111 prodInfo: 'pic', 111 prodInfo: 'pic',
112 prodTag: '非常带劲', 112 prodTag: '非常带劲',
113 stock: '4531' 113 stock: '4531'
114 }, 114 },
115 { 115 {
116 prodInfo: 'pic', 116 prodInfo: 'pic',
117 prodTag: '非常带劲', 117 prodTag: '非常带劲',
118 stock: '531' 118 stock: '531'
119 }, 119 },
120 { 120 {
121 prodInfo: 'pic', 121 prodInfo: 'pic',
122 prodTag: '非常带劲', 122 prodTag: '非常带劲',
123 stock: '768' 123 stock: '768'
124 }] 124 }]
125 } 125 }
126 }, 126 },
127 watch: { 127 watch: {
128 }, 128 },
129 created() { 129 created() {
130 }, 130 },
131 method: { 131 method: {
132 onRouteChanged() { 132 onRouteChanged() {
133 const that = this 133 const that = this
134 that.path = that.$route.path 134 that.path = that.$route.path
135 }, 135 },
136 handleClick(tab, event) { 136 handleClick(tab, event) {
137 console.log(tab, event) 137 console.log(tab, event)
138 } 138 }
139 } 139 }
140 } 140 }
141 141
142 </script> 142 </script>
143 143
144 <style> 144 <style>
145 .el-header { 145 .el-header {
146 background-color: #B3C0D1; 146 background-color: #B3C0D1;
147 color: #333; 147 color: #333;
148 line-height: 60px; 148 line-height: 60px;
149 } 149 }
150 150
151 .el-aside { 151 .el-aside {
152 color: #333; 152 color: #333;
153 } 153 }
154 </style> 154 </style>
155 155
src/views/prod/list.vue
1 <template> 1 <template>
2 <div class="app-container"> 2 <div class="app-container">
3 <div class="filter-container">
4 <!-- 搜索input -->
5 <el-input
6 v-model="listQuery.title"
7 :placeholder="$t('table.title')"
8 style="width: 200px;"
9 class="filter-item"
10 @keyup.enter.native="handleFilter"
11 />
12 <!-- type选择 -->
13 <el-select
14 v-model="listQuery.type"
15 :placeholder="$t('table.type')"
16 clearable
17 class="filter-item"
18 style="width: 110px"
19 >
20 <el-option
21 v-for="item in calendarTypeOptions"
22 :key="item.key"
23 :label="item.display_name"
24 :value="item.key"
25 />
26 </el-select>
27
28 <!-- imp选择 -->
29 <el-select
30 v-model="listQuery.importance"
31 :placeholder="$t('table.importance')"
32 clearable
33 filterable
34 style="width: 130px"
35 class="filter-item"
36 >
37 <!-- 分组tag筛选 -->
38 <el-option-group
39 v-for="group in importanceOptions"
40 :key="group.label"
41 :label="group.label"
42 >
43 <el-option
44 v-for="item in group.options"
45 :key="item.value"
46 :label="item.label"
47 :value="item.value"
48 />
49 </el-option-group>
50 </el-select>
51 <!-- 排序 -->
52 <el-select
53 v-model="listQuery.sort"
54 style="width: 140px"
55 class="filter-item"
56 @change="handleFilter"
57 >
58 <el-option
59 v-for="item in sortOptions"
60 :key="item.key"
61 :label="item.label"
62 :value="item.key"
63 />
64 </el-select>
65 <!-- search按钮 -->
66 <el-button
67 v-waves
68 class="filter-item"
69 type="primary"
70 icon="el-icon-search"
71 @click="handleFilter"
72 >
73 {{ $t('table.search') }}
74 </el-button>
75 <!-- add按钮 -->
76 <el-button
77 class="filter-item"
78 style="margin-left: 10px;"
79 type="primary"
80 icon="el-icon-edit"
81 @click="handleCreate"
82 >
83 {{ $t('table.add') }}
84 </el-button>
85 <!-- 导出为excel按钮 -->
86 <el-button
87 v-waves
88 :loading="downloadLoading"
89 class="filter-item"
90 type="primary"
91 icon="el-icon-download"
92 @click="handleDownload"
93 >
94 {{ $t('table.export') }}
95 </el-button>
96 <!-- 是否显示审核人 -->
97 <el-checkbox
98 v-model="showReviewer"
99 class="filter-item"
100 style="margin-left:15px;"
101 @change="tableKey=tableKey+1"
102 >
103 {{ $t('table.reviewer') }}
104 </el-checkbox>
105 </div>
106
107 <!-- 表格 -->
3 <el-table 108 <el-table
109 :key="tableKey"
4 v-loading="listLoading" 110 v-loading="listLoading"
5 :data="list" 111 :data="list"
6 border 112 border
7 fit 113 fit
8 highlight-current-row 114 highlight-current-row
9 style="width: 100%" 115 style="width: 100%;"
116 @sort-change="sortChange"
10 > 117 >
118 <!-- id列 -->
11 <el-table-column 119 <el-table-column
120 :label="$t('table.id')"
121 prop="id"
122 sortable="custom"
12 align="center" 123 align="center"
13 label="ID"
14 width="80" 124 width="80"
125 :class-name="getSortClass('id')"
15 > 126 >
16 <template slot-scope="scope"> 127 <template slot-scope="{row}">
17 <span>{{ scope.row.id }}</span> 128 <span>{{ row.id }}</span>
18 </template> 129 </template>
19 </el-table-column> 130 </el-table-column>
20 131 <!-- date列 -->
21 <el-table-column 132 <el-table-column
22 width="180px" 133 :label="$t('table.date')"
134 width="150px"
23 align="center" 135 align="center"
24 label="Date"
25 > 136 >
26 <template slot-scope="scope"> 137 <template slot-scope="{row}">
27 <span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span> 138 <span>{{ row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
28 </template> 139 </template>
29 </el-table-column> 140 </el-table-column>
30 141 <!-- title列 -->
142 <el-table-column
143 :label="$t('table.title')"
144 min-width="150px"
145 >
146 <template slot-scope="{row}">
147 <span
148 class="link-type"
149 @click="handleUpdate(row)"
150 >{{ row.title }}</span>
151 <el-tag>{{ row.type | typeFilter }}</el-tag>
152 </template>
153 </el-table-column>
154 <!-- author列 -->
31 <el-table-column 155 <el-table-column
32 width="120px" 156 :label="$t('table.author')"
157 width="110px"
33 align="center" 158 align="center"
34 label="Author"
35 > 159 >
36 <template slot-scope="scope"> 160 <template slot-scope="{row}">
37 <span>{{ scope.row.author }}</span> 161 <span>{{ row.author }}</span>
162 </template>
163 </el-table-column>
164 <!-- reviewer列 -->
165 <el-table-column
166 v-if="showReviewer"
167 :label="$t('table.reviewer')"
168 width="110px"
169 align="center"
170 >
171 <template slot-scope="{row}">
172 <span style="color:red;">{{ row.reviewer }}</span>
38 </template> 173 </template>
39 </el-table-column> 174 </el-table-column>
40
41 <el-table-column 175 <el-table-column
42 width="100px" 176 :label="$t('table.importance')"
43 label="Importance" 177 width="80px"
44 > 178 >
45 <template slot-scope="scope"> 179 <template slot-scope="{row}">
46 <svg-icon 180 <svg-icon
47 v-for="n in +scope.row.importance" 181 v-for="n in +row.importance"
48 :key="n" 182 :key="n"
49 icon-class="star" 183 icon-class="star"
50 class="meta-item__icon" 184 class="meta-item__icon"
51 /> 185 />
52 </template> 186 </template>
53 </el-table-column> 187 </el-table-column>
54 188 <!-- 阅读数列 -->
55 <el-table-column 189 <el-table-column
56 class-name="status-col" 190 :label="$t('table.readings')"
57 label="Status" 191 align="center"
58 width="110" 192 width="95"
59 > 193 >
60 <template slot-scope="{row}"> 194 <template slot-scope="{row}">
61 <el-tag :type="row.status | statusFilter"> 195 <span
62 {{ row.status }} 196 v-if="row.pageviews"
63 </el-tag> 197 class="link-type"
198 @click="handleFetchPv(row.pageviews)"
199 >{{ row.pageviews }}</span>
200 <span v-else>0</span>
64 </template> 201 </template>
65 </el-table-column> 202 </el-table-column>
66 203
204 <!-- 状态列 -->
67 <el-table-column 205 <el-table-column
68 min-width="300px" 206 :label="$t('table.status')"
69 label="Title" 207 class-name="status-col"
208 width="100"
70 > 209 >
71 <template slot-scope="{row}"> 210 <template slot-scope="{row}">
72 <router-link 211 <el-tag :type="row.status | statusFilter">
73 :to="'/example/edit/'+row.id" 212 {{ row.status }}
74 class="link-type" 213 </el-tag>
75 >
76 <span>{{ row.title }}</span>
77 </router-link>
78 </template> 214 </template>
79 </el-table-column> 215 </el-table-column>
80 216 <!-- 操作列 -->
81 <el-table-column 217 <el-table-column
218 :label="$t('table.actions')"
82 align="center" 219 align="center"
83 label="Actions" 220 width="230"
84 width="120" 221 class-name="small-padding fixed-width"
85 > 222 >
86 <template slot-scope="scope"> 223 <template slot-scope="{row,$index}">
87 <router-link :to="'/example/edit/'+scope.row.id"> 224 <el-button
88 <el-button 225 type="primary"
89 type="primary" 226 size="mini"
90 size="small" 227 @click="handleUpdate(row)"
91 icon="el-icon-edit" 228 >
92 > 229 {{ $t('table.edit') }}
93 Edit 230 </el-button>
94 </el-button> 231 <el-button
95 </router-link> 232 v-if="row.status!='published'"
233 size="mini"
234 type="success"
235 @click="handleModifyStatus(row,'published')"
236 >
237 {{ $t('table.publish') }}
238 </el-button>
239 <el-button
240 v-if="row.status!='draft'"
241 size="mini"
242 @click="handleModifyStatus(row,'draft')"
243 >
244 {{ $t('table.draft') }}
245 </el-button>
246 <el-button
247 v-if="row.status!='deleted'"
248 size="mini"
249 type="danger"
250 @click="handleDelete(row,$index)"
251 >
252 {{ $t('table.delete') }}
253 </el-button>
96 </template> 254 </template>
97 </el-table-column> 255 </el-table-column>
98 </el-table> 256 </el-table>
99 257
258 <!-- 分页器 -->
100 <pagination 259 <pagination
101 v-show="total>0" 260 v-show="total>0"
102 :total="total" 261 :total="total"
103 :page.sync="listQuery.page" 262 :page.sync="listQuery.page"
104 :limit.sync="listQuery.limit" 263 :limit.sync="listQuery.limit"
105 @pagination="getList" 264 @pagination="getList"
106 /> 265 />
266
267 <el-dialog
268 :title="textMap[dialogStatus]"
269 :visible.sync="dialogFormVisible"
270 >
271 <el-form
272 ref="dataForm"
273 :rules="rules"
274 :model="temp"
275 label-position="left"
276 label-width="70px"
277 style="width: 400px; margin-left:50px;"
278 >
279 <el-form-item
280 :label="$t('table.type')"
281 prop="type"
282 >
283 <el-select
284 v-model="temp.type"
285 class="filter-item"
286 placeholder="Please select"
287 >
288 <el-option
289 v-for="item in calendarTypeOptions"
290 :key="item.key"
291 :label="item.display_name"
292 :value="item.key"
293 />
294 </el-select>
295 </el-form-item>
296 <el-form-item
297 :label="$t('table.date')"
298 prop="timestamp"
299 >
300 <el-date-picker
301 v-model="temp.timestamp"
302 type="datetime"
303 placeholder="Please pick a date"
304 />
305 </el-form-item>
306 <el-form-item
307 :label="$t('table.title')"
308 prop="title"
309 >
310 <el-input v-model="temp.title" />
311 </el-form-item>
312 <el-form-item :label="$t('table.status')">
313 <el-select
314 v-model="temp.status"
315 class="filter-item"
316 placeholder="Please select"
317 >
318 <el-option
319 v-for="item in statusOptions"
320 :key="item"
321 :label="item"
322 :value="item"
323 />
324 </el-select>
325 </el-form-item>
326 <el-form-item :label="$t('table.importance')">
327 <el-rate
328 v-model="temp.importance"
329 :colors="['#99A9BF', '#F7BA2A', '#FF9900']"
330 :max="3"
331 style="margin-top:8px;"
332 />
333 </el-form-item>
334 <el-form-item :label="$t('table.remark')">
335 <el-input
336 v-model="temp.remark"
337 :autosize="{ minRows: 2, maxRows: 4}"
338 type="textarea"
339 placeholder="Please input"
340 />
341 </el-form-item>
342 </el-form>
343 <div
344 slot="footer"
345 class="dialog-footer"
346 >
347 <el-button @click="dialogFormVisible = false">
348 {{ $t('table.cancel') }}
349 </el-button>
350 <el-button
351 type="primary"
352 @click="dialogStatus==='create'?createData():updateData()"
353 >
354 {{ $t('table.confirm') }}
355 </el-button>
356 </div>
357 </el-dialog>
358
359 <el-dialog
360 :visible.sync="dialogPvVisible"
361 title="Reading statistics"
362 >
363 <el-table
364 :data="pvData"
365 border
366 fit
367 highlight-current-row
368 style="width: 100%"
369 >
370 <el-table-column
371 prop="key"
372 label="Channel"
373 />
374 <el-table-column
375 prop="pv"
376 label="Pv"
377 />
378 </el-table>
379 <span
380 slot="footer"
381 class="dialog-footer"
382 >
383 <el-button
384 type="primary"
385 @click="dialogPvVisible = false"
386 >{{ $t('table.confirm') }}</el-button>
387 </span>
388 </el-dialog>
107 </div> 389 </div>
108 </template> 390 </template>
109 391
110 <script> 392 <script>
111 import { fetchList } from '@/api/article' 393 import {
112 import Pagination from '@/components/Pagination' // Secondary package based on el-pagination 394 fetchList,
395 fetchPv,
396 createArticle,
397 updateArticle
398 } from '@/api/article'
399 import waves from '@/directive/waves' // waves directive
400 import { parseTime } from '@/utils'
401 import Pagination from '@/components/Pagination' // secondary package based on el-pagination
402
403 const calendarTypeOptions = [
404 { key: 'CN', display_name: '成镜' },
405 { key: 'US', display_name: '镜片' },
406 { key: 'JP', display_name: '隐形眼镜' },
407 { key: 'EU', display_name: '特种镜' }
408 ]
409
410 // arr to obj, such as { CN : "China", US : "USA" }
411 const calendarTypeKeyValue = calendarTypeOptions.reduce((acc, cur) => {
412 acc[cur.key] = cur.display_name
413 return acc
414 }, {})
113 415
114 export default { 416 export default {
115 name: 'ArticleList', 417 name: 'ComplexTable',
116 components: { Pagination }, 418 components: { Pagination },
419 directives: { waves },
117 filters: { 420 filters: {
118 statusFilter(status) { 421 statusFilter(status) {
119 const statusMap = { 422 const statusMap = {
120 published: 'success', 423 published: 'success',
121 draft: 'info', 424 draft: 'info',
122 deleted: 'danger' 425 deleted: 'danger'
123 } 426 }
124 return statusMap[status] 427 return statusMap[status]
428 },
429 typeFilter(type) {
430 return calendarTypeKeyValue[type]
125 } 431 }
126 }, 432 },
127 data() { 433 data() {
128 return { 434 return {
435 tableKey: 0,
129 list: null, 436 list: null,
130 total: 0, 437 total: 0,
131 listLoading: true, 438 listLoading: true,
132 listQuery: { 439 listQuery: {
133 page: 1, 440 page: 1,
134 limit: 20 441 limit: 20,
135 } 442 importance: undefined,
443 title: undefined,
444 type: undefined,
445 sort: '+id'
446 },
447 importanceOptions: [{
448 label: '款式索引',
449 options: [{
450 value: 'young',
451 label: '青春学子风'
452 }, {
453 value: 'leisure',
454 label: '休闲'
455 }, {
456 value: 'business',
457 label: '商务'
458 }, {
459 value: 'Retro',
460 label: '复古'
461 }, {
462 value: 'fashion',
463 label: '时尚'
464 }]
465 }, {
466 label: '颜色',
467 options: [{
468 value: 'golden',
469 label: '金色'
470 }, {
471 value: 'silver',
472 label: '银色'
473 }, {
474 value: 'black',
475 label: '黑色'
476 }, {
477 value: 'multicolour',
478 label: '彩色'
479 }, {
480 value: 'gun',
481 label: '枪色'
482 }]
483 }],
484 calendarTypeOptions,
485 sortOptions: [
486 { label: 'ID Ascending', key: '+id' },
487 { label: 'ID Descending', key: '-id' }
488 ],
489 statusOptions: ['published', 'draft', 'deleted'],
490 showReviewer: false,
491 temp: {
492 id: undefined,
493 importance: 1,
494 remark: '',
495 timestamp: new Date(),
496 title: '',
497 type: '',
498 status: 'published'
499 },
500 dialogFormVisible: false,
501 dialogStatus: '',
502 textMap: {
503 update: 'Edit',
504 create: 'Create'
505 },
506 dialogPvVisible: false,
507 pvData: [],
508 rules: {
509 type: [
510 { required: true, message: 'type is required', trigger: 'change' }
511 ],
512 timestamp: [
513 {
514 type: 'date',
515 required: true,
516 message: 'timestamp is required',
517 trigger: 'change'
518 }
519 ],
520 title: [
521 { required: true, message: 'title is required', trigger: 'blur' }
522 ]
523 },
524 downloadLoading: false
136 } 525 }
137 }, 526 },
138 created() { 527 created() {
139 this.getList() 528 this.getList()
140 }, 529 },
141 methods: { 530 methods: {
142 getList() { 531 getList() {
143 this.listLoading = true 532 this.listLoading = true
144 fetchList(this.listQuery).then(response => { 533 fetchList(this.listQuery).then(response => {
145 this.list = response.data.items 534 this.list = response.data.items
146 this.total = response.data.total 535 this.total = response.data.total
147 this.listLoading = false 536
537 // Just to simulate the time of the request
538 setTimeout(() => {
539 this.listLoading = false
540 }, 1.5 * 1000)
541 })
542 },
543 handleFilter() {
544 this.listQuery.page = 1
545 this.getList()
546 },
547 handleModifyStatus(row, status) {
548 this.$message({
549 message: '操作成功',
550 type: 'success'
551 })
552 row.status = status
553 },
554 sortChange(data) {
555 const { prop, order } = data
556 if (prop === 'id') {
557 this.sortByID(order)
558 }
559 },
560 sortByID(order) {
561 if (order === 'ascending') {
562 this.listQuery.sort = '+id'
563 } else {
564 this.listQuery.sort = '-id'
565 }
566 this.handleFilter()
567 },
568 resetTemp() {
569 this.temp = {
570 id: undefined,
571 importance: 1,
572 remark: '',
573 timestamp: new Date(),
574 title: '',
575 status: 'published',
576 type: ''
577 }
578 },
579 handleCreate() {
580 this.resetTemp()
581 this.dialogStatus = 'create'
582 this.dialogFormVisible = true
583 this.$nextTick(() => {
584 this.$refs['dataForm'].clearValidate()
148 }) 585 })
586 },
587 createData() {
588 this.$refs['dataForm'].validate(valid => {
589 if (valid) {
590 this.temp.id = parseInt(Math.random() * 100) + 1024 // mock a id
591 this.temp.author = '秀野堂主'
592 createArticle(this.temp).then(() => {
593 this.list.unshift(this.temp)
594 this.dialogFormVisible = false
595 this.$notify({
596 title: '成功',
597 message: '创建成功',
598 type: 'success',
599 duration: 2000
600 })
601 })
602 }
603 })
604 },
605 handleUpdate(row) {
606 this.temp = Object.assign({}, row) // copy obj
607 this.temp.timestamp = new Date(this.temp.timestamp)
608 this.dialogStatus = 'update'
609 this.dialogFormVisible = true
610 this.$nextTick(() => {
611 this.$refs['dataForm'].clearValidate()
612 })
613 },
614 updateData() {
615 this.$refs['dataForm'].validate(valid => {
616 if (valid) {
617 const tempData = Object.assign({}, this.temp)
618 tempData.timestamp = +new Date(tempData.timestamp) // change Thu Nov 30 2017 16:41:05 GMT+0800 (CST) to 1512031311464
619 updateArticle(tempData).then(() => {
620 const index = this.list.findIndex(v => v.id === this.temp.id)
621 this.list.splice(index, 1, this.temp)
622 this.dialogFormVisible = false
623 this.$notify({
624 title: '成功',
625 message: '更新成功',
626 type: 'success',
627 duration: 2000
628 })
629 })
630 }
631 })
632 },
633 handleDelete(row, index) {
634 this.$notify({
635 title: '成功',
636 message: '删除成功',
637 type: 'success',
638 duration: 2000
639 })
640 this.list.splice(index, 1)
641 },
642 handleFetchPv(pv) {
643 fetchPv(pv).then(response => {
644 this.pvData = response.data.pvData
645 this.dialogPvVisible = true
646 })
647 },
648 handleDownload() {
649 this.downloadLoading = true
650 import('@/vendor/Export2Excel').then(excel => {
651 const tHeader = ['timestamp', 'title', 'type', 'importance', 'status']
652 const filterVal = [
653 'timestamp',
654 'title',
655 'type',
656 'importance',
657 'status'
658 ]
659 const data = this.formatJson(filterVal)
660 excel.export_json_to_excel({
661 header: tHeader,
662 data,
663 filename: 'table-list'
664 })
665 this.downloadLoading = false
666 })
667 },
668 formatJson(filterVal) {
669 return this.list.map(v =>
670 filterVal.map(j => {
671 if (j === 'timestamp') {
672 return parseTime(v[j])
673 } else {
674 return v[j]
675 }
676 })
677 )
678 },
679 getSortClass: function(key) {