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
Litemall
Commits
324c8da3
Unverified
Commit
324c8da3
authored
Dec 29, 2019
by
linlinjava
Committed by
GitHub
Dec 29, 2019
Browse files
Merge branch 'master' into dev
parents
693cf5cd
4c46da9b
Changes
393
Hide whitespace changes
Inline
Side-by-side
Too many changes to show.
To preserve performance only
20 of 393+
files are displayed.
Plain diff
Email patch
litemall-admin/src/views/layout/components/Sidebar/SidebarItem.vue
View file @
324c8da3
<
template
>
<div
v-if=
"!item.hidden&&item.children"
class=
"menu-wrapper"
>
<div
v-if=
"!item.hidden"
class=
"menu-wrapper"
>
<template
v-if=
"hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow"
>
<app-link
:to=
"resolvePath(onlyOneChild.path)"
>
<app-link
v-if=
"onlyOneChild.meta"
:to=
"resolvePath(onlyOneChild.path)"
>
<el-menu-item
:index=
"resolvePath(onlyOneChild.path)"
:class=
"
{'submenu-title-noDropdown':!isNest}">
<item
v-if=
"onlyOneChild.meta"
:icon=
"onlyOneChild.meta.icon||item.meta.icon"
:title=
"onlyOneChild.meta.title"
/>
<item
:icon=
"onlyOneChild.meta.icon||
(item.meta&&
item.meta.icon
)
"
:title=
"onlyOneChild.meta.title"
/>
</el-menu-item>
</app-link>
</
template
>
<el-submenu
v-else
ref=
"submenu"
:index=
"resolvePath(item.path)"
>
<el-submenu
v-else
ref=
"subMenu"
:index=
"resolvePath(item.path)"
popper-append-to-body
>
<
template
slot=
"title"
>
<item
v-if=
"item.meta"
:icon=
"item.meta.icon"
:title=
"item.meta.title"
/>
</
template
>
<
template
v-for=
"child in item.children"
v-if=
"!child.hidden"
>
<sidebar-item
v-if=
"child.children&&child.children.length>0"
:is-nest=
"true"
:item=
"child"
:key=
"child.path"
:base-path=
"resolvePath(child.path)"
class=
"nest-menu"
/>
<app-link
v-else
:to=
"resolvePath(child.path)"
:key=
"child.name"
>
<el-menu-item
:index=
"resolvePath(child.path)"
>
<item
v-if=
"child.meta"
:icon=
"child.meta.icon"
:title=
"child.meta.title"
/>
</el-menu-item>
</app-link>
<item
v-if=
"item.meta"
:icon=
"item.meta && item.meta.icon"
:title=
"item.meta.title"
/>
</
template
>
<sidebar-item
v-for=
"child in item.children"
:key=
"child.path"
:is-nest=
"true"
:item=
"child"
:base-path=
"resolvePath(child.path)"
class=
"nest-menu"
/>
</el-submenu>
</div>
</template>
<
script
>
import
path
from
'
path
'
import
{
isExternal
}
from
'
@/utils
'
import
{
isExternal
}
from
'
@/utils
/validate
'
import
Item
from
'
./Item
'
import
AppLink
from
'
./Link
'
import
FixiOSBug
from
'
./FixiOSBug
'
...
...
@@ -61,12 +50,13 @@ export default {
}
},
data
()
{
return
{
onlyOneChild
:
null
}
// To fix https://github.com/PanJiaChen/vue-admin-template/issues/237
// TODO: refactor with render function
this
.
onlyOneChild
=
null
return
{}
},
methods
:
{
hasOneShowingChild
(
children
,
parent
)
{
hasOneShowingChild
(
children
=
[]
,
parent
)
{
const
showingChildren
=
children
.
filter
(
item
=>
{
if
(
item
.
hidden
)
{
return
false
...
...
@@ -91,13 +81,13 @@ export default {
return
false
},
resolvePath
(
routePath
)
{
if
(
this
.
isExternal
Link
(
routePath
))
{
if
(
isExternal
(
routePath
))
{
return
routePath
}
if
(
isExternal
(
this
.
basePath
))
{
return
this
.
basePath
}
return
path
.
resolve
(
this
.
basePath
,
routePath
)
},
isExternalLink
(
routePath
)
{
return
isExternal
(
routePath
)
}
}
}
...
...
litemall-admin/src/views/layout/components/TagsView.vue
View file @
324c8da3
<
template
>
<div
class=
"tags-view-container"
>
<div
id=
"tags-view-container"
class=
"tags-view-container"
>
<scroll-pane
ref=
"scrollPane"
class=
"tags-view-wrapper"
>
<router-link
v-for=
"tag in visitedViews"
ref=
"tag"
:key=
"tag.path"
:class=
"isActive(tag)?'active':''"
:to=
"
{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
:key="tag.path"
tag="span"
class="tags-view-item"
@click.middle.native="closeSelectedTag(tag)"
@contextmenu.prevent.native="openMenu(tag,$event)">
@click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''"
@contextmenu.prevent.native="openMenu(tag,$event)"
>
{{
tag
.
title
}}
<span
class=
"el-icon-close"
@
click.prevent.stop=
"closeSelectedTag(tag)"
/>
<span
v-if=
"!isAffix(tag)"
class=
"el-icon-close"
@
click.prevent.stop=
"closeSelectedTag(tag)"
/>
</router-link>
</scroll-pane>
<ul
v-show=
"visible"
:style=
"
{left:left+'px',top:top+'px'}" class="contextmenu">
<li
@
click=
"refreshSelectedTag(selectedTag)"
>
刷新
</li>
<li
@
click=
"closeSelectedTag(selectedTag)"
>
关闭
</li>
<li
@
click=
"closeOthersTags"
>
关闭其
它
</li>
<li
@
click=
"closeAllTags"
>
关闭所有
</li>
<li
v-if=
"!isAffix(selectedTag)"
@
click=
"closeSelectedTag(selectedTag)"
>
关闭
</li>
<li
@
click=
"closeOthersTags"
>
关闭其
他
</li>
<li
@
click=
"closeAllTags
(selectedTag)
"
>
关闭所有
</li>
</ul>
</div>
</
template
>
<
script
>
import
ScrollPane
from
'
@/components/ScrollPane
'
import
ScrollPane
from
'
./ScrollPane
'
import
path
from
'
path
'
export
default
{
components
:
{
ScrollPane
},
...
...
@@ -34,17 +36,21 @@ export default {
visible
:
false
,
top
:
0
,
left
:
0
,
selectedTag
:
{}
selectedTag
:
{},
affixTags
:
[]
}
},
computed
:
{
visitedViews
()
{
return
this
.
$store
.
state
.
tagsView
.
visitedViews
},
routes
()
{
return
this
.
$store
.
state
.
permission
.
routers
}
},
watch
:
{
$route
()
{
this
.
add
View
Tags
()
this
.
addTags
()
this
.
moveToCurrentTag
()
},
visible
(
value
)
{
...
...
@@ -56,16 +62,50 @@ export default {
}
},
mounted
()
{
this
.
addViewTags
()
this
.
initTags
()
this
.
addTags
()
},
methods
:
{
isActive
(
route
)
{
return
route
.
path
===
this
.
$route
.
path
},
addViewTags
()
{
isAffix
(
tag
)
{
return
tag
.
meta
&&
tag
.
meta
.
affix
},
filterAffixTags
(
routes
,
basePath
=
'
/
'
)
{
let
tags
=
[]
routes
.
forEach
(
route
=>
{
if
(
route
.
meta
&&
route
.
meta
.
affix
)
{
const
tagPath
=
path
.
resolve
(
basePath
,
route
.
path
)
tags
.
push
({
fullPath
:
tagPath
,
path
:
tagPath
,
name
:
route
.
name
,
meta
:
{
...
route
.
meta
}
})
}
if
(
route
.
children
)
{
const
tempTags
=
this
.
filterAffixTags
(
route
.
children
,
route
.
path
)
if
(
tempTags
.
length
>=
1
)
{
tags
=
[...
tags
,
...
tempTags
]
}
}
})
return
tags
},
initTags
()
{
const
affixTags
=
this
.
affixTags
=
this
.
filterAffixTags
(
this
.
routes
)
for
(
const
tag
of
affixTags
)
{
// Must have tag name
if
(
tag
.
name
)
{
this
.
$store
.
dispatch
(
'
tagsView/addVisitedView
'
,
tag
)
}
}
},
addTags
()
{
const
{
name
}
=
this
.
$route
if
(
name
)
{
this
.
$store
.
dispatch
(
'
addView
'
,
this
.
$route
)
this
.
$store
.
dispatch
(
'
tagsView/
addView
'
,
this
.
$route
)
}
return
false
},
...
...
@@ -75,19 +115,17 @@ export default {
for
(
const
tag
of
tags
)
{
if
(
tag
.
to
.
path
===
this
.
$route
.
path
)
{
this
.
$refs
.
scrollPane
.
moveToTarget
(
tag
)
// when query is different then update
if
(
tag
.
to
.
fullPath
!==
this
.
$route
.
fullPath
)
{
this
.
$store
.
dispatch
(
'
updateVisitedView
'
,
this
.
$route
)
this
.
$store
.
dispatch
(
'
tagsView/
updateVisitedView
'
,
this
.
$route
)
}
break
}
}
})
},
refreshSelectedTag
(
view
)
{
this
.
$store
.
dispatch
(
'
delCachedView
'
,
view
).
then
(()
=>
{
this
.
$store
.
dispatch
(
'
tagsView/
delCachedView
'
,
view
).
then
(()
=>
{
const
{
fullPath
}
=
view
this
.
$nextTick
(()
=>
{
this
.
$router
.
replace
({
...
...
@@ -97,26 +135,40 @@ export default {
})
},
closeSelectedTag
(
view
)
{
this
.
$store
.
dispatch
(
'
delView
'
,
view
).
then
(({
visitedViews
})
=>
{
this
.
$store
.
dispatch
(
'
tagsView/
delView
'
,
view
).
then
(({
visitedViews
})
=>
{
if
(
this
.
isActive
(
view
))
{
const
latestView
=
visitedViews
.
slice
(
-
1
)[
0
]
if
(
latestView
)
{
this
.
$router
.
push
(
latestView
)
}
else
{
this
.
$router
.
push
(
'
/
'
)
}
this
.
toLastView
(
visitedViews
,
view
)
}
})
},
closeOthersTags
()
{
this
.
$router
.
push
(
this
.
selectedTag
)
this
.
$store
.
dispatch
(
'
delOthersViews
'
,
this
.
selectedTag
).
then
(()
=>
{
this
.
$store
.
dispatch
(
'
tagsView/
delOthersViews
'
,
this
.
selectedTag
).
then
(()
=>
{
this
.
moveToCurrentTag
()
})
},
closeAllTags
()
{
this
.
$store
.
dispatch
(
'
delAllViews
'
)
this
.
$router
.
push
(
'
/
'
)
closeAllTags
(
view
)
{
this
.
$store
.
dispatch
(
'
tagsView/delAllViews
'
).
then
(({
visitedViews
})
=>
{
if
(
this
.
affixTags
.
some
(
tag
=>
tag
.
path
===
view
.
path
))
{
return
}
this
.
toLastView
(
visitedViews
,
view
)
})
},
toLastView
(
visitedViews
,
view
)
{
const
latestView
=
visitedViews
.
slice
(
-
1
)[
0
]
if
(
latestView
)
{
this
.
$router
.
push
(
latestView
.
fullPath
)
}
else
{
// now the default is to redirect to the home page if there is no tags-view,
// you can adjust it according to your needs.
if
(
view
.
name
===
'
Dashboard
'
)
{
// to reload home page
this
.
$router
.
replace
({
path
:
'
/redirect
'
+
view
.
fullPath
})
}
else
{
this
.
$router
.
push
(
'
/
'
)
}
}
},
openMenu
(
tag
,
e
)
{
const
menuMinWidth
=
105
...
...
@@ -130,8 +182,8 @@ export default {
}
else
{
this
.
left
=
left
}
this
.
top
=
e
.
clientY
this
.
top
=
e
.
clientY
this
.
visible
=
true
this
.
selectedTag
=
tag
},
...
...
@@ -142,7 +194,7 @@ export default {
}
</
script
>
<
style
rel=
"stylesheet/scss"
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
.tags-view-container
{
height
:
34px
;
width
:
100%
;
...
...
@@ -189,7 +241,7 @@ export default {
.contextmenu
{
margin
:
0
;
background
:
#fff
;
z-index
:
1
00
;
z-index
:
30
00
;
position
:
absolute
;
list-style-type
:
none
;
padding
:
5px
0
;
...
...
@@ -210,7 +262,7 @@ export default {
}
</
style
>
<
style
rel=
"stylesheet/scss"
lang=
"scss"
>
<
style
lang=
"scss"
>
//reset element css of el-icon-close
.tags-view-wrapper
{
.tags-view-item
{
...
...
litemall-admin/src/views/login/index.vue
View file @
324c8da3
...
...
@@ -5,20 +5,17 @@
<h3
class=
"title"
>
管理员登录
</h3>
</div>
<el-form-item
prop=
"username"
>
<span
class=
"svg-container
svg-container_login
"
>
<span
class=
"svg-container"
>
<svg-icon
icon-class=
"user"
/>
</span>
<el-input
v-model=
"loginForm.username"
name=
"username"
type=
"text"
auto-complete=
"on"
placeholder=
"
username
"
/>
<el-input
v-model=
"loginForm.username"
name=
"username"
type=
"text"
tabindex=
"1"
auto-complete=
"on"
placeholder=
"
管理员账户
"
/>
</el-form-item>
<el-form-item
prop=
"password"
>
<span
class=
"svg-container"
>
<svg-icon
icon-class=
"password"
/>
</span>
<el-input
:type=
"passwordType"
v-model=
"loginForm.password"
name=
"password"
auto-complete=
"on"
placeholder=
"password"
@
keyup.enter.native=
"handleLogin"
/>
<span
class=
"show-pwd"
@
click=
"showPwd"
>
<svg-icon
icon-class=
"eye"
/>
</span>
<el-input
v-model=
"loginForm.password"
:type=
"passwordType"
name=
"password"
auto-complete=
"on"
tabindex=
"2"
show-password
placeholder=
"管理员密码"
@
keyup.enter.native=
"handleLogin"
/>
</el-form-item>
<el-button
:loading=
"loading"
type=
"primary"
style=
"width:100%;margin-bottom:30px;"
@
click.native.prevent=
"handleLogin"
>
登录
</el-button>
...
...
@@ -46,13 +43,6 @@
export
default
{
name
:
'
Login
'
,
data
()
{
const
validateUsername
=
(
rule
,
value
,
callback
)
=>
{
if
(
validateUsername
==
null
)
{
callback
(
new
Error
(
'
请输入正确的管理员用户名
'
))
}
else
{
callback
()
}
}
const
validatePassword
=
(
rule
,
value
,
callback
)
=>
{
if
(
value
.
length
<
6
)
{
callback
(
new
Error
(
'
管理员密码长度应大于6
'
))
...
...
@@ -66,8 +56,11 @@ export default {
password
:
'
admin123
'
},
loginRules
:
{
username
:
[{
required
:
true
,
trigger
:
'
blur
'
,
validator
:
validateUsername
}],
password
:
[{
required
:
true
,
trigger
:
'
blur
'
,
validator
:
validatePassword
}]
username
:
[{
required
:
true
,
message
:
'
管理员账户不允许为空
'
,
trigger
:
'
blur
'
}],
password
:
[
{
required
:
true
,
message
:
'
管理员密码不允许为空
'
,
trigger
:
'
blur
'
},
{
validator
:
validatePassword
,
trigger
:
'
blur
'
}
]
},
passwordType
:
'
password
'
,
loading
:
false
...
...
@@ -89,13 +82,6 @@ export default {
// window.removeEventListener('hashchange', this.afterQRScan)
},
methods
:
{
showPwd
()
{
if
(
this
.
passwordType
===
'
password
'
)
{
this
.
passwordType
=
''
}
else
{
this
.
passwordType
=
'
password
'
}
},
handleLogin
()
{
this
.
$refs
.
loginForm
.
validate
(
valid
=>
{
if
(
valid
&&
!
this
.
loading
)
{
...
...
@@ -119,9 +105,19 @@ export default {
}
</
script
>
<
style
rel=
"stylesheet/scss"
lang=
"scss"
>
$bg
:
#2d3a4b
;
$light_gray
:
#eee
;
<
style
lang=
"scss"
>
/* 修复input 背景不协调 和光标变色 */
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
$bg
:
#283443
;
$light_gray
:
#fff
;
$cursor
:
#fff
;
@supports
(
-webkit-mask
:
none
)
and
(
not
(
cater-color
:
$
cursor
))
{
.login-container
.el-input
input
{
color
:
$cursor
;
}
}
/* reset element-ui css */
.login-container
{
...
...
@@ -129,6 +125,7 @@ $light_gray:#eee;
display
:
inline-block
;
height
:
47px
;
width
:
85%
;
input
{
background
:
transparent
;
border
:
0px
;
...
...
@@ -137,13 +134,15 @@ $light_gray:#eee;
padding
:
12px
5px
12px
15px
;
color
:
$light_gray
;
height
:
47px
;
caret-color
:
$cursor
;
&
:-webkit-autofill
{
box-shadow
:
0
0
0px
1000px
$bg
inset
!
important
;
-webkit-box-shadow
:
0
0
0px
1000px
$bg
inset
!
important
;
-webkit-text-fill-color
:
#fff
!
important
;
-webkit-text-fill-color
:
$cursor
!
important
;
}
}
}
.el-form-item
{
border
:
1px
solid
rgba
(
255
,
255
,
255
,
0
.1
);
background
:
rgba
(
0
,
0
,
0
,
0
.1
);
...
...
@@ -153,63 +152,57 @@ $light_gray:#eee;
}
</
style
>
<
style
rel=
"stylesheet/scss"
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
$bg
:
#2d3a4b
;
$dark_gray
:
#889aa4
;
$light_gray
:
#eee
;
.login-container
{
position
:
fixed
;
height
:
100%
;
min-height
:
100%
;
width
:
100%
;
background-color
:
$bg
;
overflow
:
hidden
;
.login-form
{
position
:
absolute
;
left
:
0
;
right
:
0
;
position
:
relative
;
width
:
520px
;
padding
:
35px
35px
15px
35px
;
margin
:
120px
auto
;
max-width
:
100%
;
padding
:
160px
35px
0
;
margin
:
0
auto
;
overflow
:
hidden
;
}
.tips
{
font-size
:
14px
;
color
:
#fff
;
margin-bottom
:
10px
;
span
{
&
:first-of-type
{
margin-right
:
16px
;
}
}
}
.svg-container
{
padding
:
6px
5px
6px
15px
;
color
:
$dark_gray
;
vertical-align
:
middle
;
width
:
30px
;
display
:
inline-block
;
&
_login
{
font-size
:
20px
;
}
}
.title-container
{
position
:
relative
;
.title
{
font-size
:
26px
;
font-weight
:
400
;
color
:
$light_gray
;
margin
:
0px
auto
40px
auto
;
text-align
:
center
;
font-weight
:
bold
;
}
}
.show-pwd
{
position
:
absolute
;
right
:
10px
;
top
:
7px
;
font-size
:
16px
;
color
:
$dark_gray
;
cursor
:
pointer
;
user-select
:
none
;
}
}
</
style
>
litemall-admin/src/views/mall/brand.vue
View file @
324c8da3
...
...
@@ -110,7 +110,7 @@ export default {
data
()
{
return
{
uploadPath
,
list
:
undefined
,
list
:
[]
,
total
:
0
,
listLoading
:
true
,
listQuery
:
{
...
...
@@ -157,7 +157,7 @@ export default {
this
.
listLoading
=
true
listBrand
(
this
.
listQuery
)
.
then
(
response
=>
{
this
.
list
=
response
.
data
.
data
.
items
this
.
list
=
response
.
data
.
data
.
list
this
.
total
=
response
.
data
.
data
.
total
this
.
listLoading
=
false
})
...
...
litemall-admin/src/views/mall/category.vue
View file @
324c8da3
...
...
@@ -180,7 +180,7 @@ export default {
this
.
listLoading
=
true
listCategory
()
.
then
(
response
=>
{
this
.
list
=
response
.
data
.
data
this
.
list
=
response
.
data
.
data
.
list
this
.
listLoading
=
false
})
.
catch
(()
=>
{
...
...
@@ -190,7 +190,7 @@ export default {
},
getCatL1
()
{
listCatL1
().
then
(
response
=>
{
this
.
catL1
=
response
.
data
.
data
this
.
catL1
=
response
.
data
.
data
.
list
})
},
resetForm
()
{
...
...
litemall-admin/src/views/mall/issue.vue
View file @
324c8da3
...
...
@@ -91,7 +91,7 @@ export default {
getList
()
{
this
.
listLoading
=
true
listIssue
(
this
.
listQuery
).
then
(
response
=>
{
this
.
list
=
response
.
data
.
data
.
items
this
.
list
=
response
.
data
.
data
.
list
this
.
total
=
response
.
data
.
data
.
total
this
.
listLoading
=
false
}).
catch
(()
=>
{
...
...
litemall-admin/src/views/mall/keyword.vue
View file @
324c8da3
...
...
@@ -82,7 +82,7 @@ export default {
components
:
{
Pagination
},
data
()
{
return
{
list
:
undefined
,
list
:
[]
,
total
:
0
,
listLoading
:
true
,
listQuery
:
{
...
...
@@ -119,7 +119,7 @@ export default {
getList
()
{
this
.
listLoading
=
true
listKeyword
(
this
.
listQuery
).
then
(
response
=>
{
this
.
list
=
response
.
data
.
data
.
items
this
.
list
=
response
.
data
.
data
.
list
this
.
total
=
response
.
data
.
data
.
total
this
.
listLoading
=
false
}).
catch
(()
=>
{
...
...
litemall-admin/src/views/mall/order.vue
View file @
324c8da3
...
...
@@ -3,10 +3,10 @@
<!-- 查询和其他操作 -->
<div
class=
"filter-container"
>
<el-input
v-model=
"listQuery.userId"
clearable
class=
"filter-item"
style=
"width: 200px;"
placeholder=
"请输入用户ID"
/>
<el-input
v-model=
"listQuery.orderSn"
clearable
class=
"filter-item"
style=
"width: 200px;"
placeholder=
"请输入订单编号"
/>
<el-input
v-model=
"listQuery.userId"
clearable
class=
"filter-item"
style=
"width: 200px;"
placeholder=
"请输入用户ID"
/>
<el-input
v-model=
"listQuery.orderSn"
clearable
class=
"filter-item"
style=
"width: 200px;"
placeholder=
"请输入订单编号"
/>
<el-select
v-model=
"listQuery.orderStatusArray"
multiple
style=
"width: 200px"
class=
"filter-item"
placeholder=
"请选择订单状态"
>
<el-option
v-for=
"(key, value) in statusMap"
:key=
"key"
:label=
"key"
:value=
"value"
/>
<el-option
v-for=
"(key, value) in statusMap"
:key=
"key"
:label=
"key"
:value=
"value"
/>
</el-select>
<el-button
v-permission=
"['GET /admin/order/list']"
class=
"filter-item"
type=
"primary"
icon=
"el-icon-search"
@
click=
"handleFilter"
>
查找
</el-button>
<el-button
:loading=
"downloadLoading"
class=
"filter-item"
type=
"primary"
icon=
"el-icon-download"
@
click=
"handleDownload"
>
导出
</el-button>
...
...
@@ -15,9 +15,9 @@
<!-- 查询结果 -->
<el-table
v-loading=
"listLoading"
:data=
"list"
element-loading-text=
"正在查询中。。。"
border
fit
highlight-current-row
>
<el-table-column
align=
"center"
min-width=
"100"
label=
"订单编号"
prop=
"orderSn"
/>
<el-table-column
align=
"center"
min-width=
"100"
label=
"订单编号"
prop=
"orderSn"
/>
<el-table-column
align=
"center"
label=
"用户ID"
prop=
"userId"
/>
<el-table-column
align=
"center"
label=
"用户ID"
prop=
"userId"
/>
<el-table-column
align=
"center"
label=
"订单状态"
prop=
"orderStatus"
>
<template
slot-scope=
"scope"
>
...
...
@@ -25,21 +25,21 @@
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"订单金额"
prop=
"orderPrice"
/>
<el-table-column
align=
"center"
label=
"订单金额"
prop=
"orderPrice"
/>
<el-table-column
align=
"center"
label=
"支付金额"
prop=
"actualPrice"
/>
<el-table-column
align=
"center"
label=
"支付金额"
prop=
"actualPrice"
/>
<el-table-column
align=
"center"
label=
"支付时间"
prop=
"payTime"
/>
<el-table-column
align=
"center"
label=
"支付时间"
prop=
"payTime"
/>
<el-table-column
align=
"center"
label=
"物流单号"
prop=
"shipSn"
/>
<el-table-column
align=
"center"
label=
"物流单号"
prop=
"shipSn"
/>
<el-table-column
align=
"center"
label=
"物流渠道"
prop=
"shipChannel"
/>
<el-table-column
align=
"center"
label=
"物流渠道"
prop=
"shipChannel"
/>
<el-table-column
align=
"center"
label=
"操作"
width=
"200"
class-name=
"small-padding fixed-width"
>
<
template
slot-scope=
"scope"
>
<el-button
v-permission=
"['GET /admin/order/detail']"
type=
"primary"
size=
"mini"
@
click=
"handleDetail(scope.row)"
>
详情
</el-button>
<el-button
v-permission=
"['POST /admin/order/ship']"
v-if=
"scope.row.orderStatus==201"
type=
"primary"
size=
"mini"
@
click=
"handleShip(scope.row)"
>
发货
</el-button>
<el-button
v-permission=
"['POST /admin/order/refund']"
v-if=
"scope.row.orderStatus==202"
type=
"primary"
size=
"mini"
@
click=
"handleRefund(scope.row)"
>
退款
</el-button>
<el-button
v-if=
"scope.row.orderStatus==201"
v-permission=
"['POST /admin/order/ship']"
type=
"primary"
size=
"mini"
@
click=
"handleShip(scope.row)"
>
发货
</el-button>
<el-button
v-if=
"scope.row.orderStatus==202||scope.row.orderStatus==204"
v-permission=
"['POST /admin/order/refund']"
type=
"primary"
size=
"mini"
@
click=
"handleRefund(scope.row)"
>
退款
</el-button>
</
template
>
</el-table-column>
</el-table>
...
...
@@ -48,71 +48,84 @@
<!-- 订单详情对话框 -->
<el-dialog
:visible.sync=
"orderDialogVisible"
title=
"订单详情"
width=
"800"
>
<el-form
:data=
"orderDetail"
label-position=
"left"
>
<el-form-item
label=
"订单编号"
>
<span>
{{ orderDetail.order.orderSn }}
</span>
</el-form-item>
<el-form-item
label=
"订单状态"
>
<el-tag>
{{ orderDetail.order.orderStatus | orderStatusFilter }}
</el-tag>
</el-form-item>
<el-form-item
label=
"订单用户"
>
<span>
{{ orderDetail.user.nickname }}
</span>
</el-form-item>
<el-form-item
label=
"用户留言"
>
<span>
{{ orderDetail.order.message }}
</span>
</el-form-item>
<el-form-item
label=
"收货信息"
>
<span>
(收货人){{ orderDetail.order.consignee }}
</span>
<span>
(手机号){{ orderDetail.order.mobile }}
</span>
<span>
(地址){{ orderDetail.order.address }}
</span>
</el-form-item>
<el-form-item
label=
"商品信息"
>
<el-table
:data=
"orderDetail.orderGoods"
border
fit
highlight-current-row
>
<el-table-column
align=
"center"
label=
"商品名称"
prop=
"goodsName"
/>
<el-table-column
align=
"center"
label=
"商品编号"
prop=
"goodsSn"
/>
<el-table-column
align=
"center"
label=
"货品规格"
prop=
"specifications"
/>
<el-table-column
align=
"center"
label=
"货品价格"
prop=
"price"
/>
<el-table-column
align=
"center"
label=
"货品数量"
prop=
"number"
/>
<el-table-column
align=
"center"
label=
"货品图片"
prop=
"picUrl"
>
<
template
slot-scope=
"scope"
>
<img
:src=
"scope.row.picUrl"
width=
"40"
>
</
template
>
</el-table-column>
</el-table>
</el-form-item>
<el-form-item
label=
"费用信息"
>
<span>
(实际费用){{ orderDetail.order.actualPrice }}元 =
(商品总价){{ orderDetail.order.goodsPrice }}元 +
(快递费用){{ orderDetail.order.freightPrice }}元 -
(优惠减免){{ orderDetail.order.couponPrice }}元 -
(积分减免){{ orderDetail.order.integralPrice }}元
</span>
</el-form-item>
<el-form-item
label=
"支付信息"
>
<span>
(支付渠道)微信支付
</span>
<span>
(支付时间){{ orderDetail.order.payTime }}
</span>
</el-form-item>
<el-form-item
label=
"快递信息"
>
<span>
(快递公司){{ orderDetail.order.shipChannel }}
</span>
<span>
(快递单号){{ orderDetail.order.shipSn }}
</span>
<span>
(发货时间){{ orderDetail.order.shipTime }}
</span>
</el-form-item>
<el-form-item
label=
"收货信息"
>
<span>
(确认收货时间){{ orderDetail.order.confirmTime }}
</span>
</el-form-item>
</el-form>
<section
ref=
"print"
>
<el-form
:data=
"orderDetail"
label-position=
"left"
>
<el-form-item
label=
"订单编号"
>
<span>
{{ orderDetail.order.orderSn }}
</span>
</el-form-item>
<el-form-item
label=
"订单状态"
>
<el-tag>
{{ orderDetail.order.orderStatus | orderStatusFilter }}
</el-tag>
</el-form-item>
<el-form-item
label=
"订单用户"
>
<span>
{{ orderDetail.user.nickname }}
</span>
</el-form-item>
<el-form-item
label=
"用户留言"
>
<span>
{{ orderDetail.order.message }}
</span>
</el-form-item>
<el-form-item
label=
"收货信息"
>
<span>
(收货人){{ orderDetail.order.consignee }}
</span>
<span>
(手机号){{ orderDetail.order.mobile }}
</span>
<span>
(地址){{ orderDetail.order.address }}
</span>
</el-form-item>
<el-form-item
label=
"商品信息"
>
<el-table
:data=
"orderDetail.orderGoods"
border
fit
highlight-current-row
>
<el-table-column
align=
"center"
label=
"商品名称"
prop=
"goodsName"
/>
<el-table-column
align=
"center"
label=
"商品编号"
prop=
"goodsSn"
/>
<el-table-column
align=
"center"
label=
"货品规格"
prop=
"specifications"
/>
<el-table-column
align=
"center"
label=
"货品价格"
prop=
"price"
/>
<el-table-column
align=
"center"
label=
"货品数量"
prop=
"number"
/>
<el-table-column
align=
"center"
label=
"货品图片"
prop=
"picUrl"
>
<
template
slot-scope=
"scope"
>
<img
:src=
"scope.row.picUrl"
width=
"40"
>
</
template
>
</el-table-column>
</el-table>
</el-form-item>
<el-form-item
label=
"费用信息"
>
<span>
(实际费用){{ orderDetail.order.actualPrice }}元 =
(商品总价){{ orderDetail.order.goodsPrice }}元 +
(快递费用){{ orderDetail.order.freightPrice }}元 -
(优惠减免){{ orderDetail.order.couponPrice }}元 -
(积分减免){{ orderDetail.order.integralPrice }}元
</span>
</el-form-item>
<el-form-item
label=
"支付信息"
>
<span>
(支付渠道)微信支付
</span>
<span>
(支付时间){{ orderDetail.order.payTime }}
</span>
</el-form-item>
<el-form-item
label=
"快递信息"
>
<span>
(快递公司){{ orderDetail.order.shipChannel }}
</span>
<span>
(快递单号){{ orderDetail.order.shipSn }}
</span>
<span>
(发货时间){{ orderDetail.order.shipTime }}
</span>
</el-form-item>
<el-form-item
label=
"退款信息"
>
<span>
(退款金额){{ orderDetail.order.refundAmount }}元
</span>
<span>
(退款类型){{ orderDetail.order.refundType }}
</span>
<span>
(退款备注){{ orderDetail.order.refundContent }}
</span>
<span>
(退款时间){{ orderDetail.order.refundTime }}
</span>
</el-form-item>
<el-form-item
label=
"收货信息"
>
<span>
(确认收货时间){{ orderDetail.order.confirmTime }}
</span>
</el-form-item>
</el-form>
</section>
<span
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"orderDialogVisible = false"
>
取 消
</el-button>
<el-button
type=
"primary"
@
click=
"printOrder"
>
打 印
</el-button>
</span>
</el-dialog>
<!-- 发货对话框 -->
<el-dialog
:visible.sync=
"shipDialogVisible"
title=
"发货"
>
<el-form
ref=
"shipForm"
:model=
"shipForm"
status-icon
label-position=
"left"
label-width=
"100px"
style=
"width: 400px; margin-left:50px;"
>
<el-form-item
label=
"快递公司"
prop=
"shipChannel"
>
<el-input
v-model=
"shipForm.shipChannel"
/>
<el-select
v-model=
"shipForm.shipChannel"
placeholder=
"请选择"
>
<el-option
v-for=
"item in channels"
:key=
"item.code"
:label=
"item.name"
:value=
"item.code"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"快递编号"
prop=
"shipSn"
>
<el-input
v-model=
"shipForm.shipSn"
/>
<el-input
v-model=
"shipForm.shipSn"
/>
</el-form-item>
</el-form>
<div
slot=
"footer"
class=
"dialog-footer"
>
...
...
@@ -125,7 +138,7 @@
<el-dialog
:visible.sync=
"refundDialogVisible"
title=
"退款"
>
<el-form
ref=
"refundForm"
:model=
"refundForm"
status-icon
label-position=
"left"
label-width=
"100px"
style=
"width: 400px; margin-left:50px;"
>
<el-form-item
label=
"退款金额"
prop=
"refundMoney"
>
<el-input
v-model=
"refundForm.refundMoney"
:disabled=
"true"
/>
<el-input
v-model=
"refundForm.refundMoney"
:disabled=
"true"
/>
</el-form-item>
</el-form>
<div
slot=
"footer"
class=
"dialog-footer"
>
...
...
@@ -137,12 +150,8 @@
</div>
</template>
<
style
>
</
style
>
<
script
>
import
{
listOrder
,
shipOrder
,
refundOrder
,
detail
Order
}
from
'
@/api/order
'
import
{
detailOrder
,
listOrder
,
listChannel
,
refundOrder
,
ship
Order
}
from
'
@/api/order
'
import
Pagination
from
'
@/components/Pagination
'
// Secondary package based on el-pagination
import
checkPermission
from
'
@/utils/permission
'
// 权限判断函数
...
...
@@ -150,9 +159,11 @@ const statusMap = {
101
:
'
未付款
'
,
102
:
'
用户取消
'
,
103
:
'
系统取消
'
,
200
:
'
已付款团购
'
,
201
:
'
已付款
'
,
202
:
'
申请退款
'
,
203
:
'
已退款
'
,
204
:
'
已超时团购
'
,
301
:
'
已发货
'
,
401
:
'
用户收货
'
,
402
:
'
系统收货
'
...
...
@@ -168,7 +179,7 @@ export default {
},
data
()
{
return
{
list
:
undefined
,
list
:
[]
,
total
:
0
,
listLoading
:
true
,
listQuery
:
{
...
...
@@ -198,18 +209,20 @@ export default {
refundMoney
:
undefined
},
refundDialogVisible
:
false
,
downloadLoading
:
false
downloadLoading
:
false
,
channels
:
[]
}
},
created
()
{
this
.
getList
()
this
.
getChannel
()
},
methods
:
{
checkPermission
,
getList
()
{
this
.
listLoading
=
true
listOrder
(
this
.
listQuery
).
then
(
response
=>
{
this
.
list
=
response
.
data
.
data
.
items
this
.
list
=
response
.
data
.
data
.
list
this
.
total
=
response
.
data
.
data
.
total
this
.
listLoading
=
false
}).
catch
(()
=>
{
...
...
@@ -218,6 +231,11 @@ export default {
this
.
listLoading
=
false
})
},
getChannel
()
{
listChannel
().
then
(
response
=>
{
this
.
channels
=
response
.
data
.
data
})
},
handleFilter
()
{
this
.
listQuery
.
page
=
1
this
.
getList
()
...
...
@@ -293,6 +311,10 @@ export default {
excel
.
export_json_to_excel2
(
tHeader
,
this
.
list
,
filterVal
,
'
订单信息
'
)
this
.
downloadLoading
=
false
})
},
printOrder
()
{
this
.
$print
(
this
.
$refs
.
print
)
this
.
orderDialogVisible
=
false
}
}
}
...
...
litemall-admin/src/views/mall/region.vue
View file @
324c8da3
...
...
@@ -35,7 +35,7 @@ export default {
},
data
()
{
return
{
list
:
undefined
,
list
:
[]
,
listLoading
:
true
,
downloadLoading
:
false
}
...
...
@@ -47,7 +47,7 @@ export default {
getList
()
{
this
.
listLoading
=
true
listRegion
().
then
(
response
=>
{
this
.
list
=
response
.
data
.
data
this
.
list
=
response
.
data
.
data
.
list
this
.
listLoading
=
false
}).
catch
(()
=>
{
this
.
list
=
[]
...
...
litemall-admin/src/views/promotion/ad.vue
View file @
324c8da3
...
...
@@ -60,10 +60,12 @@
:action=
"uploadPath"
:show-file-list=
"false"
:on-success=
"uploadUrl"
:before-upload=
"checkFileSize"
class=
"avatar-uploader"
accept=
".jpg,.jpeg,.png,.gif"
>
<img
v-if=
"dataForm.url"
:src=
"dataForm.url"
class=
"avatar"
>
<i
v-else
class=
"el-icon-plus avatar-uploader-icon"
/>
<div
slot=
"tip"
class=
"el-upload__tip"
>
只能上传jpg/png文件,且不超过1024kb
</div>
</el-upload>
</el-form-item>
<el-form-item
label=
"广告位置"
prop=
"position"
>
...
...
@@ -129,7 +131,7 @@ export default {
data
()
{
return
{
uploadPath
,
list
:
undefined
,
list
:
[]
,
total
:
0
,
listLoading
:
true
,
listQuery
:
{
...
...
@@ -182,7 +184,7 @@ export default {
this
.
listLoading
=
true
listAd
(
this
.
listQuery
)
.
then
(
response
=>
{
this
.
list
=
response
.
data
.
data
.
items
this
.
list
=
response
.
data
.
data
.
list
this
.
total
=
response
.
data
.
data
.
total
this
.
listLoading
=
false
})
...
...
@@ -218,6 +220,13 @@ export default {
uploadUrl
:
function
(
response
)
{
this
.
dataForm
.
url
=
response
.
data
.
url
},
checkFileSize
:
function
(
file
)
{
if
(
file
.
size
>
1048576
)
{
this
.
$message
.
error
(
`
${
file
.
name
}
文件大于1024KB,请选择小于1024KB大小的图片`
)
return
false
}
return
true
},
createData
()
{
this
.
$refs
[
'
dataForm
'
].
validate
(
valid
=>
{
if
(
valid
)
{
...
...
litemall-admin/src/views/promotion/coupon.vue
View file @
324c8da3
...
...
@@ -245,7 +245,7 @@ export default {
return
{
typeOptions
:
Object
.
assign
({},
defaultTypeOptions
),
statusOptions
:
Object
.
assign
({},
defaultStatusOptions
),
list
:
undefined
,
list
:
[]
,
total
:
0
,
listLoading
:
true
,
listQuery
:
{
...
...
@@ -297,7 +297,7 @@ export default {
this
.
listLoading
=
true
listCoupon
(
this
.
listQuery
)
.
then
(
response
=>
{
this
.
list
=
response
.
data
.
data
.
items
this
.
list
=
response
.
data
.
data
.
list
this
.
total
=
response
.
data
.
data
.
total
this
.
listLoading
=
false
})
...
...
litemall-admin/src/views/promotion/couponDetail.vue
View file @
324c8da3
...
...
@@ -154,7 +154,7 @@ export default {
typeOptions
:
Object
.
assign
({},
defaultTypeOptions
),
useStatusOptions
:
Object
.
assign
({},
defaultUseStatusOptions
),
coupon
:
{},
list
:
undefined
,
list
:
[]
,
total
:
0
,
listLoading
:
true
,
listQuery
:
{
...
...
@@ -187,7 +187,7 @@ export default {
this
.
listLoading
=
true
listCouponUser
(
this
.
listQuery
)
.
then
(
response
=>
{
this
.
list
=
response
.
data
.
data
.
items
this
.
list
=
response
.
data
.
data
.
list
this
.
total
=
response
.
data
.
data
.
total
this
.
listLoading
=
false
})
...
...
litemall-admin/src/views/promotion/grouponActivity.vue
View file @
324c8da3
...
...
@@ -3,14 +3,15 @@
<!-- 查询和其他操作 -->
<div
class=
"filter-container"
>
<el-input
v-model=
"listQuery.g
oods
Id"
clearable
class=
"filter-item"
style=
"width: 200px;"
placeholder=
"请输入
商品编号"
/>
<el-input
v-model=
"listQuery.g
rouponRule
Id"
clearable
class=
"filter-item"
style=
"width: 200px;"
placeholder=
"请输入
团购规则ID"
/>
<el-button
v-permission=
"['GET /admin/groupon/listRecord']"
class=
"filter-item"
type=
"primary"
icon=
"el-icon-search"
@
click=
"handleFilter"
>
查找
</el-button>
<el-button
:loading=
"downloadLoading"
class=
"filter-item"
type=
"primary"
icon=
"el-icon-download"
@
click=
"handleDownload"
>
导出
@
click=
"handleDownload"
>
导出
</el-button>
</div>
...
...
@@ -20,21 +21,21 @@
<el-table-column
type=
"expand"
>
<template
slot-scope=
"scope"
>
<el-table
:data=
"scope.row.subGroupons"
border
style=
"width: 100%"
>
<el-table-column
align=
"center"
label=
"订单ID"
prop=
"orderId"
/>
<el-table-column
align=
"center"
label=
"用户ID"
prop=
"userId"
/>
<el-table-column
align=
"center"
label=
"订单ID"
prop=
"orderId"
/>
<el-table-column
align=
"center"
label=
"用户ID"
prop=
"userId"
/>
</el-table>
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"订单ID"
prop=
"groupon.orderId"
/>
<el-table-column
align=
"center"
label=
"订单ID"
prop=
"groupon.orderId"
/>
<el-table-column
align=
"center"
label=
"用户ID"
prop=
"groupon.userId"
/>
<el-table-column
align=
"center"
label=
"用户ID"
prop=
"groupon.userId"
/>
<el-table-column
align=
"center"
label=
"参与人数"
prop=
"subGroupons.length"
/>
<el-table-column
align=
"center"
label=
"参与人数"
prop=
"subGroupons.length"
/>
<el-table-column
align=
"center"
label=
"团购折扣"
prop=
"rules.discount"
/>
<el-table-column
align=
"center"
label=
"团购折扣"
prop=
"rules.discount"
/>
<el-table-column
align=
"center"
label=
"团购要求"
prop=
"rules.discountMember"
/>
<el-table-column
align=
"center"
label=
"团购要求"
prop=
"rules.discountMember"
/>
<el-table-column
align=
"center"
property=
"iconUrl"
label=
"分享图片"
>
<
template
slot-scope=
"scope"
>
...
...
@@ -42,15 +43,15 @@
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"开始时间"
prop=
"rules.addTime"
/>
<el-table-column
align=
"center"
label=
"开始时间"
prop=
"rules.addTime"
/>
<el-table-column
align=
"center"
label=
"结束时间"
prop=
"rules.expireTime"
/>
<el-table-column
align=
"center"
label=
"结束时间"
prop=
"rules.expireTime"
/>
</el-table>
<pagination
v-show=
"total>0"
:total=
"total"
:page.sync=
"listQuery.page"
:limit.sync=
"listQuery.limit"
@
pagination=
"getList"
/>
<el-tooltip
placement=
"top"
content=
"返回顶部"
>
<back-to-top
:visibility-height=
"100"
/>
<back-to-top
:visibility-height=
"100"
/>
</el-tooltip>
</div>
...
...
@@ -93,7 +94,7 @@ export default {
listQuery
:
{
page
:
1
,
limit
:
20
,
g
oods
Id
:
undefined
,
g
rouponRule
Id
:
undefined
,
sort
:
'
add_time
'
,
order
:
'
desc
'
},
...
...
@@ -109,7 +110,7 @@ export default {
getList
()
{
this
.
listLoading
=
true
listRecord
(
this
.
listQuery
).
then
(
response
=>
{
this
.
list
=
response
.
data
.
data
.
items
this
.
list
=
response
.
data
.
data
.
list
this
.
total
=
response
.
data
.
data
.
total
this
.
listLoading
=
false
}).
catch
(()
=>
{
...
...
litemall-admin/src/views/promotion/grouponRule.vue
View file @
324c8da3
...
...
@@ -3,7 +3,7 @@
<!-- 查询和其他操作 -->
<div
class=
"filter-container"
>
<el-input
v-model=
"listQuery.goodsId"
clearable
class=
"filter-item"
style=
"width: 200px;"
placeholder=
"请输入商品编号"
/>
<el-input
v-model=
"listQuery.goodsId"
clearable
class=
"filter-item"
style=
"width: 200px;"
placeholder=
"请输入商品编号"
/>
<el-button
v-permission=
"['GET /admin/groupon/list']"
class=
"filter-item"
type=
"primary"
icon=
"el-icon-search"
@
click=
"handleFilter"
>
查找
</el-button>
<el-button
v-permission=
"['POST /admin/groupon/create']"
class=
"filter-item"
type=
"primary"
icon=
"el-icon-edit"
@
click=
"handleCreate"
>
添加
</el-button>
<el-button
...
...
@@ -11,15 +11,18 @@
class=
"filter-item"
type=
"primary"
icon=
"el-icon-download"
@
click=
"handleDownload"
>
导出
@
click=
"handleDownload"
>
导出
</el-button>
</div>
<!-- 查询结果 -->
<el-table
v-loading=
"listLoading"
:data=
"list"
element-loading-text=
"正在查询中。。。"
border
fit
highlight-current-row
>
<el-table-column
align=
"center"
label=
"
商品
ID"
prop=
"
goodsI
d"
/>
<el-table-column
align=
"center"
label=
"
团购规则
ID"
prop=
"
i
d"
/>
<el-table-column
align=
"center"
min-width=
"100"
label=
"名称"
prop=
"goodsName"
/>
<el-table-column
align=
"center"
label=
"商品ID"
prop=
"goodsId"
/>
<el-table-column
align=
"center"
min-width=
"100"
label=
"名称"
prop=
"goodsName"
/>
<el-table-column
align=
"center"
property=
"picUrl"
label=
"图片"
>
<template
slot-scope=
"scope"
>
...
...
@@ -27,13 +30,17 @@
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"团购优惠"
prop=
"discount"
/>
<el-table-column
align=
"center"
label=
"团购优惠"
prop=
"discount"
/>
<el-table-column
align=
"center"
label=
"团购要求"
prop=
"discountMember"
/>
<el-table-column
align=
"center"
label=
"团购要求"
prop=
"discountMember"
/>
<el-table-column
align=
"center"
label=
"开始时间"
prop=
"addTime"
/>
<el-table-column
align=
"center"
label=
"状态"
prop=
"status"
>
<
template
slot-scope=
"scope"
>
<el-tag
:type=
"scope.row.status === 0 ? 'success' : 'error' "
>
{{
statusMap
[
scope
.
row
.
status
]
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"结束时间"
prop=
"expireTime"
/>
<el-table-column
align=
"center"
label=
"结束时间"
prop=
"expireTime"
/>
<el-table-column
align=
"center"
label=
"操作"
width=
"200"
class-name=
"small-padding fixed-width"
>
<
template
slot-scope=
"scope"
>
...
...
@@ -51,23 +58,25 @@
:model=
"dataForm"
status-icon
label-position=
"left"
label-width=
"100px"
style=
"width: 400px; margin-left:50px;"
>
label-width=
"120px"
style=
"width: 400px; margin-left:50px;"
>
<el-form-item
label=
"商品ID"
prop=
"goodsId"
>
<el-input
v-model=
"dataForm.goodsId"
/>
<el-input
v-model=
"dataForm.goodsId"
/>
</el-form-item>
<el-form-item
label=
"团购折扣"
prop=
"discount"
>
<el-input
v-model=
"dataForm.discount"
/>
<el-input
v-model=
"dataForm.discount"
/>
</el-form-item>
<el-form-item
label=
"团购人数要求"
prop=
"discountMember"
>
<el-input
v-model=
"dataForm.discountMember"
/>
<el-input
v-model=
"dataForm.discountMember"
/>
</el-form-item>
<el-form-item
label=
"过期时间"
prop=
"expireTime"
>
<el-date-picker
v-model=
"dataForm.expireTime"
type=
"datetime"
placeholder=
"选择日期"
value-format=
"yyyy-MM-dd HH:mm:ss"
/>
value-format=
"yyyy-MM-dd HH:mm:ss"
/>
</el-form-item>
</el-form>
<div
slot=
"footer"
class=
"dialog-footer"
>
...
...
@@ -80,7 +89,7 @@
<pagination
v-show=
"total>0"
:total=
"total"
:page.sync=
"listQuery.page"
:limit.sync=
"listQuery.limit"
@
pagination=
"getList"
/>
<el-tooltip
placement=
"top"
content=
"返回顶部"
>
<back-to-top
:visibility-height=
"100"
/>
<back-to-top
:visibility-height=
"100"
/>
</el-tooltip>
</div>
...
...
@@ -120,8 +129,16 @@ export default {
update
:
'
编辑
'
,
create
:
'
创建
'
},
statusMap
:
[
'
正常
'
,
'
到期下线
'
,
'
提前下线
'
],
rules
:
{
goodsId
:
[{
required
:
true
,
message
:
'
商品不能为空
'
,
trigger
:
'
blur
'
}]
goodsId
:
[{
required
:
true
,
message
:
'
商品不能为空
'
,
trigger
:
'
blur
'
}],
discount
:
[{
required
:
true
,
message
:
'
团购折扣不能为空
'
,
trigger
:
'
blur
'
}],
discountMember
:
[{
required
:
true
,
message
:
'
团购人数不能为空
'
,
trigger
:
'
blur
'
}],
expireTime
:
[{
required
:
true
,
message
:
'
过期时间不能为空
'
,
trigger
:
'
blur
'
}]
}
}
},
...
...
@@ -132,7 +149,7 @@ export default {
getList
()
{
this
.
listLoading
=
true
listGroupon
(
this
.
listQuery
).
then
(
response
=>
{
this
.
list
=
response
.
data
.
data
.
items
this
.
list
=
response
.
data
.
data
.
list
this
.
total
=
response
.
data
.
data
.
total
this
.
listLoading
=
false
}).
catch
(()
=>
{
...
...
litemall-admin/src/views/promotion/topic.vue
View file @
324c8da3
...
...
@@ -35,7 +35,7 @@
<el-table-column
align=
"center"
label=
"阅读数量"
prop=
"readCount"
/>
<el-table-column
align=
"center"
label=
"操作"
min-width=
"
2
00"
class-name=
"small-padding fixed-width"
>
<el-table-column
align=
"center"
label=
"操作"
min-width=
"
1
00"
class-name=
"small-padding fixed-width"
>
<
template
slot-scope=
"scope"
>
<el-button
v-permission=
"['POST /admin/topic/update']"
type=
"primary"
size=
"mini"
@
click=
"handleUpdate(scope.row)"
>
编辑
</el-button>
<el-button
v-permission=
"['POST /admin/topic/delete']"
type=
"danger"
size=
"mini"
@
click=
"handleDelete(scope.row)"
>
删除
</el-button>
...
...
@@ -49,44 +49,6 @@
<back-to-top
:visibility-height=
"100"
/>
</el-tooltip>
<!-- 添加或修改对话框 -->
<el-dialog
:title=
"textMap[dialogStatus]"
:visible.sync=
"dialogFormVisible"
>
<el-form
ref=
"dataForm"
:rules=
"rules"
:model=
"dataForm"
status-icon
label-position=
"left"
label-width=
"100px"
style=
"width: 400px; margin-left:50px;"
>
<el-form-item
label=
"专题标题"
prop=
"title"
>
<el-input
v-model=
"dataForm.title"
/>
</el-form-item>
<el-form-item
label=
"专题子标题"
prop=
"subtitle"
>
<el-input
v-model=
"dataForm.subtitle"
/>
</el-form-item>
<el-form-item
label=
"专题图片"
prop=
"picUrl"
>
<el-upload
:headers=
"headers"
:action=
"uploadPath"
:show-file-list=
"false"
:on-success=
"uploadPicUrl"
class=
"avatar-uploader"
accept=
".jpg,.jpeg,.png,.gif"
>
<img
v-if=
"dataForm.picUrl"
:src=
"dataForm.picUrl"
class=
"avatar"
>
<i
v-else
class=
"el-icon-plus avatar-uploader-icon"
/>
</el-upload>
</el-form-item>
<el-form-item
style=
"width: 700px;"
label=
"专题内容"
>
<editor
:init=
"editorInit"
v-model=
"dataForm.content"
/>
</el-form-item>
<el-form-item
label=
"商品低价"
prop=
"price"
>
<el-input
v-model=
"dataForm.price"
/>
</el-form-item>
<el-form-item
label=
"阅读量"
prop=
"readCount"
>
<el-input
v-model=
"dataForm.readCount"
/>
</el-form-item>
</el-form>
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"dialogFormVisible = false"
>
取消
</el-button>
<el-button
v-if=
"dialogStatus=='create'"
type=
"primary"
@
click=
"createData"
>
确定
</el-button>
<el-button
v-else
type=
"primary"
@
click=
"updateData"
>
确定
</el-button>
</div>
</el-dialog>
</div>
</template>
...
...
@@ -120,20 +82,16 @@
</
style
>
<
script
>
import
{
listTopic
,
createTopic
,
updateTopic
,
deleteTopic
}
from
'
@/api/topic
'
import
{
createStorage
,
uploadPath
}
from
'
@/api/storage
'
import
{
listTopic
,
deleteTopic
}
from
'
@/api/topic
'
import
BackToTop
from
'
@/components/BackToTop
'
import
Editor
from
'
@tinymce/tinymce-vue
'
import
Pagination
from
'
@/components/Pagination
'
// Secondary package based on el-pagination
import
{
getToken
}
from
'
@/utils/auth
'
export
default
{
name
:
'
Topic
'
,
components
:
{
BackToTop
,
Editor
,
Pagination
},
components
:
{
BackToTop
,
Pagination
},
data
()
{
return
{
uploadPath
,
list
:
undefined
,
list
:
[],
total
:
0
,
listLoading
:
true
,
listQuery
:
{
...
...
@@ -144,65 +102,9 @@ export default {
sort
:
'
add_time
'
,
order
:
'
desc
'
},
dataForm
:
{
id
:
undefined
,
titile
:
undefined
,
subtitle
:
undefined
,
picUrl
:
undefined
,
content
:
''
,
price
:
undefined
,
readCount
:
undefined
,
goods
:
[]
},
contentDetail
:
''
,
contentDialogVisible
:
false
,
dialogFormVisible
:
false
,
dialogStatus
:
''
,
textMap
:
{
update
:
'
编辑
'
,
create
:
'
创建
'
},
rules
:
{
title
:
[
{
required
:
true
,
message
:
'
专题标题不能为空
'
,
trigger
:
'
blur
'
}
],
subtitle
:
[
{
required
:
true
,
message
:
'
专题子标题不能为空
'
,
trigger
:
'
blur
'
}
],
content
:
[
{
required
:
true
,
message
:
'
专题内容不能为空
'
,
trigger
:
'
blur
'
}
]
},
downloadLoading
:
false
,
editorInit
:
{
language
:
'
zh_CN
'
,
convert_urls
:
false
,
plugins
:
[
'
advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools importcss insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount
'
],
toolbar
:
[
'
searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscript code codesample
'
,
'
hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor fullscreen
'
],
images_upload_handler
:
function
(
blobInfo
,
success
,
failure
)
{
const
formData
=
new
FormData
()
formData
.
append
(
'
file
'
,
blobInfo
.
blob
())
createStorage
(
formData
)
.
then
(
res
=>
{
success
(
res
.
data
.
data
.
url
)
})
.
catch
(()
=>
{
failure
(
'
上传失败,请重新上传
'
)
})
}
}
}
},
computed
:
{
headers
()
{
return
{
'
X-Litemall-Admin-Token
'
:
getToken
()
}
downloadLoading
:
false
}
},
created
()
{
...
...
@@ -213,7 +115,7 @@ export default {
this
.
listLoading
=
true
listTopic
(
this
.
listQuery
)
.
then
(
response
=>
{
this
.
list
=
response
.
data
.
data
.
items
this
.
list
=
response
.
data
.
data
.
list
this
.
total
=
response
.
data
.
data
.
total
this
.
listLoading
=
false
})
...
...
@@ -227,88 +129,11 @@ export default {
this
.
listQuery
.
page
=
1
this
.
getList
()
},
resetForm
()
{
this
.
dataForm
=
{
id
:
undefined
,
titile
:
undefined
,
subtitle
:
undefined
,
picUrl
:
undefined
,
content
:
''
,
price
:
undefined
,
readCount
:
undefined
,
goods
:
[]
}
},
handleCreate
()
{
this
.
resetForm
()
this
.
dialogStatus
=
'
create
'
this
.
dialogFormVisible
=
true
this
.
$nextTick
(()
=>
{
this
.
$refs
[
'
dataForm
'
].
clearValidate
()
})
},
uploadPicUrl
:
function
(
response
)
{
this
.
dataForm
.
picUrl
=
response
.
data
.
url
},
createData
()
{
this
.
$refs
[
'
dataForm
'
].
validate
(
valid
=>
{
if
(
valid
)
{
createTopic
(
this
.
dataForm
)
.
then
(
response
=>
{
this
.
list
.
unshift
(
response
.
data
.
data
)
this
.
dialogFormVisible
=
false
this
.
$notify
.
success
({
title
:
'
成功
'
,
message
:
'
创建专题成功
'
})
})
.
catch
(
response
=>
{
this
.
$notify
.
error
({
title
:
'
失败
'
,
message
:
response
.
data
.
errmsg
})
})
}
})
},
showContent
(
content
)
{
this
.
contentDetail
=
content
this
.
contentDialogVisible
=
true
this
.
$router
.
push
({
path
:
'
/promotion/topic-create
'
})
},
handleUpdate
(
row
)
{
this
.
dataForm
=
Object
.
assign
({},
row
)
this
.
dialogStatus
=
'
update
'
this
.
dialogFormVisible
=
true
this
.
$nextTick
(()
=>
{
this
.
$refs
[
'
dataForm
'
].
clearValidate
()
})
},
updateData
()
{
this
.
$refs
[
'
dataForm
'
].
validate
(
valid
=>
{
if
(
valid
)
{
updateTopic
(
this
.
dataForm
)
.
then
(()
=>
{
for
(
const
v
of
this
.
list
)
{
if
(
v
.
id
===
this
.
dataForm
.
id
)
{
const
index
=
this
.
list
.
indexOf
(
v
)
this
.
list
.
splice
(
index
,
1
,
this
.
dataForm
)
break
}
}
this
.
dialogFormVisible
=
false
this
.
$notify
.
success
({
title
:
'
成功
'
,
message
:
'
更新专题成功
'
})
})
.
catch
(
response
=>
{
this
.
$notify
.
error
({
title
:
'
失败
'
,
message
:
response
.
data
.
errmsg
})
})
}
})
this
.
$router
.
push
({
path
:
'
/promotion/topic-edit
'
,
query
:
{
id
:
row
.
id
}})
},
handleDelete
(
row
)
{
deleteTopic
(
row
)
...
...
@@ -327,6 +152,10 @@ export default {
})
})
},
showContent
(
content
)
{
this
.
contentDetail
=
content
this
.
contentDialogVisible
=
true
},
handleDownload
()
{
this
.
downloadLoading
=
true
import
(
'
@/vendor/Export2Excel
'
).
then
(
excel
=>
{
...
...
litemall-admin/src/views/promotion/topicCreate.vue
0 → 100644
View file @
324c8da3
<
template
>
<div
class=
"app-container"
>
<el-form
ref=
"topic"
:rules=
"rules"
:model=
"topic"
status-icon
label-position=
"left"
label-width=
"100px"
style=
"width: 800px; margin-left:50px;"
>
<el-form-item
label=
"专题标题"
prop=
"title"
>
<el-input
v-model=
"topic.title"
/>
</el-form-item>
<el-form-item
label=
"专题子标题"
prop=
"subtitle"
>
<el-input
v-model=
"topic.subtitle"
/>
</el-form-item>
<el-form-item
label=
"专题图片"
prop=
"picUrl"
>
<el-upload
:headers=
"headers"
:action=
"uploadPath"
:show-file-list=
"false"
:on-success=
"uploadPicUrl"
class=
"avatar-uploader"
accept=
".jpg,.jpeg,.png,.gif"
>
<img
v-if=
"topic.picUrl"
:src=
"topic.picUrl"
class=
"avatar"
>
<i
v-else
class=
"el-icon-plus avatar-uploader-icon"
/>
</el-upload>
</el-form-item>
<el-form-item
label=
"专题内容"
prop=
"content"
>
<editor
:init=
"editorInit"
v-model=
"topic.content"
/>
</el-form-item>
<el-form-item
label=
"商品低价"
prop=
"price"
>
<el-input
v-model=
"topic.price"
/>
</el-form-item>
<el-form-item
label=
"阅读量"
prop=
"readCount"
>
<el-input
v-model=
"topic.readCount"
/>
</el-form-item>
<el-form-item
label=
"专题商品"
prop=
"goods"
>
<el-button
style=
"float:right;"
size=
"mini"
type=
"primary"
@
click=
"handleCreate()"
>
创建商品
</el-button>
<!-- 查询结果 -->
<el-table
:data=
"goodsList"
border
fit
highlight-current-row
>
<el-table-column
align=
"center"
label=
"商品ID"
prop=
"id"
/>
<el-table-column
align=
"center"
property=
"picUrl"
label=
"图片"
>
<template
slot-scope=
"scope"
>
<img
:src=
"scope.row.picUrl"
width=
"60"
>
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"商品名称"
prop=
"name"
/>
<el-table-column
align=
"center"
label=
"商品介绍"
prop=
"brief"
/>
<el-table-column
align=
"center"
label=
"操作"
class-name=
"small-padding fixed-width"
>
<
template
slot-scope=
"scope"
>
<el-button
type=
"danger"
size=
"mini"
@
click=
"handleDelete(scope.row)"
>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"handleCancel"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"handleConfirm"
>
确定
</el-button>
</div>
<el-dialog
:visible.sync=
"addVisiable"
title=
"添加商品"
>
<div
class=
"search"
>
<el-input
v-model=
"listQuery.goodsSn"
clearable
class=
"filter-item"
style=
"width: 200px;"
placeholder=
"请输入商品编号"
/>
<el-input
v-model=
"listQuery.name"
clearable
class=
"filter-item"
style=
"width: 200px;"
placeholder=
"请输入商品名称"
/>
<el-button
class=
"filter-item"
type=
"primary"
icon=
"el-icon-search"
@
click=
"handleFilter"
>
查找
</el-button>
<el-table
v-loading=
"listLoading"
:data=
"list"
element-loading-text=
"正在查询中。。。"
border
fit
highlight-current-row
@
selection-change=
"handleSelectionChange"
>
<el-table-column
type=
"selection"
width=
"55"
/>
<el-table-column
align=
"center"
label=
"商品ID"
prop=
"id"
/>
<el-table-column
align=
"center"
property=
"picUrl"
label=
"图片"
>
<
template
slot-scope=
"scope"
>
<img
:src=
"scope.row.picUrl"
width=
"40"
>
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"商品名称"
prop=
"name"
/>
</el-table>
<pagination
v-show=
"total>0"
:total=
"total"
:page.sync=
"listQuery.page"
:limit.sync=
"listQuery.limit"
@
pagination=
"getList"
/>
</div>
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"addVisiable = false"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"confirmAdd"
>
确定
</el-button>
</div>
</el-dialog>
</div>
</template>
<
style
>
.el-dialog
{
width
:
800px
;
}
.avatar-uploader
.el-upload
{
border
:
1px
dashed
#d9d9d9
;
border-radius
:
6px
;
cursor
:
pointer
;
position
:
relative
;
overflow
:
hidden
;
}
.avatar-uploader
.el-upload
:hover
{
border-color
:
#20a0ff
;
}
.avatar-uploader-icon
{
font-size
:
28px
;
color
:
#8c939d
;
width
:
120px
;
height
:
120px
;
line-height
:
120px
;
text-align
:
center
;
}
.avatar
{
width
:
145px
;
height
:
145px
;
display
:
block
;
}
</
style
>
<
script
>
import
{
createTopic
}
from
'
@/api/topic
'
import
{
listGoods
}
from
'
@/api/goods
'
import
{
createStorage
,
uploadPath
}
from
'
@/api/storage
'
import
BackToTop
from
'
@/components/BackToTop
'
import
Editor
from
'
@tinymce/tinymce-vue
'
import
Pagination
from
'
@/components/Pagination
'
// Secondary package based on el-pagination
import
{
getToken
}
from
'
@/utils/auth
'
export
default
{
name
:
'
TopicEdit
'
,
components
:
{
BackToTop
,
Editor
,
Pagination
},
data
()
{
return
{
uploadPath
,
id
:
0
,
topic
:
{
goods
:
[]
},
goodsList
:
[],
addVisiable
:
false
,
list
:
[],
total
:
0
,
listLoading
:
false
,
listQuery
:
{
page
:
1
,
limit
:
5
,
id
:
undefined
,
name
:
undefined
,
sort
:
'
add_time
'
,
order
:
'
desc
'
},
selectedlist
:
[],
rules
:
{
title
:
[
{
required
:
true
,
message
:
'
专题标题不能为空
'
,
trigger
:
'
blur
'
}
],
subtitle
:
[
{
required
:
true
,
message
:
'
专题子标题不能为空
'
,
trigger
:
'
blur
'
}
],
content
:
[
{
required
:
true
,
message
:
'
专题内容不能为空
'
,
trigger
:
'
blur
'
}
],
price
:
[
{
required
:
true
,
message
:
'
专题低价不能为空
'
,
trigger
:
'
blur
'
}
]
},
editorInit
:
{
language
:
'
zh_CN
'
,
convert_urls
:
false
,
height
:
500
,
plugins
:
[
'
advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools importcss insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount
'
],
toolbar
:
[
'
searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscript code codesample
'
,
'
hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor fullscreen
'
],
images_upload_handler
:
function
(
blobInfo
,
success
,
failure
)
{
const
formData
=
new
FormData
()
formData
.
append
(
'
file
'
,
blobInfo
.
blob
())
createStorage
(
formData
)
.
then
(
res
=>
{
success
(
res
.
data
.
data
.
url
)
})
.
catch
(()
=>
{
failure
(
'
上传失败,请重新上传
'
)
})
}
}
}
},
computed
:
{
headers
()
{
return
{
'
X-Litemall-Admin-Token
'
:
getToken
()
}
}
},
created
()
{
},
methods
:
{
getList
()
{
this
.
listLoading
=
true
listGoods
(
this
.
listQuery
).
then
(
response
=>
{
this
.
list
=
response
.
data
.
data
.
list
this
.
total
=
response
.
data
.
data
.
total
this
.
listLoading
=
false
}).
catch
(()
=>
{
this
.
list
=
[]
this
.
total
=
0
this
.
listLoading
=
false
})
},
handleFilter
()
{
this
.
listQuery
.
page
=
1
this
.
getList
()
},
handleSelectionChange
(
val
)
{
this
.
selectedlist
=
val
},
uploadPicUrl
:
function
(
response
)
{
this
.
topic
.
picUrl
=
response
.
data
.
url
},
handleCreate
()
{
this
.
listQuery
=
{
page
:
1
,
limit
:
5
,
id
:
undefined
,
name
:
undefined
,
sort
:
'
add_time
'
,
order
:
'
desc
'
}
this
.
list
=
[]
this
.
total
=
0
this
.
selectedlist
=
[]
this
.
addVisiable
=
true
},
confirmAdd
()
{
const
newGoodsIds
=
[]
const
newGoodsList
=
[]
this
.
selectedlist
.
forEach
(
item
=>
{
const
id
=
item
.
id
let
found
=
false
this
.
topic
.
goods
.
forEach
(
goodsId
=>
{
if
(
id
===
goodsId
)
{
found
=
true
}
})
if
(
!
found
)
{
newGoodsIds
.
push
(
id
)
newGoodsList
.
push
(
item
)
}
})
if
(
newGoodsIds
.
length
>
0
)
{
this
.
topic
.
goods
=
this
.
topic
.
goods
.
concat
(
newGoodsIds
)
this
.
goodsList
=
this
.
goodsList
.
concat
(
newGoodsList
)
}
this
.
addVisiable
=
false
},
handleDelete
(
row
)
{
for
(
var
index
=
0
;
index
<
this
.
topic
.
goods
.
length
;
index
++
)
{
if
(
row
.
id
===
this
.
topic
.
goods
[
index
])
{
this
.
topic
.
goods
.
splice
(
index
,
1
)
}
}
for
(
var
index2
=
0
;
index2
<
this
.
goodsList
.
length
;
index2
++
)
{
if
(
row
.
id
===
this
.
goodsList
[
index2
].
id
)
{
this
.
goodsList
.
splice
(
index2
,
1
)
}
}
},
handleCancel
()
{
this
.
$router
.
push
({
path
:
'
/promotion/topic
'
})
},
handleConfirm
()
{
this
.
$refs
[
'
topic
'
].
validate
(
valid
=>
{
if
(
valid
)
{
createTopic
(
this
.
topic
).
then
(
response
=>
{
this
.
$router
.
push
({
path
:
'
/promotion/topic
'
})
})
.
catch
(
response
=>
{
this
.
$notify
.
error
({
title
:
'
失败
'
,
message
:
response
.
data
.
errmsg
})
})
}
})
}
}
}
</
script
>
litemall-admin/src/views/promotion/topicEdit.vue
0 → 100644
View file @
324c8da3
<
template
>
<div
class=
"app-container"
>
<el-form
ref=
"topic"
:rules=
"rules"
:model=
"topic"
status-icon
label-position=
"left"
label-width=
"100px"
style=
"width: 800px; margin-left:50px;"
>
<el-form-item
label=
"专题标题"
prop=
"title"
>
<el-input
v-model=
"topic.title"
/>
</el-form-item>
<el-form-item
label=
"专题子标题"
prop=
"subtitle"
>
<el-input
v-model=
"topic.subtitle"
/>
</el-form-item>
<el-form-item
label=
"专题图片"
prop=
"picUrl"
>
<el-upload
:headers=
"headers"
:action=
"uploadPath"
:show-file-list=
"false"
:on-success=
"uploadPicUrl"
class=
"avatar-uploader"
accept=
".jpg,.jpeg,.png,.gif"
>
<img
v-if=
"topic.picUrl"
:src=
"topic.picUrl"
class=
"avatar"
>
<i
v-else
class=
"el-icon-plus avatar-uploader-icon"
/>
</el-upload>
</el-form-item>
<el-form-item
label=
"专题内容"
prop=
"content"
>
<editor
:init=
"editorInit"
v-model=
"topic.content"
/>
</el-form-item>
<el-form-item
label=
"商品低价"
prop=
"price"
>
<el-input
v-model=
"topic.price"
/>
</el-form-item>
<el-form-item
label=
"阅读量"
prop=
"readCount"
>
<el-input
v-model=
"topic.readCount"
/>
</el-form-item>
<el-form-item
label=
"专题商品"
prop=
"goods"
>
<el-button
style=
"float:right;"
size=
"mini"
type=
"primary"
@
click=
"handleCreate()"
>
创建商品
</el-button>
<!-- 查询结果 -->
<el-table
:data=
"goodsList"
border
fit
highlight-current-row
>
<el-table-column
align=
"center"
label=
"商品ID"
prop=
"id"
/>
<el-table-column
align=
"center"
property=
"picUrl"
label=
"图片"
>
<template
slot-scope=
"scope"
>
<img
:src=
"scope.row.picUrl"
width=
"60"
>
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"商品名称"
prop=
"name"
/>
<el-table-column
align=
"center"
label=
"商品介绍"
prop=
"brief"
/>
<el-table-column
align=
"center"
label=
"操作"
class-name=
"small-padding fixed-width"
>
<
template
slot-scope=
"scope"
>
<el-button
type=
"danger"
size=
"mini"
@
click=
"handleDelete(scope.row)"
>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"handleCancel"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"handleConfirm"
>
确定
</el-button>
</div>
<el-dialog
:visible.sync=
"addVisiable"
title=
"添加商品"
>
<div
class=
"search"
>
<el-input
v-model=
"listQuery.goodsSn"
clearable
class=
"filter-item"
style=
"width: 200px;"
placeholder=
"请输入商品编号"
/>
<el-input
v-model=
"listQuery.name"
clearable
class=
"filter-item"
style=
"width: 200px;"
placeholder=
"请输入商品名称"
/>
<el-button
class=
"filter-item"
type=
"primary"
icon=
"el-icon-search"
@
click=
"handleFilter"
>
查找
</el-button>
<el-table
v-loading=
"listLoading"
:data=
"list"
element-loading-text=
"正在查询中。。。"
border
fit
highlight-current-row
@
selection-change=
"handleSelectionChange"
>
<el-table-column
type=
"selection"
width=
"55"
/>
<el-table-column
align=
"center"
label=
"商品ID"
prop=
"id"
/>
<el-table-column
align=
"center"
property=
"picUrl"
label=
"图片"
>
<
template
slot-scope=
"scope"
>
<img
:src=
"scope.row.picUrl"
width=
"40"
>
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"商品名称"
prop=
"name"
/>
</el-table>
<pagination
v-show=
"total>0"
:total=
"total"
:page.sync=
"listQuery.page"
:limit.sync=
"listQuery.limit"
@
pagination=
"getList"
/>
</div>
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"addVisiable = false"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"confirmAdd"
>
确定
</el-button>
</div>
</el-dialog>
</div>
</template>
<
style
>
.el-dialog
{
width
:
800px
;
}
.avatar-uploader
.el-upload
{
border
:
1px
dashed
#d9d9d9
;
border-radius
:
6px
;
cursor
:
pointer
;
position
:
relative
;
overflow
:
hidden
;
}
.avatar-uploader
.el-upload
:hover
{
border-color
:
#20a0ff
;
}
.avatar-uploader-icon
{
font-size
:
28px
;
color
:
#8c939d
;
width
:
120px
;
height
:
120px
;
line-height
:
120px
;
text-align
:
center
;
}
.avatar
{
width
:
145px
;
height
:
145px
;
display
:
block
;
}
</
style
>
<
script
>
import
{
readTopic
,
updateTopic
}
from
'
@/api/topic
'
import
{
listGoods
}
from
'
@/api/goods
'
import
{
createStorage
,
uploadPath
}
from
'
@/api/storage
'
import
BackToTop
from
'
@/components/BackToTop
'
import
Editor
from
'
@tinymce/tinymce-vue
'
import
Pagination
from
'
@/components/Pagination
'
// Secondary package based on el-pagination
import
{
getToken
}
from
'
@/utils/auth
'
export
default
{
name
:
'
TopicEdit
'
,
components
:
{
BackToTop
,
Editor
,
Pagination
},
data
()
{
return
{
uploadPath
,
id
:
0
,
topic
:
{},
goodsList
:
[],
addVisiable
:
false
,
list
:
[],
total
:
0
,
listLoading
:
false
,
listQuery
:
{
page
:
1
,
limit
:
5
,
id
:
undefined
,
name
:
undefined
,
sort
:
'
add_time
'
,
order
:
'
desc
'
},
selectedlist
:
[],
rules
:
{
title
:
[
{
required
:
true
,
message
:
'
专题标题不能为空
'
,
trigger
:
'
blur
'
}
],
subtitle
:
[
{
required
:
true
,
message
:
'
专题子标题不能为空
'
,
trigger
:
'
blur
'
}
],
content
:
[
{
required
:
true
,
message
:
'
专题内容不能为空
'
,
trigger
:
'
blur
'
}
],
price
:
[
{
required
:
true
,
message
:
'
专题低价不能为空
'
,
trigger
:
'
blur
'
}
]
},
editorInit
:
{
language
:
'
zh_CN
'
,
convert_urls
:
false
,
height
:
500
,
plugins
:
[
'
advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools importcss insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount
'
],
toolbar
:
[
'
searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscript code codesample
'
,
'
hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor fullscreen
'
],
images_upload_handler
:
function
(
blobInfo
,
success
,
failure
)
{
const
formData
=
new
FormData
()
formData
.
append
(
'
file
'
,
blobInfo
.
blob
())
createStorage
(
formData
)
.
then
(
res
=>
{
success
(
res
.
data
.
data
.
url
)
})
.
catch
(()
=>
{
failure
(
'
上传失败,请重新上传
'
)
})
}
}
}
},
computed
:
{
headers
()
{
return
{
'
X-Litemall-Admin-Token
'
:
getToken
()
}
}
},
created
()
{
if
(
this
.
$route
.
query
.
id
==
null
)
{
return
}
this
.
id
=
this
.
$route
.
query
.
id
this
.
getTopic
()
},
methods
:
{
getTopic
()
{
this
.
listLoading
=
true
readTopic
({
id
:
this
.
id
})
.
then
(
response
=>
{
this
.
topic
=
response
.
data
.
data
.
topic
this
.
goodsList
=
response
.
data
.
data
.
goodsList
this
.
listLoading
=
false
})
.
catch
(()
=>
{
this
.
topic
=
{}
this
.
goodsList
=
[]
this
.
listLoading
=
false
})
},
getList
()
{
this
.
listLoading
=
true
listGoods
(
this
.
listQuery
).
then
(
response
=>
{
this
.
list
=
response
.
data
.
data
.
list
this
.
total
=
response
.
data
.
data
.
total
this
.
listLoading
=
false
}).
catch
(()
=>
{
this
.
list
=
[]
this
.
total
=
0
this
.
listLoading
=
false
})
},
handleFilter
()
{
this
.
listQuery
.
page
=
1
this
.
getList
()
},
handleSelectionChange
(
val
)
{
this
.
selectedlist
=
val
},
uploadPicUrl
:
function
(
response
)
{
this
.
topic
.
picUrl
=
response
.
data
.
url
},
handleCreate
()
{
this
.
listQuery
=
{
page
:
1
,
limit
:
5
,
id
:
undefined
,
name
:
undefined
,
sort
:
'
add_time
'
,
order
:
'
desc
'
}
this
.
list
=
[]
this
.
total
=
0
this
.
selectedlist
=
[]
this
.
addVisiable
=
true
},
confirmAdd
()
{
const
newGoodsIds
=
[]
const
newGoodsList
=
[]
this
.
selectedlist
.
forEach
(
item
=>
{
const
id
=
item
.
id
let
found
=
false
this
.
topic
.
goods
.
forEach
(
goodsId
=>
{
if
(
id
===
goodsId
)
{
found
=
true
}
})
if
(
!
found
)
{
newGoodsIds
.
push
(
id
)
newGoodsList
.
push
(
item
)
}
})
if
(
newGoodsIds
.
length
>
0
)
{
this
.
topic
.
goods
=
this
.
topic
.
goods
.
concat
(
newGoodsIds
)
this
.
goodsList
=
this
.
goodsList
.
concat
(
newGoodsList
)
}
this
.
addVisiable
=
false
},
handleDelete
(
row
)
{
for
(
var
index
=
0
;
index
<
this
.
topic
.
goods
.
length
;
index
++
)
{
if
(
row
.
id
===
this
.
topic
.
goods
[
index
])
{
this
.
topic
.
goods
.
splice
(
index
,
1
)
}
}
for
(
var
index2
=
0
;
index2
<
this
.
goodsList
.
length
;
index2
++
)
{
if
(
row
.
id
===
this
.
goodsList
[
index2
].
id
)
{
this
.
goodsList
.
splice
(
index2
,
1
)
}
}
},
handleCancel
()
{
this
.
$router
.
push
({
path
:
'
/promotion/topic
'
})
},
handleConfirm
()
{
this
.
$refs
[
'
topic
'
].
validate
(
valid
=>
{
if
(
valid
)
{
updateTopic
(
this
.
topic
).
then
(
response
=>
{
this
.
$router
.
push
({
path
:
'
/promotion/topic
'
})
})
.
catch
(
response
=>
{
this
.
$notify
.
error
({
title
:
'
失败
'
,
message
:
response
.
data
.
errmsg
})
})
}
})
}
}
}
</
script
>
litemall-admin/src/views/redirect/index.vue
View file @
324c8da3
<
script
>
export
default
{
beforeC
reate
()
{
c
reate
d
()
{
const
{
params
,
query
}
=
this
.
$route
const
{
path
}
=
params
this
.
$router
.
replace
({
path
:
'
/
'
+
path
,
query
})
...
...
litemall-admin/src/views/sys/admin.vue
View file @
324c8da3
...
...
@@ -162,7 +162,7 @@ export default {
roleOptions
()
.
then
(
response
=>
{
this
.
roleOptions
=
response
.
data
.
data
this
.
roleOptions
=
response
.
data
.
data
.
list
})
},
methods
:
{
...
...
@@ -178,7 +178,7 @@ export default {
this
.
listLoading
=
true
listAdmin
(
this
.
listQuery
)
.
then
(
response
=>
{
this
.
list
=
response
.
data
.
data
.
items
this
.
list
=
response
.
data
.
data
.
list
this
.
total
=
response
.
data
.
data
.
total
this
.
listLoading
=
false
})
...
...
litemall-admin/src/views/sys/log.vue
View file @
324c8da3
...
...
@@ -79,7 +79,7 @@ export default {
this
.
listLoading
=
true
listLog
(
this
.
listQuery
)
.
then
(
response
=>
{
this
.
list
=
response
.
data
.
data
.
items
this
.
list
=
response
.
data
.
data
.
list
this
.
total
=
response
.
data
.
data
.
total
this
.
listLoading
=
false
})
...
...
Prev
1
…
6
7
8
9
10
11
12
13
14
…
20
Next
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