Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
jinli gu
Springboot Plus
Commits
a30f21ad
Commit
a30f21ad
authored
Oct 12, 2019
by
zengchao
Browse files
-
parent
ab4da671
Changes
6
Hide whitespace changes
Inline
Side-by-side
ve-admin/admin-web/src/components/Pagination/index.vue
View file @
a30f21ad
<!--
* @Author: 一日看尽长安花
* @since: 2019-09-09 12:16:28
* @LastEditTime: 2019-09-09 12:16:28
* @LastEditors: 一日看尽长安花
* @Description:
-->
<
template
>
<div
:class=
"
{
'
hidden
'
:hidden}" class="pagination-container">
<div
:class=
"
{
hidden:
hidden
}" class="pagination-container">
<el-pagination
:background=
"background"
:current-page.sync=
"currentPage"
...
...
@@ -15,7 +22,7 @@
</
template
>
<
script
>
import
{
scrollTo
}
from
'
@/utils/scroll-to
'
import
{
scrollTo
}
from
'
@/utils/scroll-to
'
;
export
default
{
name
:
'
Pagination
'
,
...
...
@@ -35,7 +42,7 @@ export default {
pageSizes
:
{
type
:
Array
,
default
()
{
return
[
10
,
20
,
30
,
50
]
return
[
10
,
20
,
30
,
50
]
;
}
},
layout
:
{
...
...
@@ -56,38 +63,38 @@ export default {
}
},
computed
:
{
currentPage
:
{
currentPag
g
e
:
{
get
()
{
return
this
.
page
return
this
.
page
;
},
set
(
val
)
{
this
.
$emit
(
'
update:page
'
,
val
)
this
.
$emit
(
'
update:page
'
,
val
)
;
}
},
pageSize
:
{
get
()
{
return
this
.
limit
return
this
.
limit
;
},
set
(
val
)
{
this
.
$emit
(
'
update:limit
'
,
val
)
this
.
$emit
(
'
update:limit
'
,
val
)
;
}
}
},
methods
:
{
handleSizeChange
(
val
)
{
this
.
$emit
(
'
pagination
'
,
{
page
:
this
.
currentPage
,
limit
:
val
})
this
.
$emit
(
'
pagination
'
,
{
page
:
this
.
currentPage
,
limit
:
val
})
;
if
(
this
.
autoScroll
)
{
scrollTo
(
0
,
800
)
scrollTo
(
0
,
800
)
;
}
},
handleCurrentChange
(
val
)
{
this
.
$emit
(
'
pagination
'
,
{
page
:
val
,
limit
:
this
.
pageSize
})
this
.
$emit
(
'
pagination
'
,
{
page
:
val
,
limit
:
this
.
pageSize
})
;
if
(
this
.
autoScroll
)
{
scrollTo
(
0
,
800
)
scrollTo
(
0
,
800
)
;
}
}
}
}
}
;
</
script
>
<
style
scoped
>
...
...
ve-admin/admin-web/src/store/modules/permission.js
View file @
a30f21ad
/*
* @Description: In User Settings Edit
* @Author: your name
* @Date: 2019-09-09 12:16:28
* @LastEditTime: 2019-09-09 12:16:28
* @LastEditors: your name
*/
import
{
constantRoutes
}
from
'
@/router
'
;
import
{
getRoutes
}
from
'
@/api/role
'
;
import
{
default
as
asyncRoutesMap
}
from
'
@/router/maps/index
'
;
import
{
deepClone
,
objectMerge
,
isNotNullAndNotUndefined
,
}
from
'
@/utils/index
'
;
import
{
deepClone
,
objectMerge
}
from
'
@/utils/index
'
;
import
{
isExists
,
isNotExists
}
from
'
@/utils/object-util
'
;
/**
* Use meta.role to determine if the current user has permission
...
...
@@ -39,10 +43,10 @@ export function filterAsyncRoutes(routesMap, routes, roles) {
// 从前端路由表中选出与当前后端路由信息相对应的那条路由信息
for
(
let
rm
of
routesMap
)
{
if
(
is
NotNullAndNotUndefined
(
rm
.
name
)
&&
is
NotNullAndNotUndefined
(
route
.
name
)
&&
is
NotNullAndNotUndefined
(
rm
.
path
)
&&
is
NotNullAndNotUndefined
(
route
.
path
)
&&
is
Exists
(
rm
.
name
)
&&
is
Exists
(
route
.
name
)
&&
is
Exists
(
rm
.
path
)
&&
is
Exists
(
route
.
path
)
&&
(
rm
.
path
===
route
.
path
||
rm
.
name
===
route
.
name
)
)
{
// 优先path判断,是因为导航菜单的展开和收起是根据path判断的。
...
...
@@ -57,7 +61,7 @@ export function filterAsyncRoutes(routesMap, routes, roles) {
tempRoute
.
children
=
filterAsyncRoutes
(
tempRouteMap
.
children
,
tempRoute
.
children
,
roles
,
roles
);
}
// 以后台路由表优先,相同属性覆盖前台路由映射.除去路由路径交由前台控制
...
...
@@ -74,14 +78,14 @@ export function filterAsyncRoutes(routesMap, routes, roles) {
const
state
=
{
routes
:
[],
addRoutes
:
[]
,
addRoutes
:
[]
};
const
mutations
=
{
SET_ROUTES
:
(
state
,
routes
)
=>
{
state
.
addRoutes
=
routes
;
state
.
routes
=
constantRoutes
.
concat
(
routes
);
}
,
}
};
const
actions
=
{
...
...
@@ -95,7 +99,7 @@ const actions = {
accessedRoutes
=
filterAsyncRoutes
(
deepClone
(
asyncRoutesMap
),
asyncRoutes
,
roles
,
roles
);
accessedRoutes
.
push
({
path
:
'
*
'
,
redirect
:
'
/404
'
,
hidden
:
true
});
...
...
@@ -106,12 +110,12 @@ const actions = {
reject
(
error
);
});
});
}
,
}
};
export
default
{
namespaced
:
true
,
state
,
mutations
,
actions
,
actions
};
ve-admin/admin-web/src/utils/object-util.js
0 → 100644
View file @
a30f21ad
/*
* @Description: In User Settings Edit
* @Author: your name
* @Date: 2019-10-11 17:40:57
* @LastEditTime: 2019-10-12 09:24:07
* @LastEditors: Please set LastEditors
*/
/**
* @description: obj不存在。由于js存在undefined 和 null两种特殊的数据类型,认为从空间和引用指向上,只要有一个不存在则判断为不存在。
* @param {Object}
* @return {Boolean}
*/
export
function
isExists
(
obj
)
{
return
void
0
===
obj
||
null
===
obj
;
}
/**
* @description: obj存在
* @param {Object}
* @return {Boolean}
*/
export
function
isNotExists
(
obj
)
{
return
!
isExists
(
obj
);
}
ve-admin/admin-web/src/utils/request.js
View file @
a30f21ad
import
axios
from
'
axios
'
import
{
MessageBox
,
Message
}
from
'
element-ui
'
import
store
from
'
@/store
'
import
{
getToken
}
from
'
@/utils/auth
'
/*
* @Description: In User Settings Edit
* @Author: your name
* @Date: 2019-09-09 12:16:28
* @LastEditTime: 2019-09-09 12:16:28
* @LastEditors: your name
*/
import
axios
from
'
axios
'
;
import
{
MessageBox
,
Message
}
from
'
element-ui
'
;
import
store
from
'
@/store
'
;
import
{
getToken
}
from
'
@/utils/auth
'
;
// create an axios instance
const
service
=
axios
.
create
({
baseURL
:
process
.
env
.
VUE_APP_BASE_API
,
// url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests
timeout
:
5000
// request timeout
})
})
;
// request interceptor
service
.
interceptors
.
request
.
use
(
...
...
@@ -19,16 +26,16 @@ service.interceptors.request.use(
// let each request carry token
// ['Authorization'] see to MDN explain about "HTTP Authorization"
// please modify it according to the actual situation
config
.
headers
[
'
Authorization
'
]
=
getToken
()
config
.
headers
[
'
Authorization
'
]
=
getToken
()
;
}
return
config
return
config
;
},
error
=>
{
// do something with request error
console
.
log
(
'
request err =>
'
+
error
)
// for debug
return
Promise
.
reject
(
error
)
console
.
log
(
'
request err =>
'
+
error
)
;
// for debug
return
Promise
.
reject
(
error
)
;
}
)
)
;
// response interceptor
service
.
interceptors
.
response
.
use
(
...
...
@@ -43,7 +50,7 @@ service.interceptors.response.use(
* You can also judge the status by HTTP Status Code
*/
response
=>
{
const
res
=
response
.
data
const
res
=
response
.
data
;
// if the custom code is not 20000, it is judged as an error.
if
(
res
.
code
!==
200
)
{
...
...
@@ -51,7 +58,7 @@ service.interceptors.response.use(
message
:
res
.
message
||
'
Error
'
,
type
:
'
error
'
,
duration
:
5
*
1000
})
})
;
// 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
if
(
res
.
code
===
50008
||
res
.
code
===
50012
||
res
.
code
===
50014
)
{
...
...
@@ -66,24 +73,24 @@ service.interceptors.response.use(
}
).
then
(()
=>
{
store
.
dispatch
(
'
user/resetToken
'
).
then
(()
=>
{
location
.
reload
()
})
})
location
.
reload
()
;
})
;
})
;
}
return
Promise
.
reject
(
new
Error
(
res
.
message
||
'
Error
'
))
return
Promise
.
reject
(
new
Error
(
res
.
message
||
'
Error
'
))
;
}
else
{
return
res
return
res
;
}
},
error
=>
{
console
.
log
(
'
response err ==>
'
+
error
)
// for debug
console
.
log
(
'
response err ==>
'
+
error
)
;
// for debug
Message
({
message
:
error
.
message
,
type
:
'
error
'
,
duration
:
5
*
1000
})
return
Promise
.
reject
(
error
)
})
;
return
Promise
.
reject
(
error
)
;
}
)
)
;
export
default
service
export
default
service
;
ve-admin/admin-web/src/utils/str-util.js
0 → 100644
View file @
a30f21ad
/*
* @Description: 字符串工具类
* @Author: 一日看尽长安花
* @Date: 2019-10-11 17:40:47
* @LastEditTime: 2019-10-12 09:36:33
* @LastEditors: Please set LastEditors
*/
import
{
isExists
,
isNotExists
}
from
'
@/utils/object-util
'
;
import
{
isString
,
trim
}
from
'
lodash
'
;
/**
* @description: 字符串为空串
* @param {Object}
* @return {Boolean}
*/
export
function
isBlank
(
str
)
{
if
(
isNotExists
(
str
))
{
if
(
isString
(
str
))
{
if
(
trim
(
str
).
length
===
0
)
{
return
true
;
}
else
{
return
false
;
}
}
else
{
throw
'
str is not string type
'
;
}
}
else
{
throw
'
str is null
'
;
}
}
/**
* @description: 字符串不为空串
* @param {Object}
* @return {Boolean}
*/
export
function
isNotBlank
(
str
)
{
if
(
isNotExists
(
str
))
{
if
(
isString
(
str
))
{
if
(
trim
(
str
).
length
>
0
)
{
return
true
;
}
else
{
return
false
;
}
}
else
{
throw
'
str is not string type
'
;
}
}
else
{
throw
'
str is null
'
;
}
}
ve-admin/admin-web/src/views/table/complex-table.vue
View file @
a30f21ad
<!--
* @Author: ???????
* @since: 2019-09-09 12:16:29
* @LastEditTime: 2019-10-12 17:10:36
* @LastEditors: ???????
* @Description:
-->
<
template
>
<div
class=
"app-container"
>
<div
class=
"filter-container"
>
<el-input
v-model=
"listQuery.title"
placeholder=
"Title"
style=
"width: 200px;"
class=
"filter-item"
@
keyup.enter.native=
"handleFilter"
/>
<el-select
v-model=
"listQuery.importance"
placeholder=
"Imp"
clearable
style=
"width: 90px"
class=
"filter-item"
>
<el-option
v-for=
"item in importanceOptions"
:key=
"item"
:label=
"item"
:value=
"item"
/>
<el-input
v-model=
"listQuery.title"
placeholder=
"Title"
style=
"width: 200px;"
class=
"filter-item"
@
keyup.enter.native=
"handleFilter"
/>
<el-select
v-model=
"listQuery.importance"
placeholder=
"Imp"
clearable
style=
"width: 90px"
class=
"filter-item"
>
<el-option
v-for=
"item in importanceOptions"
:key=
"item"
:label=
"item"
:value=
"item"
/>
</el-select>
<el-select
v-model=
"listQuery.type"
placeholder=
"Type"
clearable
class=
"filter-item"
style=
"width: 130px"
>
<el-option
v-for=
"item in calendarTypeOptions"
:key=
"item.key"
:label=
"item.display_name+'('+item.key+')'"
:value=
"item.key"
/>
<el-select
v-model=
"listQuery.type"
placeholder=
"Type"
clearable
class=
"filter-item"
style=
"width: 130px"
>
<el-option
v-for=
"item in calendarTypeOptions"
:key=
"item.key"
:label=
"item.display_name + '(' + item.key + ')'"
:value=
"item.key"
/>
</el-select>
<el-select
v-model=
"listQuery.sort"
style=
"width: 140px"
class=
"filter-item"
@
change=
"handleFilter"
>
<el-option
v-for=
"item in sortOptions"
:key=
"item.key"
:label=
"item.label"
:value=
"item.key"
/>
<el-select
v-model=
"listQuery.sort"
style=
"width: 140px"
class=
"filter-item"
@
change=
"handleFilter"
>
<el-option
v-for=
"item in sortOptions"
:key=
"item.key"
:label=
"item.label"
:value=
"item.key"
/>
</el-select>
<el-button
v-waves
class=
"filter-item"
type=
"primary"
icon=
"el-icon-search"
@
click=
"handleFilter"
>
<el-button
v-waves
class=
"filter-item"
type=
"primary"
icon=
"el-icon-search"
@
click=
"handleFilter"
>
Search
</el-button>
<el-button
class=
"filter-item"
style=
"margin-left: 10px;"
type=
"primary"
icon=
"el-icon-edit"
@
click=
"handleCreate"
>
<el-button
class=
"filter-item"
style=
"margin-left: 10px;"
type=
"primary"
icon=
"el-icon-edit"
@
click=
"handleCreate"
>
Add
</el-button>
<el-button
v-waves
:loading=
"downloadLoading"
class=
"filter-item"
type=
"primary"
icon=
"el-icon-download"
@
click=
"handleDownload"
>
<el-button
v-waves
:loading=
"downloadLoading"
class=
"filter-item"
type=
"primary"
icon=
"el-icon-download"
@
click=
"handleDownload"
>
Export
</el-button>
<el-checkbox
v-model=
"showReviewer"
class=
"filter-item"
style=
"margin-left:15px;"
@
change=
"tableKey=tableKey+1"
>
<el-checkbox
v-model=
"showReviewer"
class=
"filter-item"
style=
"margin-left:15px;"
@
change=
"tableKey = tableKey + 1"
>
reviewer
</el-checkbox>
</div>
...
...
@@ -35,19 +104,30 @@
style=
"width: 100%;"
@
sort-change=
"sortChange"
>
<el-table-column
label=
"ID"
prop=
"id"
sortable=
"custom"
align=
"center"
width=
"80"
:class-name=
"getSortClass('id')"
>
<el-table-column
label=
"ID"
prop=
"id"
sortable=
"custom"
align=
"center"
width=
"80"
:class-name=
"getSortClass('id')"
>
<template
slot-scope=
"scope"
>
<span>
{{
scope
.
row
.
id
}}
</span>
</
template
>
</el-table-column>
<el-table-column
label=
"Date"
width=
"150px"
align=
"center"
>
<
template
slot-scope=
"scope"
>
<span>
{{
scope
.
row
.
timestamp
|
parseTime
(
'
{y
}
-{m
}
-{d
}
{h
}
:{i
}
'
)
}}
<
/span
>
<span>
{{
scope
.
row
.
timestamp
|
parseTime
(
'
{y
}
-{m
}
-{d
}
{h
}
:{i
}
'
)
}}
<
/span
>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"
Title
"
min
-
width
=
"
150px
"
>
<
template
slot
-
scope
=
"
{row
}
"
>
<
span
class
=
"
link-type
"
@
click
=
"
handleUpdate(row)
"
>
{{
row
.
title
}}
<
/span
>
<
template
slot
-
scope
=
"
{ row
}
"
>
<
span
class
=
"
link-type
"
@
click
=
"
handleUpdate(row)
"
>
{{
row
.
title
}}
<
/span
>
<
el
-
tag
>
{{
row
.
type
|
typeFilter
}}
<
/el-tag
>
<
/template
>
<
/el-table-column
>
...
...
@@ -56,114 +136,210 @@
<
span
>
{{
scope
.
row
.
author
}}
<
/span
>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
v
-
if
=
"
showReviewer
"
label
=
"
Reviewer
"
width
=
"
110px
"
align
=
"
center
"
>
<
el
-
table
-
column
v
-
if
=
"
showReviewer
"
label
=
"
Reviewer
"
width
=
"
110px
"
align
=
"
center
"
>
<
template
slot
-
scope
=
"
scope
"
>
<
span
style
=
"
color:red;
"
>
{{
scope
.
row
.
reviewer
}}
<
/span
>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"
Imp
"
width
=
"
80px
"
>
<
template
slot
-
scope
=
"
scope
"
>
<
svg
-
icon
v
-
for
=
"
n in +scope.row.importance
"
:
key
=
"
n
"
icon
-
class
=
"
star
"
class
=
"
meta-item__icon
"
/>
<
svg
-
icon
v
-
for
=
"
n in +scope.row.importance
"
:
key
=
"
n
"
icon
-
class
=
"
star
"
class
=
"
meta-item__icon
"
/>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"
Readings
"
align
=
"
center
"
width
=
"
95
"
>
<
template
slot
-
scope
=
"
{row
}
"
>
<
span
v
-
if
=
"
row.pageviews
"
class
=
"
link-type
"
@
click
=
"
handleFetchPv(row.pageviews)
"
>
{{
row
.
pageviews
}}
<
/span
>
<
template
slot
-
scope
=
"
{ row
}
"
>
<
span
v
-
if
=
"
row.pageviews
"
class
=
"
link-type
"
@
click
=
"
handleFetchPv(row.pageviews)
"
>
{{
row
.
pageviews
}}
<
/span
>
<
span
v
-
else
>
0
<
/span
>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"
Status
"
class
-
name
=
"
status-col
"
width
=
"
100
"
>
<
template
slot
-
scope
=
"
{row
}
"
>
<
template
slot
-
scope
=
"
{
row
}
"
>
<
el
-
tag
:
type
=
"
row.status | statusFilter
"
>
{{
row
.
status
}}
<
/el-tag
>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"
Actions
"
align
=
"
center
"
width
=
"
230
"
class
-
name
=
"
small-padding fixed-width
"
>
<
template
slot
-
scope
=
"
{row
}
"
>
<
el
-
table
-
column
label
=
"
Actions
"
align
=
"
center
"
width
=
"
230
"
class
-
name
=
"
small-padding fixed-width
"
>
<
template
slot
-
scope
=
"
{ row
}
"
>
<
el
-
button
type
=
"
primary
"
size
=
"
mini
"
@
click
=
"
handleUpdate(row)
"
>
Edit
<
/el-button
>
<
el
-
button
v
-
if
=
"
row.status!='published'
"
size
=
"
mini
"
type
=
"
success
"
@
click
=
"
handleModifyStatus(row,'published')
"
>
<
el
-
button
v
-
if
=
"
row.status != 'published'
"
size
=
"
mini
"
type
=
"
success
"
@
click
=
"
handleModifyStatus(row, 'published')
"
>
Publish
<
/el-button
>
<
el
-
button
v
-
if
=
"
row.status!='draft'
"
size
=
"
mini
"
@
click
=
"
handleModifyStatus(row,'draft')
"
>
<
el
-
button
v
-
if
=
"
row.status != 'draft'
"
size
=
"
mini
"
@
click
=
"
handleModifyStatus(row, 'draft')
"
>
Draft
<
/el-button
>
<
el
-
button
v
-
if
=
"
row.status!='deleted'
"
size
=
"
mini
"
type
=
"
danger
"
@
click
=
"
handleModifyStatus(row,'deleted')
"
>
<
el
-
button
v
-
if
=
"
row.status != 'deleted'
"
size
=
"
mini
"
type
=
"
danger
"
@
click
=
"
handleModifyStatus(row, 'deleted')
"
>
Delete
<
/el-button
>
<
/template
>
<
/el-table-column
>
<
/el-table
>
<
pagination
v
-
show
=
"
total>0
"
:
total
=
"
total
"
:
page
.
sync
=
"
listQuery.page
"
:
limit
.
sync
=
"
listQuery.limit
"
@
pagination
=
"
getList
"
/>
<
pagination
v
-
show
=
"
total > 0
"
:
total
=
"
total
"
:
page
.
sync
=
"
listQuery.page
"
:
limit
.
sync
=
"
listQuery.limit
"
@
pagination
=
"
getList
"
/>
<
el
-
dialog
:
title
=
"
textMap[dialogStatus]
"
:
visible
.
sync
=
"
dialogFormVisible
"
>
<
el
-
form
ref
=
"
dataForm
"
:
rules
=
"
rules
"
:
model
=
"
temp
"
label
-
position
=
"
left
"
label
-
width
=
"
70px
"
style
=
"
width: 400px; margin-left:50px;
"
>
<
el
-
form
ref
=
"
dataForm
"
:
rules
=
"
rules
"
:
model
=
"
temp
"
label
-
position
=
"
left
"
label
-
width
=
"
70px
"
style
=
"
width: 400px; margin-left:50px;
"
>
<
el
-
form
-
item
label
=
"
Type
"
prop
=
"
type
"
>
<
el
-
select
v
-
model
=
"
temp.type
"
class
=
"
filter-item
"
placeholder
=
"
Please select
"
>
<
el
-
option
v
-
for
=
"
item in calendarTypeOptions
"
:
key
=
"
item.key
"
:
label
=
"
item.display_name
"
:
value
=
"
item.key
"
/>
<
el
-
select
v
-
model
=
"
temp.type
"
class
=
"
filter-item
"
placeholder
=
"
Please select
"
>
<
el
-
option
v
-
for
=
"
item in calendarTypeOptions
"
:
key
=
"
item.key
"
:
label
=
"
item.display_name
"
:
value
=
"
item.key
"
/>
<
/el-select
>
<
/el-form-item
>
<
el
-
form
-
item
label
=
"
Date
"
prop
=
"
timestamp
"
>
<
el
-
date
-
picker
v
-
model
=
"
temp.timestamp
"
type
=
"
datetime
"
placeholder
=
"
Please pick a date
"
/>
<
el
-
date
-
picker
v
-
model
=
"
temp.timestamp
"
type
=
"
datetime
"
placeholder
=
"
Please pick a date
"
/>
<
/el-form-item
>
<
el
-
form
-
item
label
=
"
Title
"
prop
=
"
title
"
>
<
el
-
input
v
-
model
=
"
temp.title
"
/>
<
/el-form-item
>
<
el
-
form
-
item
label
=
"
Status
"
>
<
el
-
select
v
-
model
=
"
temp.status
"
class
=
"
filter-item
"
placeholder
=
"
Please select
"
>
<
el
-
option
v
-
for
=
"
item in statusOptions
"
:
key
=
"
item
"
:
label
=
"
item
"
:
value
=
"
item
"
/>
<
el
-
select
v
-
model
=
"
temp.status
"
class
=
"
filter-item
"
placeholder
=
"
Please select
"
>
<
el
-
option
v
-
for
=
"
item in statusOptions
"
:
key
=
"
item
"
:
label
=
"
item
"
:
value
=
"
item
"
/>
<
/el-select
>
<
/el-form-item
>
<
el
-
form
-
item
label
=
"
Imp
"
>
<
el
-
rate
v
-
model
=
"
temp.importance
"
:
colors
=
"
['#99A9BF', '#F7BA2A', '#FF9900']
"
:
max
=
"
3
"
style
=
"
margin-top:8px;
"
/>
<
el
-
rate
v
-
model
=
"
temp.importance
"
:
colors
=
"
['#99A9BF', '#F7BA2A', '#FF9900']
"
:
max
=
"
3
"
style
=
"
margin-top:8px;
"
/>
<
/el-form-item
>
<
el
-
form
-
item
label
=
"
Remark
"
>
<
el
-
input
v
-
model
=
"
temp.remark
"
:
autosize
=
"
{ minRows: 2, maxRows: 4
}
"
type
=
"
textarea
"
placeholder
=
"
Please input
"
/>
<
el
-
input
v
-
model
=
"
temp.remark
"
:
autosize
=
"
{ minRows: 2, maxRows: 4
}
"
type
=
"
textarea
"
placeholder
=
"
Please input
"
/>
<
/el-form-item
>
<
/el-form
>
<
div
slot
=
"
footer
"
class
=
"
dialog-footer
"
>
<
el
-
button
@
click
=
"
dialogFormVisible = false
"
>
Cancel
<
/el-button
>
<
el
-
button
type
=
"
primary
"
@
click
=
"
dialogStatus==='create'?createData():updateData()
"
>
<
el
-
button
type
=
"
primary
"
@
click
=
"
dialogStatus === 'create' ? createData() : updateData()
"
>
Confirm
<
/el-button
>
<
/div
>
<
/el-dialog
>
<
el
-
dialog
:
visible
.
sync
=
"
dialogPvVisible
"
title
=
"
Reading statistics
"
>
<
el
-
table
:
data
=
"
pvData
"
border
fit
highlight
-
current
-
row
style
=
"
width: 100%
"
>
<
el
-
table
:
data
=
"
pvData
"
border
fit
highlight
-
current
-
row
style
=
"
width: 100%
"
>
<
el
-
table
-
column
prop
=
"
key
"
label
=
"
Channel
"
/>
<
el
-
table
-
column
prop
=
"
pv
"
label
=
"
Pv
"
/>
<
/el-table
>
<
span
slot
=
"
footer
"
class
=
"
dialog-footer
"
>
<
el
-
button
type
=
"
primary
"
@
click
=
"
dialogPvVisible = false
"
>
Confirm
<
/el-button
>
<
el
-
button
type
=
"
primary
"
@
click
=
"
dialogPvVisible = false
"
>
Confirm
<
/el-button
>
<
/span
>
<
/el-dialog
>
<
/div
>
<
/template
>
<
script
>
import
{
fetchList
,
fetchPv
,
createArticle
,
updateArticle
}
from
'
@/api/article
'
import
waves
from
'
@/directive/waves
'
// waves directive
import
{
parseTime
}
from
'
@/utils
'
import
Pagination
from
'
@/components/Pagination
'
// secondary package based on el-pagination
import
{
fetchList
,
fetchPv
,
createArticle
,
updateArticle
}
from
'
@/api/article
'
;
import
waves
from
'
@/directive/waves
'
;
// waves directive
import
{
parseTime
}
from
'
@/utils
'
;
import
Pagination
from
'
@/components/Pagination
'
;
// secondary package based on el-pagination
const
calendarTypeOptions
=
[
{
key
:
'
CN
'
,
display_name
:
'
China
'
}
,
{
key
:
'
US
'
,
display_name
:
'
USA
'
}
,
{
key
:
'
JP
'
,
display_name
:
'
Japan
'
}
,
{
key
:
'
EU
'
,
display_name
:
'
Eurozone
'
}
]
]
;
// arr to obj, such as
{
CN
:
"
China
"
,
US
:
"
USA
"
}
const
calendarTypeKeyValue
=
calendarTypeOptions
.
reduce
((
acc
,
cur
)
=>
{
acc
[
cur
.
key
]
=
cur
.
display_name
return
acc
}
,
{
}
)
acc
[
cur
.
key
]
=
cur
.
display_name
;
return
acc
;
}
,
{
}
)
;
export
default
{
name
:
'
ComplexTable
'
,
...
...
@@ -175,11 +351,11 @@ export default {
published
:
'
success
'
,
draft
:
'
info
'
,
deleted
:
'
danger
'
}
return
statusMap
[
status
]
}
;
return
statusMap
[
status
]
;
}
,
typeFilter
(
type
)
{
return
calendarTypeKeyValue
[
type
]
return
calendarTypeKeyValue
[
type
]
;
}
}
,
data
()
{
...
...
@@ -198,7 +374,10 @@ export default {
}
,
importanceOptions
:
[
1
,
2
,
3
],
calendarTypeOptions
,
sortOptions
:
[{
label
:
'
ID Ascending
'
,
key
:
'
+id
'
}
,
{
label
:
'
ID Descending
'
,
key
:
'
-id
'
}
],
sortOptions
:
[
{
label
:
'
ID Ascending
'
,
key
:
'
+id
'
}
,
{
label
:
'
ID Descending
'
,
key
:
'
-id
'
}
],
statusOptions
:
[
'
published
'
,
'
draft
'
,
'
deleted
'
],
showReviewer
:
false
,
temp
:
{
...
...
@@ -219,53 +398,64 @@ export default {
dialogPvVisible
:
false
,
pvData
:
[],
rules
:
{
type
:
[{
required
:
true
,
message
:
'
type is required
'
,
trigger
:
'
change
'
}
],
timestamp
:
[{
type
:
'
date
'
,
required
:
true
,
message
:
'
timestamp is required
'
,
trigger
:
'
change
'
}
],
title
:
[{
required
:
true
,
message
:
'
title is required
'
,
trigger
:
'
blur
'
}
]
type
:
[
{
required
:
true
,
message
:
'
type is required
'
,
trigger
:
'
change
'
}
],
timestamp
:
[
{
type
:
'
date
'
,
required
:
true
,
message
:
'
timestamp is required
'
,
trigger
:
'
change
'
}
],
title
:
[
{
required
:
true
,
message
:
'
title is required
'
,
trigger
:
'
blur
'
}
]
}
,
downloadLoading
:
false
}
}
;
}
,
created
()
{
this
.
getList
()
this
.
getList
()
;
}
,
methods
:
{
getList
()
{
this
.
listLoading
=
true
this
.
listLoading
=
true
;
fetchList
(
this
.
listQuery
).
then
(
response
=>
{
this
.
list
=
response
.
data
.
items
this
.
total
=
response
.
data
.
total
this
.
list
=
response
.
data
.
items
;
this
.
total
=
response
.
data
.
total
;
// Just to simulate the time of the request
setTimeout
(()
=>
{
this
.
listLoading
=
false
}
,
1.5
*
1000
)
}
)
this
.
listLoading
=
false
;
}
,
1.5
*
1000
)
;
}
)
;
}
,
handleFilter
()
{
this
.
listQuery
.
page
=
1
this
.
getList
()
this
.
listQuery
.
page
=
1
;
this
.
getList
()
;
}
,
handleModifyStatus
(
row
,
status
)
{
this
.
$message
({
message
:
'
操作Success
'
,
type
:
'
success
'
}
)
row
.
status
=
status
}
)
;
row
.
status
=
status
;
}
,
sortChange
(
data
)
{
const
{
prop
,
order
}
=
data
const
{
prop
,
order
}
=
data
;
if
(
prop
===
'
id
'
)
{
this
.
sortByID
(
order
)
this
.
sortByID
(
order
)
;
}
}
,
sortByID
(
order
)
{
if
(
order
===
'
ascending
'
)
{
this
.
listQuery
.
sort
=
'
+id
'
this
.
listQuery
.
sort
=
'
+id
'
;
}
else
{
this
.
listQuery
.
sort
=
'
-id
'
this
.
listQuery
.
sort
=
'
-id
'
;
}
this
.
handleFilter
()
this
.
handleFilter
()
;
}
,
resetTemp
()
{
this
.
temp
=
{
...
...
@@ -276,66 +466,66 @@ export default {
title
:
''
,
status
:
'
published
'
,
type
:
''
}
}
;
}
,
handleCreate
()
{
this
.
resetTemp
()
this
.
dialogStatus
=
'
create
'
this
.
dialogFormVisible
=
true
this
.
resetTemp
()
;
this
.
dialogStatus
=
'
create
'
;
this
.
dialogFormVisible
=
true
;
this
.
$nextTick
(()
=>
{
this
.
$refs
[
'
dataForm
'
].
clearValidate
()
}
)
this
.
$refs
[
'
dataForm
'
].
clearValidate
()
;
}
)
;
}
,
createData
()
{
this
.
$refs
[
'
dataForm
'
].
validate
(
(
valid
)
=>
{
this
.
$refs
[
'
dataForm
'
].
validate
(
valid
=>
{
if
(
valid
)
{
this
.
temp
.
id
=
parseInt
(
Math
.
random
()
*
100
)
+
1024
// mock a id
this
.
temp
.
author
=
'
vue-element-admin
'
this
.
temp
.
id
=
parseInt
(
Math
.
random
()
*
100
)
+
1024
;
// mock a id
this
.
temp
.
author
=
'
vue-element-admin
'
;
createArticle
(
this
.
temp
).
then
(()
=>
{
this
.
list
.
unshift
(
this
.
temp
)
this
.
dialogFormVisible
=
false
this
.
list
.
unshift
(
this
.
temp
)
;
this
.
dialogFormVisible
=
false
;
this
.
$notify
({
title
:
'
Success
'
,
message
:
'
Created Successfully
'
,
type
:
'
success
'
,
duration
:
2000
}
)
}
)
}
)
;
}
)
;
}
}
)
}
)
;
}
,
handleUpdate
(
row
)
{
this
.
temp
=
Object
.
assign
({
}
,
row
)
// copy obj
this
.
temp
.
timestamp
=
new
Date
(
this
.
temp
.
timestamp
)
this
.
dialogStatus
=
'
update
'
this
.
dialogFormVisible
=
true
this
.
temp
=
Object
.
assign
({
}
,
row
)
;
// copy obj
this
.
temp
.
timestamp
=
new
Date
(
this
.
temp
.
timestamp
)
;
this
.
dialogStatus
=
'
update
'
;
this
.
dialogFormVisible
=
true
;
this
.
$nextTick
(()
=>
{
this
.
$refs
[
'
dataForm
'
].
clearValidate
()
}
)
this
.
$refs
[
'
dataForm
'
].
clearValidate
()
;
}
)
;
}
,
updateData
()
{
this
.
$refs
[
'
dataForm
'
].
validate
(
(
valid
)
=>
{
this
.
$refs
[
'
dataForm
'
].
validate
(
valid
=>
{
if
(
valid
)
{
const
tempData
=
Object
.
assign
({
}
,
this
.
temp
)
tempData
.
timestamp
=
+
new
Date
(
tempData
.
timestamp
)
// change Thu Nov 30 2017 16:41:05 GMT+0800 (CST) to 1512031311464
const
tempData
=
Object
.
assign
({
}
,
this
.
temp
)
;
tempData
.
timestamp
=
+
new
Date
(
tempData
.
timestamp
)
;
// change Thu Nov 30 2017 16:41:05 GMT+0800 (CST) to 1512031311464
updateArticle
(
tempData
).
then
(()
=>
{
for
(
const
v
of
this
.
list
)
{
if
(
v
.
id
===
this
.
temp
.
id
)
{
const
index
=
this
.
list
.
indexOf
(
v
)
this
.
list
.
splice
(
index
,
1
,
this
.
temp
)
break
const
index
=
this
.
list
.
indexOf
(
v
)
;
this
.
list
.
splice
(
index
,
1
,
this
.
temp
)
;
break
;
}
}
this
.
dialogFormVisible
=
false
this
.
dialogFormVisible
=
false
;
this
.
$notify
({
title
:
'
Success
'
,
message
:
'
Update Successfully
'
,
type
:
'
success
'
,
duration
:
2000
}
)
}
)
}
)
;
}
)
;
}
}
)
}
)
;
}
,
handleDelete
(
row
)
{
this
.
$notify
({
...
...
@@ -343,47 +533,55 @@ export default {
message
:
'
Delete Successfully
'
,
type
:
'
success
'
,
duration
:
2000
}
)
const
index
=
this
.
list
.
indexOf
(
row
)
this
.
list
.
splice
(
index
,
1
)
}
)
;
const
index
=
this
.
list
.
indexOf
(
row
)
;
this
.
list
.
splice
(
index
,
1
)
;
}
,
handleFetchPv
(
pv
)
{
fetchPv
(
pv
).
then
(
response
=>
{
this
.
pvData
=
response
.
data
.
pvData
this
.
dialogPvVisible
=
true
}
)
this
.
pvData
=
response
.
data
.
pvData
;
this
.
dialogPvVisible
=
true
;
}
)
;
}
,
handleDownload
()
{
this
.
downloadLoading
=
true
this
.
downloadLoading
=
true
;
import
(
'
@/vendor/Export2Excel
'
).
then
(
excel
=>
{
const
tHeader
=
[
'
timestamp
'
,
'
title
'
,
'
type
'
,
'
importance
'
,
'
status
'
]
const
filterVal
=
[
'
timestamp
'
,
'
title
'
,
'
type
'
,
'
importance
'
,
'
status
'
]
const
data
=
this
.
formatJson
(
filterVal
,
this
.
list
)
const
tHeader
=
[
'
timestamp
'
,
'
title
'
,
'
type
'
,
'
importance
'
,
'
status
'
];
const
filterVal
=
[
'
timestamp
'
,
'
title
'
,
'
type
'
,
'
importance
'
,
'
status
'
];
const
data
=
this
.
formatJson
(
filterVal
,
this
.
list
);
excel
.
export_json_to_excel
({
header
:
tHeader
,
data
,
filename
:
'
table-list
'
}
)
this
.
downloadLoading
=
false
}
)
}
)
;
this
.
downloadLoading
=
false
;
}
)
;
}
,
formatJson
(
filterVal
,
jsonData
)
{
return
jsonData
.
map
(
v
=>
filterVal
.
map
(
j
=>
{
if
(
j
===
'
timestamp
'
)
{
return
parseTime
(
v
[
j
])
}
else
{
return
v
[
j
]
}
}
))
return
jsonData
.
map
(
v
=>
filterVal
.
map
(
j
=>
{
if
(
j
===
'
timestamp
'
)
{
return
parseTime
(
v
[
j
]);
}
else
{
return
v
[
j
];
}
}
)
);
}
,
getSortClass
:
function
(
key
)
{
const
sort
=
this
.
listQuery
.
sort
const
sort
=
this
.
listQuery
.
sort
;
return
sort
===
`+${key
}
`
?
'
ascending
'
:
sort
===
`-${key
}
`
?
'
descending
'
:
''
:
''
;
}
}
}
}
;
<
/script
>
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment