Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Administrator
mall4cloud
Commits
a21f5a9a
Commit
a21f5a9a
authored
Dec 20, 2023
by
liang.tang
Browse files
mall4cloud
parents
Pipeline
#244
canceled with stages
Changes
355
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1555 additions
and
0 deletions
+1555
-0
front-end/mall4cloud-multishop-master/src/lang/zh.js
front-end/mall4cloud-multishop-master/src/lang/zh.js
+125
-0
front-end/mall4cloud-multishop-master/src/layout/components/AppMain.vue
...4cloud-multishop-master/src/layout/components/AppMain.vue
+49
-0
front-end/mall4cloud-multishop-master/src/layout/components/Navbar.vue
...l4cloud-multishop-master/src/layout/components/Navbar.vue
+201
-0
front-end/mall4cloud-multishop-master/src/layout/components/Sidebar/FixiOSBug.js
...ltishop-master/src/layout/components/Sidebar/FixiOSBug.js
+26
-0
front-end/mall4cloud-multishop-master/src/layout/components/Sidebar/Item.vue
...d-multishop-master/src/layout/components/Sidebar/Item.vue
+41
-0
front-end/mall4cloud-multishop-master/src/layout/components/Sidebar/Link.vue
...d-multishop-master/src/layout/components/Sidebar/Link.vue
+43
-0
front-end/mall4cloud-multishop-master/src/layout/components/Sidebar/Logo.vue
...d-multishop-master/src/layout/components/Sidebar/Logo.vue
+82
-0
front-end/mall4cloud-multishop-master/src/layout/components/Sidebar/SidebarItem.vue
...shop-master/src/layout/components/Sidebar/SidebarItem.vue
+98
-0
front-end/mall4cloud-multishop-master/src/layout/components/Sidebar/index.vue
...-multishop-master/src/layout/components/Sidebar/index.vue
+52
-0
front-end/mall4cloud-multishop-master/src/layout/components/TagsView/ScrollPane.vue
...shop-master/src/layout/components/TagsView/ScrollPane.vue
+94
-0
front-end/mall4cloud-multishop-master/src/layout/components/TagsView/index.vue
...multishop-master/src/layout/components/TagsView/index.vue
+294
-0
front-end/mall4cloud-multishop-master/src/layout/components/index.js
...all4cloud-multishop-master/src/layout/components/index.js
+4
-0
front-end/mall4cloud-multishop-master/src/layout/index.vue
front-end/mall4cloud-multishop-master/src/layout/index.vue
+95
-0
front-end/mall4cloud-multishop-master/src/layout/mixin/ResizeHandler.js
...4cloud-multishop-master/src/layout/mixin/ResizeHandler.js
+45
-0
front-end/mall4cloud-multishop-master/src/main.js
front-end/mall4cloud-multishop-master/src/main.js
+60
-0
front-end/mall4cloud-multishop-master/src/permission.js
front-end/mall4cloud-multishop-master/src/permission.js
+84
-0
front-end/mall4cloud-multishop-master/src/router/index.js
front-end/mall4cloud-multishop-master/src/router/index.js
+79
-0
front-end/mall4cloud-multishop-master/src/settings.js
front-end/mall4cloud-multishop-master/src/settings.js
+42
-0
front-end/mall4cloud-multishop-master/src/store/getters.js
front-end/mall4cloud-multishop-master/src/store/getters.js
+16
-0
front-end/mall4cloud-multishop-master/src/store/index.js
front-end/mall4cloud-multishop-master/src/store/index.js
+25
-0
No files found.
Too many changes to show.
To preserve performance only
355 of 355+
files are displayed.
Plain diff
Email patch
front-end/mall4cloud-multishop-master/src/lang/zh.js
0 → 100644
View file @
a21f5a9a
import
spu
from
'
./product/spu/zh
'
import
attr
from
'
./product/attr/zh
'
import
category
from
'
./product/category/zh
'
import
notice
from
'
./multishop/notice/zh
'
import
shopUser
from
'
./multishop/shop-user/zh
'
import
hotSearch
from
'
./multishop/hot-search/zh
'
import
imgbox
from
'
./biz/imgbox/zh
'
import
role
from
'
./rbac/role/zh
'
import
menu
from
'
./rbac/menu/zh
'
import
menuPermission
from
'
./rbac/menu-permission/zh
'
import
selector
from
'
./components/category-selector/zh
'
import
shopUserAccount
from
'
./multishop/shop-user-account/zh
'
import
order
from
'
./order/order/zh
'
import
constant
from
'
./constant/zh
'
import
admin
from
'
./admin/zh
'
import
shop
from
'
./shop/zh
'
import
address
from
'
./address/zh
'
import
product
from
'
./product/zh
'
export
default
{
language
:
'
简体中文
'
,
route
:
{
dashboard
:
'
首页
'
},
tip
:
{
select
:
'
请选择
'
,
input
:
'
请输入
'
},
navbar
:
{
logOut
:
'
退出登录
'
},
tagsView
:
{
refresh
:
'
刷新
'
,
close
:
'
关闭
'
,
closeOthers
:
'
关闭其它
'
,
closeAll
:
'
关闭所有
'
},
date
:
{
start
:
'
开始日期
'
,
end
:
'
结束日期
'
,
tip
:
'
至
'
,
t
:
'
今日
'
,
y
:
'
昨日
'
,
n
:
'
近7天
'
,
m
:
'
近30天
'
,
a
:
'
全部
'
},
login
:
{
title
:
'
系统登录
'
,
logIn
:
'
登录
'
,
username
:
'
账号
'
,
password
:
'
密码
'
,
any
:
'
随便填
'
,
thirdparty
:
'
第三方登录
'
,
thirdpartyTips
:
'
本地不能模拟,请结合自己业务进行模拟!!!
'
},
unit
:
{
dollar
:
'
元
'
},
table
:
{
search
:
'
搜索
'
,
add
:
'
添加
'
,
export
:
'
导出
'
,
id
:
'
序号
'
,
status
:
'
状态
'
,
actions
:
'
操作
'
,
edit
:
'
编辑
'
,
create
:
'
新建
'
,
clear
:
'
清空
'
,
publish
:
'
发布
'
,
delete
:
'
删除
'
,
cancel
:
'
取消
'
,
confirm
:
'
确定
'
,
offline
:
'
下线
'
,
seq
:
'
排序号
'
,
actionSuccess
:
'
操作成功
'
,
tips
:
'
提示
'
,
noNull
:
'
不能为空
'
,
sureToDelete
:
'
确定进行删除操作?
'
,
createTime
:
'
创建时间
'
,
updateTime
:
'
更新时间
'
},
action
:
{
putOnShelf
:
'
上架
'
,
offShelf
:
'
下架
'
},
rbac
:
{
role
,
menu
,
menuPermission
},
multishop
:
{
hotSearch
,
shopUser
,
notice
,
shopUserAccount
},
product
:
{
...
product
,
attr
,
category
,
spu
},
biz
:
{
imgbox
},
order
:
{
order
},
constant
:
{
...
constant
},
admin
:
{
...
admin
},
shop
:
{
...
shop
},
address
:
{
...
address
},
components
:
{
selector
}
}
front-end/mall4cloud-multishop-master/src/layout/components/AppMain.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<section
class=
"app-main"
>
<transition
name=
"fade-transform"
mode=
"out-in"
>
<keep-alive
:include=
"cachedViews"
>
<router-view
:key=
"key"
/>
</keep-alive>
</transition>
</section>
</
template
>
<
script
>
export
default
{
name
:
'
AppMain
'
,
computed
:
{
cachedViews
()
{
return
this
.
$store
.
state
.
tagsView
.
cachedViews
},
key
()
{
return
this
.
$route
.
path
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.app-main
{
position
:
relative
;
width
:
1034px
;
background
:
#FFFFFF
;
overflow
:
hidden
;
margin-left
:
20px
;
}
.hasTagsView
{
.app-main
{
/* 134 = navbar + tags-view + margin-bottom = 94 + 20 + 20 */
min-height
:
calc
(
100vh
-
134px
);
}
}
</
style
>
<
style
lang=
"scss"
>
// fix css style bug in open el-dialog
.el-popup-parent--hidden
{
.fixed-header
{
padding-right
:
15px
;
}
}
</
style
>
front-end/mall4cloud-multishop-master/src/layout/components/Navbar.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<div
class=
"navbar"
>
<div
class=
"navbar-content"
>
<!-- 1.左边部分 -->
<div
class=
"left-menu"
>
<div
class=
"title"
>
商家后台
</div>
</div>
<!-- 2.右边部分 -->
<div
class=
"right-menu"
>
<div
v-if=
"device !== 'mobile'"
class=
"switch-language font-item"
>
<el-dropdown
@
command=
"handleSetLanguage"
>
<span
class=
"el-dropdown-link"
>
语言
<i
class=
"el-icon-arrow-down el-icon--right"
/>
</span>
<el-dropdown-menu
slot=
"dropdown"
>
<el-dropdown-item
:disabled=
"language === 'zh'"
command=
"zh"
>
中文
</el-dropdown-item>
<el-dropdown-item
:disabled=
"language === 'en'"
command=
"en"
>
English
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<el-dropdown
class=
"avatar-container"
trigger=
"click"
>
<div
class=
"avatar-wrapper"
>
<div
class=
"img-box"
>
<img
:src=
"avatar + '?imageView2/1/w/80/h/80'"
class=
"user-avatar"
>
</div>
<div
class=
"user-name"
>
{{
name
}}
</div>
<i
class=
"el-icon-caret-bottom"
/>
</div>
<el-dropdown-menu
slot=
"dropdown"
>
<el-dropdown-item
@
click.native=
"logout"
>
<span
style=
"display: block"
>
{{
$t
(
"
navbar.logOut
"
)
}}
</span>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</div>
</
template
>
<
script
>
import
{
mapGetters
}
from
'
vuex
'
export
default
{
data
()
{
return
{
isHavePlatformNotice
:
true
,
// 是否有新的平台公告
isHaveNewsBox
:
true
// 是否有新消息
}
},
computed
:
{
...
mapGetters
([
'
name
'
,
'
avatar
'
,
'
device
'
]),
language
()
{
return
this
.
$store
.
getters
.
language
}
},
methods
:
{
async
logout
()
{
await
this
.
$store
.
dispatch
(
'
user/logout
'
)
this
.
$router
.
push
(
`/login?redirect=
${
this
.
$route
.
fullPath
}
`
)
},
// 切换语言
handleSetLanguage
(
lang
)
{
this
.
$i18n
.
locale
=
lang
this
.
$store
.
dispatch
(
'
app/setLanguage
'
,
lang
)
this
.
$message
({
message
:
'
Switch Language Success
'
,
type
:
'
success
'
})
},
// 跳转到平台公告
toPlatformNotice
()
{
// this.$router.push('')
},
// 跳转到消息盒子
toNewsBox
()
{
// this.$router.push('')
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.navbar
{
display
:
flex
;
align-items
:
center
;
min-width
:
1260px
;
width
:
100%
;
height
:
60px
;
background
:
#323232
;
overflow
:
hidden
;
.navbar-content
{
display
:
flex
;
align-items
:
center
;
width
:
1260px
;
margin
:
0
auto
;
// 1.左边部分
.left-menu
{
display
:
flex
;
align-items
:
flex-end
;
.logo-img
{
width
:
104px
;
height
:
22px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.title
{
font-size
:
14px
;
color
:
#ffffff
;
margin-left
:
4px
;
}
}
// 2.右边部分
.right-menu
{
display
:
flex
;
align-items
:
center
;
margin-left
:
auto
;
.font-item
{
display
:
flex
;
align-items
:
center
;
font-size
:
14px
;
font-weight
:
400
;
color
:
#ffffff
;
&
::after
{
display
:
block
;
width
:
1px
;
height
:
18px
;
content
:
""
;
background
:
#ffffff
;
opacity
:
0
.5
;
margin
:
0
15px
;
}
.el-dropdown
{
color
:
#ffffff
;
}
}
.platform-notice
,
.news-box
{
position
:
relative
;
span
{
position
:
absolute
;
top
:
0
;
right
:
23px
;
display
:
block
;
width
:
5px
;
height
:
5px
;
background
:
#fac94f
;
border-radius
:
50%
;
}
}
.avatar-container
{
.avatar-wrapper
{
display
:
flex
;
align-items
:
center
;
position
:
relative
;
.img-box
{
width
:
30px
;
height
:
30px
;
border-radius
:
50%
;
background
:
#fff
;
cursor
:
pointer
;
overflow
:
hidden
;
}
.user-avatar
{
width
:
100%
;
height
:
100%
;
}
.user-name
{
font-size
:
14px
;
font-weight
:
400
;
color
:
#ffffff
;
padding-left
:
10px
;
padding-right
:
6px
;
}
.el-icon-caret-bottom
{
font-size
:
12px
;
color
:
#ffffff
;
cursor
:
pointer
;
}
}
}
}
}
}
</
style
>
front-end/mall4cloud-multishop-master/src/layout/components/Sidebar/FixiOSBug.js
0 → 100644
View file @
a21f5a9a
export
default
{
computed
:
{
device
()
{
return
this
.
$store
.
state
.
app
.
device
}
},
mounted
()
{
// In order to fix the click on menu on the ios device will trigger the mouseleave bug
// https://github.com/PanJiaChen/vue-element-admin/issues/1135
this
.
fixBugIniOS
()
},
methods
:
{
fixBugIniOS
()
{
const
$subMenu
=
this
.
$refs
.
subMenu
if
(
$subMenu
)
{
const
handleMouseleave
=
$subMenu
.
handleMouseleave
$subMenu
.
handleMouseleave
=
(
e
)
=>
{
if
(
this
.
device
===
'
mobile
'
)
{
return
}
handleMouseleave
(
e
)
}
}
}
}
}
front-end/mall4cloud-multishop-master/src/layout/components/Sidebar/Item.vue
0 → 100644
View file @
a21f5a9a
<
script
>
export
default
{
name
:
'
MenuItem
'
,
functional
:
true
,
props
:
{
icon
:
{
type
:
String
,
default
:
''
},
title
:
{
type
:
String
,
default
:
''
}
},
render
(
h
,
context
)
{
const
{
icon
,
title
}
=
context
.
props
const
vnodes
=
[]
if
(
icon
)
{
if
(
icon
.
includes
(
'
el-icon
'
))
{
vnodes
.
push
(
<
i
class
=
{[
icon
,
'
sub-el-icon
'
]}
/>
)
}
else
{
vnodes
.
push
(
<
svg
-
icon
icon
-
class
=
{
icon
}
/>
)
}
}
if
(
title
)
{
vnodes
.
push
(
<
span
slot
=
'
title
'
>
{(
title
)}
<
/span>
)
}
return
vnodes
}
}
</
script
>
<
style
scoped
>
.sub-el-icon
{
color
:
currentColor
;
width
:
1em
;
/* height: 1em; */
}
</
style
>
front-end/mall4cloud-multishop-master/src/layout/components/Sidebar/Link.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<component
:is=
"type"
v-bind=
"linkProps(to)"
>
<slot
/>
</component>
</
template
>
<
script
>
import
{
isExternal
}
from
'
@/utils/validate
'
export
default
{
props
:
{
to
:
{
type
:
String
,
required
:
true
}
},
computed
:
{
isExternal
()
{
return
isExternal
(
this
.
to
)
},
type
()
{
if
(
this
.
isExternal
)
{
return
'
a
'
}
return
'
router-link
'
}
},
methods
:
{
linkProps
(
to
)
{
if
(
this
.
isExternal
)
{
return
{
href
:
to
,
target
:
'
_blank
'
,
rel
:
'
noopener
'
}
}
return
{
to
:
to
}
}
}
}
</
script
>
front-end/mall4cloud-multishop-master/src/layout/components/Sidebar/Logo.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<div
class=
"sidebar-logo-container"
:class=
"
{'collapse':collapse}">
<transition
name=
"sidebarLogoFade"
>
<router-link
v-if=
"collapse"
key=
"collapse"
class=
"sidebar-logo-link"
to=
"/"
>
<img
v-if=
"logo"
:src=
"logo"
class=
"sidebar-logo"
>
<h1
v-else
class=
"sidebar-title"
>
{{
title
}}
</h1>
</router-link>
<router-link
v-else
key=
"expand"
class=
"sidebar-logo-link"
to=
"/"
>
<img
v-if=
"logo"
:src=
"logo"
class=
"sidebar-logo"
>
<h1
class=
"sidebar-title"
>
{{
title
}}
</h1>
</router-link>
</transition>
</div>
</
template
>
<
script
>
export
default
{
name
:
'
SidebarLogo
'
,
props
:
{
collapse
:
{
type
:
Boolean
,
required
:
true
}
},
data
()
{
return
{
title
:
'
mall4cloud
'
,
logo
:
'
https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png
'
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.sidebarLogoFade-enter-active
{
transition
:
opacity
1
.5s
;
}
.sidebarLogoFade-enter
,
.sidebarLogoFade-leave-to
{
opacity
:
0
;
}
.sidebar-logo-container
{
position
:
relative
;
width
:
100%
;
height
:
50px
;
line-height
:
50px
;
background
:
#2b2f3a
;
text-align
:
center
;
overflow
:
hidden
;
&
.sidebar-logo-link
{
height
:
100%
;
width
:
100%
;
&
.sidebar-logo
{
width
:
32px
;
height
:
32px
;
vertical-align
:
middle
;
margin-right
:
12px
;
}
&
.sidebar-title
{
display
:
inline-block
;
margin
:
0
;
color
:
#fff
;
font-weight
:
600
;
line-height
:
50px
;
font-size
:
14px
;
font-family
:
Avenir
,
Helvetica
Neue
,
Arial
,
Helvetica
,
sans-serif
;
vertical-align
:
middle
;
}
}
&
.collapse
{
.sidebar-logo
{
margin-right
:
0px
;
}
}
}
</
style
>
front-end/mall4cloud-multishop-master/src/layout/components/Sidebar/SidebarItem.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<div
v-if=
"!item.hidden"
>
<template
v-if=
"hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow"
>
<app-link
v-if=
"onlyOneChild.meta"
:to=
"resolvePath(onlyOneChild.path)"
>
<el-menu-item
:index=
"resolvePath(onlyOneChild.path)"
:class=
"
{'submenu-title-noDropdown':!isNest}">
<item
:icon=
"onlyOneChild.meta.icon||(item.meta&&item.meta.icon)"
:title=
"generateTitle(onlyOneChild.meta.title)"
/>
</el-menu-item>
</app-link>
</
template
>
<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 && item.meta.icon"
:title=
"generateTitle(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
{
generateTitle
}
from
'
@/utils/i18n
'
import
{
isExternal
}
from
'
@/utils/validate
'
import
Item
from
'
./Item
'
import
AppLink
from
'
./Link
'
import
FixiOSBug
from
'
./FixiOSBug
'
export
default
{
name
:
'
SidebarItem
'
,
components
:
{
Item
,
AppLink
},
mixins
:
[
FixiOSBug
],
props
:
{
// route object
item
:
{
type
:
Object
,
required
:
true
},
isNest
:
{
type
:
Boolean
,
default
:
false
},
basePath
:
{
type
:
String
,
default
:
''
}
},
data
()
{
// To fix https://github.com/PanJiaChen/vue-admin-template/issues/237
// TODO: refactor with render function
this
.
onlyOneChild
=
null
return
{}
},
methods
:
{
hasOneShowingChild
(
children
=
[],
parent
)
{
const
showingChildren
=
children
.
filter
(
item
=>
{
if
(
item
.
hidden
)
{
return
false
}
else
{
// Temp set(will be used if only has one showing child)
this
.
onlyOneChild
=
item
return
true
}
})
// When there is only one child router, the child router is displayed by default
if
(
showingChildren
.
length
===
1
)
{
return
true
}
// Show parent if there are no child router to display
if
(
showingChildren
.
length
===
0
)
{
this
.
onlyOneChild
=
{
...
parent
,
path
:
''
,
noShowingChildren
:
true
}
return
true
}
return
false
},
resolvePath
(
routePath
)
{
if
(
isExternal
(
routePath
))
{
return
routePath
}
if
(
isExternal
(
this
.
basePath
))
{
return
this
.
basePath
}
return
path
.
resolve
(
this
.
basePath
,
routePath
)
},
generateTitle
}
}
</
script
>
front-end/mall4cloud-multishop-master/src/layout/components/Sidebar/index.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<div>
<el-scrollbar
wrap-class=
"scrollbar-wrapper"
>
<el-menu
:default-openeds=
"openeds"
:default-active=
"activeMenu"
:background-color=
"variables.menuBg"
:text-color=
"variables.menuText"
:unique-opened=
"false"
:active-text-color=
"variables.menuActiveText"
>
<sidebar-item
v-for=
"route in permission_routes"
:key=
"route.path"
:item=
"route"
:base-path=
"route.path"
/>
</el-menu>
</el-scrollbar>
</div>
</
template
>
<
script
>
import
{
mapGetters
}
from
'
vuex
'
import
SidebarItem
from
'
./SidebarItem
'
import
variables
from
'
@/styles/variables.scss
'
export
default
{
components
:
{
SidebarItem
},
computed
:
{
...
mapGetters
([
'
permission_routes
'
]),
activeMenu
()
{
const
route
=
this
.
$route
const
{
meta
,
path
}
=
route
// if set path, the sidebar will highlight the path you set
if
(
meta
.
activeMenu
)
{
return
meta
.
activeMenu
}
return
path
},
// 所有sub-menu的index的数组(用来默认展开所有菜单)
openeds
()
{
const
permission_routes
=
this
.
permission_routes
const
ids
=
[]
permission_routes
.
forEach
(
route
=>
{
ids
.
push
(
route
.
path
)
})
return
ids
},
variables
()
{
return
variables
}
}
}
</
script
>
front-end/mall4cloud-multishop-master/src/layout/components/TagsView/ScrollPane.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<el-scrollbar
ref=
"scrollContainer"
:vertical=
"false"
class=
"scroll-container"
@
wheel.native.prevent=
"handleScroll"
>
<slot
/>
</el-scrollbar>
</
template
>
<
script
>
const
tagAndTagSpacing
=
4
// tagAndTagSpacing
export
default
{
name
:
'
ScrollPane
'
,
data
()
{
return
{
left
:
0
}
},
computed
:
{
scrollWrapper
()
{
return
this
.
$refs
.
scrollContainer
.
$refs
.
wrap
}
},
mounted
()
{
this
.
scrollWrapper
.
addEventListener
(
'
scroll
'
,
this
.
emitScroll
,
true
)
},
beforeDestroy
()
{
this
.
scrollWrapper
.
removeEventListener
(
'
scroll
'
,
this
.
emitScroll
)
},
methods
:
{
handleScroll
(
e
)
{
const
eventDelta
=
e
.
wheelDelta
||
-
e
.
deltaY
*
40
const
$scrollWrapper
=
this
.
scrollWrapper
$scrollWrapper
.
scrollLeft
=
$scrollWrapper
.
scrollLeft
+
eventDelta
/
4
},
emitScroll
()
{
this
.
$emit
(
'
scroll
'
)
},
moveToTarget
(
currentTag
)
{
const
$container
=
this
.
$refs
.
scrollContainer
.
$el
const
$containerWidth
=
$container
.
offsetWidth
const
$scrollWrapper
=
this
.
scrollWrapper
const
tagList
=
this
.
$parent
.
$refs
.
tag
let
firstTag
=
null
let
lastTag
=
null
// find first tag and last tag
if
(
tagList
.
length
>
0
)
{
firstTag
=
tagList
[
0
]
lastTag
=
tagList
[
tagList
.
length
-
1
]
}
if
(
firstTag
===
currentTag
)
{
$scrollWrapper
.
scrollLeft
=
0
}
else
if
(
lastTag
===
currentTag
)
{
$scrollWrapper
.
scrollLeft
=
$scrollWrapper
.
scrollWidth
-
$containerWidth
}
else
{
// find preTag and nextTag
const
currentIndex
=
tagList
.
findIndex
(
item
=>
item
===
currentTag
)
const
prevTag
=
tagList
[
currentIndex
-
1
]
const
nextTag
=
tagList
[
currentIndex
+
1
]
// the tag's offsetLeft after of nextTag
const
afterNextTagOffsetLeft
=
nextTag
.
$el
.
offsetLeft
+
nextTag
.
$el
.
offsetWidth
+
tagAndTagSpacing
// the tag's offsetLeft before of prevTag
const
beforePrevTagOffsetLeft
=
prevTag
.
$el
.
offsetLeft
-
tagAndTagSpacing
if
(
afterNextTagOffsetLeft
>
$scrollWrapper
.
scrollLeft
+
$containerWidth
)
{
$scrollWrapper
.
scrollLeft
=
afterNextTagOffsetLeft
-
$containerWidth
}
else
if
(
beforePrevTagOffsetLeft
<
$scrollWrapper
.
scrollLeft
)
{
$scrollWrapper
.
scrollLeft
=
beforePrevTagOffsetLeft
}
}
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.scroll-container
{
white-space
:
nowrap
;
position
:
relative
;
overflow
:
hidden
;
width
:
100%
;
::v-deep
{
.el-scrollbar__bar
{
bottom
:
0px
;
}
.el-scrollbar__wrap
{
height
:
49px
;
}
}
}
</
style
>
front-end/mall4cloud-multishop-master/src/layout/components/TagsView/index.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<div
id=
"tags-view-container"
class=
"tags-view-container"
>
<scroll-pane
ref=
"scrollPane"
class=
"tags-view-wrapper"
@
scroll=
"handleScroll"
>
<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 }"
tag="span"
class="tags-view-item"
@click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''"
@contextmenu.prevent.native="openMenu(tag,$event)"
>
{{
generateTitle
(
tag
.
title
)
}}
<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)"
>
{{
$t
(
'
tagsView.refresh
'
)
}}
</li>
<li
v-if=
"!isAffix(selectedTag)"
@
click=
"closeSelectedTag(selectedTag)"
>
{{
$t
(
'
tagsView.close
'
)
}}
</li>
<li
@
click=
"closeOthersTags"
>
{{
$t
(
'
tagsView.closeOthers
'
)
}}
</li>
<li
@
click=
"closeAllTags(selectedTag)"
>
{{
$t
(
'
tagsView.closeAll
'
)
}}
</li>
</ul>
</div>
</
template
>
<
script
>
import
ScrollPane
from
'
./ScrollPane
'
import
{
generateTitle
}
from
'
@/utils/i18n
'
import
path
from
'
path
'
export
default
{
components
:
{
ScrollPane
},
data
()
{
return
{
visible
:
false
,
top
:
0
,
left
:
0
,
selectedTag
:
{},
affixTags
:
[]
}
},
computed
:
{
visitedViews
()
{
return
this
.
$store
.
state
.
tagsView
.
visitedViews
},
routes
()
{
return
this
.
$store
.
state
.
permission
.
routes
}
},
watch
:
{
$route
()
{
this
.
addTags
()
this
.
moveToCurrentTag
()
},
visible
(
value
)
{
if
(
value
)
{
document
.
body
.
addEventListener
(
'
click
'
,
this
.
closeMenu
)
}
else
{
document
.
body
.
removeEventListener
(
'
click
'
,
this
.
closeMenu
)
}
}
},
mounted
()
{
this
.
initTags
()
this
.
addTags
()
},
methods
:
{
generateTitle
,
// generateTitle by vue-i18n
isActive
(
route
)
{
return
route
.
path
===
this
.
$route
.
path
},
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
(
'
tagsView/addView
'
,
this
.
$route
)
}
return
false
},
moveToCurrentTag
()
{
const
tags
=
this
.
$refs
.
tag
this
.
$nextTick
(()
=>
{
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
(
'
tagsView/updateVisitedView
'
,
this
.
$route
)
}
break
}
}
})
},
refreshSelectedTag
(
view
)
{
this
.
$store
.
dispatch
(
'
tagsView/delCachedView
'
,
view
).
then
(()
=>
{
const
{
fullPath
}
=
view
this
.
$nextTick
(()
=>
{
this
.
$router
.
replace
({
path
:
'
/redirect
'
+
fullPath
})
})
})
},
closeSelectedTag
(
view
)
{
this
.
$store
.
dispatch
(
'
tagsView/delView
'
,
view
).
then
(({
visitedViews
})
=>
{
if
(
this
.
isActive
(
view
))
{
this
.
toLastView
(
visitedViews
,
view
)
}
})
},
closeOthersTags
()
{
this
.
$router
.
push
(
this
.
selectedTag
)
this
.
$store
.
dispatch
(
'
tagsView/delOthersViews
'
,
this
.
selectedTag
).
then
(()
=>
{
this
.
moveToCurrentTag
()
})
},
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
===
'
order/order
'
)
{
// to reload home page
this
.
$router
.
replace
({
path
:
'
/redirect
'
+
view
.
fullPath
})
}
else
{
this
.
$router
.
push
(
'
/
'
)
}
}
},
openMenu
(
tag
,
e
)
{
const
menuMinWidth
=
105
const
offsetLeft
=
this
.
$el
.
getBoundingClientRect
().
left
// container margin left
const
offsetWidth
=
this
.
$el
.
offsetWidth
// container width
const
maxLeft
=
offsetWidth
-
menuMinWidth
// left boundary
const
left
=
e
.
clientX
-
offsetLeft
+
15
// 15: margin right
if
(
left
>
maxLeft
)
{
this
.
left
=
maxLeft
}
else
{
this
.
left
=
left
}
this
.
top
=
e
.
clientY
this
.
visible
=
true
this
.
selectedTag
=
tag
},
closeMenu
()
{
this
.
visible
=
false
},
handleScroll
()
{
this
.
closeMenu
()
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.tags-view-container
{
height
:
34px
;
width
:
100%
;
background
:
#fff
;
border-bottom
:
1px
solid
#d8dce5
;
box-shadow
:
0
1px
3px
0
rgba
(
0
,
0
,
0
,
.12
)
,
0
0
3px
0
rgba
(
0
,
0
,
0
,
.04
);
.tags-view-wrapper
{
.tags-view-item
{
display
:
inline-block
;
position
:
relative
;
cursor
:
pointer
;
height
:
26px
;
line-height
:
26px
;
border
:
1px
solid
#d8dce5
;
color
:
#495060
;
background
:
#fff
;
padding
:
0
8px
;
font-size
:
12px
;
margin-left
:
5px
;
margin-top
:
4px
;
&
:first-of-type
{
margin-left
:
15px
;
}
&
:last-of-type
{
margin-right
:
15px
;
}
&
.active
{
background-color
:
#42b983
;
color
:
#fff
;
border-color
:
#42b983
;
&
::before
{
content
:
''
;
background
:
#fff
;
display
:
inline-block
;
width
:
8px
;
height
:
8px
;
border-radius
:
50%
;
position
:
relative
;
margin-right
:
2px
;
}
}
}
}
.contextmenu
{
margin
:
0
;
background
:
#fff
;
z-index
:
3000
;
position
:
absolute
;
list-style-type
:
none
;
padding
:
5px
0
;
border-radius
:
4px
;
font-size
:
12px
;
font-weight
:
400
;
color
:
#333
;
box-shadow
:
2px
2px
3px
0
rgba
(
0
,
0
,
0
,
.3
);
li
{
margin
:
0
;
padding
:
7px
16px
;
cursor
:
pointer
;
&
:hover
{
background
:
#eee
;
}
}
}
}
</
style
>
<
style
lang=
"scss"
>
//reset element css of el-icon-close
.tags-view-wrapper
{
.tags-view-item
{
.el-icon-close
{
width
:
16px
;
height
:
16px
;
vertical-align
:
2px
;
border-radius
:
50%
;
text-align
:
center
;
transition
:
all
.3s
cubic-bezier
(
.645
,
.045
,
.355
,
1
);
transform-origin
:
100%
50%
;
&
:before
{
transform
:
scale
(
.6
);
display
:
inline-block
;
vertical-align
:
-3px
;
}
&
:hover
{
background-color
:
#b4bccc
;
color
:
#fff
;
}
}
}
}
</
style
>
front-end/mall4cloud-multishop-master/src/layout/components/index.js
0 → 100644
View file @
a21f5a9a
export
{
default
as
AppMain
}
from
'
./AppMain
'
export
{
default
as
Navbar
}
from
'
./Navbar
'
export
{
default
as
Sidebar
}
from
'
./Sidebar/index.vue
'
export
{
default
as
TagsView
}
from
'
./TagsView/index.vue
'
front-end/mall4cloud-multishop-master/src/layout/index.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<div
:class=
"classObj"
class=
"app-wrapper"
>
<div
v-if=
"device==='mobile'&&sidebar.opened"
class=
"drawer-bg"
@
click=
"handleClickOutside"
/>
<div
:class=
"
{'fixed-header':fixedHeader}">
<navbar
/>
</div>
<div
class=
"main-container"
>
<sidebar
class=
"sidebar-container"
:class=
"
{'fixed-sidebar':isCoverHead===true}" />
<app-main
/>
</div>
</div>
</
template
>
<
script
>
import
{
AppMain
,
Navbar
,
Sidebar
}
from
'
./components
'
import
ResizeMixin
from
'
./mixin/ResizeHandler
'
import
{
mapState
}
from
'
vuex
'
export
default
{
name
:
'
Layout
'
,
components
:
{
AppMain
,
Navbar
,
Sidebar
},
mixins
:
[
ResizeMixin
],
data
()
{
return
{
isCoverHead
:
false
}
},
computed
:
{
...
mapState
({
sidebar
:
state
=>
state
.
app
.
sidebar
,
device
:
state
=>
state
.
app
.
device
,
showSettings
:
state
=>
state
.
settings
.
showSettings
,
needTagsView
:
state
=>
state
.
settings
.
tagsView
,
fixedHeader
:
state
=>
state
.
settings
.
fixedHeader
}),
classObj
()
{
return
{
withoutAnimation
:
this
.
sidebar
.
withoutAnimation
,
mobile
:
this
.
device
===
'
mobile
'
}
}
},
mounted
()
{
window
.
addEventListener
(
'
scroll
'
,
()
=>
{
const
scrollTop
=
document
.
documentElement
.
scrollTop
||
document
.
body
.
scrollTop
||
window
.
pageYOffset
if
(
scrollTop
>
80
)
{
this
.
isCoverHead
=
true
}
else
{
this
.
isCoverHead
=
false
}
})
},
methods
:
{
handleClickOutside
()
{
this
.
$store
.
dispatch
(
'
app/closeSideBar
'
,
{
withoutAnimation
:
false
})
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
@import
"~@/styles/mixin.scss"
;
@import
"~@/styles/variables.scss"
;
.app-wrapper
{
@include
clearfix
;
position
:
relative
;
width
:
100%
;
height
:
100%
;
background
:
#f9f9f9
;
&
.mobile.openSidebar
{
position
:
fixed
;
top
:
0
;
}
}
.drawer-bg
{
background
:
#000
;
opacity
:
0
.3
;
width
:
100%
;
top
:
0
;
height
:
100%
;
position
:
absolute
;
z-index
:
999
;
}
.mobile
.fixed-header
{
width
:
100%
;
}
</
style
>
front-end/mall4cloud-multishop-master/src/layout/mixin/ResizeHandler.js
0 → 100644
View file @
a21f5a9a
import
store
from
'
@/store
'
const
{
body
}
=
document
const
WIDTH
=
992
// refer to Bootstrap's responsive design
export
default
{
watch
:
{
$route
(
route
)
{
if
(
this
.
device
===
'
mobile
'
&&
this
.
sidebar
.
opened
)
{
store
.
dispatch
(
'
app/closeSideBar
'
,
{
withoutAnimation
:
false
})
}
}
},
beforeMount
()
{
window
.
addEventListener
(
'
resize
'
,
this
.
$_resizeHandler
)
},
beforeDestroy
()
{
window
.
removeEventListener
(
'
resize
'
,
this
.
$_resizeHandler
)
},
mounted
()
{
const
isMobile
=
this
.
$_isMobile
()
if
(
isMobile
)
{
store
.
dispatch
(
'
app/toggleDevice
'
,
'
mobile
'
)
store
.
dispatch
(
'
app/closeSideBar
'
,
{
withoutAnimation
:
true
})
}
},
methods
:
{
// use $_ for mixins properties
// https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
$_isMobile
()
{
const
rect
=
body
.
getBoundingClientRect
()
return
rect
.
width
-
1
<
WIDTH
},
$_resizeHandler
()
{
if
(
!
document
.
hidden
)
{
const
isMobile
=
this
.
$_isMobile
()
store
.
dispatch
(
'
app/toggleDevice
'
,
isMobile
?
'
mobile
'
:
'
desktop
'
)
if
(
isMobile
)
{
store
.
dispatch
(
'
app/closeSideBar
'
,
{
withoutAnimation
:
true
})
}
}
}
}
}
front-end/mall4cloud-multishop-master/src/main.js
0 → 100644
View file @
a21f5a9a
import
Vue
from
'
vue
'
import
Cookies
from
'
js-cookie
'
import
'
normalize.css/normalize.css
'
// a modern alternative to CSS resets
import
Element
from
'
element-ui
'
import
echarts
from
'
echarts
'
import
'
./styles/element-variables.scss
'
import
'
@/styles/index.scss
'
// global css
import
App
from
'
./App
'
import
store
from
'
./store
'
import
router
from
'
./router
'
import
i18n
from
'
./lang
'
// internationalization
import
'
./icons
'
// icon
import
'
./permission
'
// permission control
import
moment
from
'
moment
'
import
*
as
filters
from
'
./filters
'
// global filters
Vue
.
use
(
Element
,
{
size
:
Cookies
.
get
(
'
size
'
)
||
'
medium
'
,
// set element-ui default size
i18n
:
(
key
,
value
)
=>
i18n
.
t
(
key
,
value
)
})
// 挂载全局
Vue
.
prototype
.
$echarts
=
echarts
// register global utility filters
Object
.
keys
(
filters
).
forEach
(
key
=>
{
Vue
.
filter
(
key
,
filters
[
key
])
})
Vue
.
config
.
productionTip
=
false
new
Vue
({
el
:
'
#app
'
,
router
,
store
,
i18n
,
render
:
h
=>
h
(
App
)
})
// 自定义moment(js时间组件)
moment
.
locale
(
'
zh-cn
'
,
{
longDateFormat
:
{
LT
:
'
HH:mm
'
,
LTS
:
'
HH:mm:ss
'
,
L
:
'
YYYY-MM-DD
'
,
LL
:
'
YYYY-MM-DD HH:mm:ss
'
},
week
:
{
// GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
dow
:
1
,
// 星期一, 是一个星期的第一天
doy
:
4
// 1月4日所在的的一周是一年的第一周
}
})
front-end/mall4cloud-multishop-master/src/permission.js
0 → 100644
View file @
a21f5a9a
import
router
from
'
./router
'
import
store
from
'
./store
'
import
NProgress
from
'
nprogress
'
// progress bar
import
'
nprogress/nprogress.css
'
// progress bar style
import
{
getToken
}
from
'
@/utils/auth
'
// get token from cookie
import
getPageTitle
from
'
@/utils/get-page-title
'
NProgress
.
configure
({
showSpinner
:
false
})
// NProgress Configuration
const
whiteList
=
[
'
/login
'
]
// no redirect whitelist
router
.
beforeEach
(
async
(
to
,
from
,
next
)
=>
{
// start progress bar
NProgress
.
start
()
// set page title
document
.
title
=
getPageTitle
(
to
.
meta
.
title
)
// determine whether the user has logged in
const
hasToken
=
getToken
()
if
(
hasToken
)
{
if
(
to
.
path
===
'
/login
'
)
{
// if is logged in, redirect to the home page
next
({
path
:
'
/
'
})
NProgress
.
done
()
// hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939
}
else
{
// debugger
// determine whether the user has obtained his permission roles through getInfo
const
hasRoles
=
store
.
getters
.
roles
&&
store
.
getters
.
roles
.
length
>
0
if
(
hasRoles
)
{
next
()
}
else
{
try
{
// 获取用户信息
const
userInfo
=
await
store
.
dispatch
(
'
user/getUserInfo
'
)
// 获取权限信息
// get user info
// note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
store
.
dispatch
(
'
user/listPermissions
'
)
let
menuIds
=
[]
if
(
!
userInfo
.
isAdmin
)
{
// 获取菜单信息
menuIds
=
await
store
.
dispatch
(
'
user/listMenuIds
'
)
}
// generate accessible routes map based on roles
const
accessRoutes
=
await
store
.
dispatch
(
'
permission/generateRoutes
'
,
menuIds
)
// 404 page must be placed at the end !!!
accessRoutes
.
push
({
path
:
'
*
'
,
redirect
:
'
/404
'
,
hidden
:
true
})
// dynamically add accessible routes
router
.
addRoutes
(
accessRoutes
)
// hack method to ensure that addRoutes is complete
// set the replace: true, so the navigation will not leave a history record
next
({
...
to
,
replace
:
true
})
}
catch
(
error
)
{
// remove token and go to login page to re-login
await
store
.
dispatch
(
'
user/resetToken
'
)
next
(
`/login?redirect=
${
to
.
path
}
`
)
NProgress
.
done
()
}
}
}
}
else
{
/* has no token*/
if
(
whiteList
.
indexOf
(
to
.
path
)
!==
-
1
)
{
// in the free login whitelist, go directly
next
()
}
else
{
// other pages that do not have permission to access are redirected to the login page.
next
(
`/login?redirect=
${
to
.
path
}
`
)
NProgress
.
done
()
}
}
})
router
.
afterEach
(()
=>
{
// finish progress bar
NProgress
.
done
()
})
front-end/mall4cloud-multishop-master/src/router/index.js
0 → 100644
View file @
a21f5a9a
import
Vue
from
'
vue
'
import
Router
from
'
vue-router
'
Vue
.
use
(
Router
)
/* Layout */
import
Layout
from
'
@/layout
'
/**
* Note: sub-menu only appear when route children.length >= 1
* Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html
*
* hidden: true if set true, item will not show in the sidebar(default is false)
* alwaysShow: true if set true, will always show the root menu
* if not set alwaysShow, when item has more than one children route,
* it will becomes nested mode, otherwise not show the root menu
* redirect: noRedirect if set noRedirect will no redirect in the breadcrumb
* name:'router-name' the name is used by <keep-alive> (must set!!!)
* meta : {
roles: ['admin','editor'] control the page roles (you can set multiple roles)
title: 'title' the name show in sidebar and breadcrumb (recommend set)
icon: 'svg-name'/'el-icon-x' the icon show in the sidebar
noCache: true if set true, the page will no be cached(default is false)
affix: true if set true, the tag will affix in the tags-view
breadcrumb: false if set false, the item will hidden in breadcrumb(default is true)
activeMenu: '/example/list' if set path, the sidebar will highlight the path you set
}
*/
/**
* constantRoutes
* a base page that does not have permission requirements
* all roles can be accessed
*/
export
const
constantRoutes
=
[
{
path
:
'
/
'
,
redirect
:
'
/order/order
'
},
{
path
:
'
/redirect
'
,
component
:
Layout
,
hidden
:
true
,
children
:
[
{
path
:
'
/redirect/:path(.*)
'
,
component
:
()
=>
import
(
'
@/views/common/redirect/index
'
)
}
]
},
{
path
:
'
/login
'
,
component
:
()
=>
import
(
'
@/views/common/login/index
'
),
hidden
:
true
},
{
path
:
'
/404
'
,
component
:
()
=>
import
(
'
@/views/common/error-page/404
'
),
hidden
:
true
},
{
path
:
'
/401
'
,
component
:
()
=>
import
(
'
@/views/common/error-page/401
'
),
hidden
:
true
}
]
const
createRouter
=
()
=>
new
Router
({
// mode: 'history', // require service support
scrollBehavior
:
()
=>
({
y
:
0
}),
routes
:
constantRoutes
})
const
router
=
createRouter
()
// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export
function
resetRouter
()
{
const
newRouter
=
createRouter
()
router
.
matcher
=
newRouter
.
matcher
// reset router
}
export
default
router
front-end/mall4cloud-multishop-master/src/settings.js
0 → 100644
View file @
a21f5a9a
module
.
exports
=
{
title
:
'
Vue Element Admin
'
,
/**
* @type {boolean} true | false
* @description Whether show the settings right-panel
*/
showSettings
:
true
,
/**
* @type {boolean} true | false
* @description Whether need tagsView
*/
tagsView
:
true
,
/**
* @type {boolean} true | false
* @description Whether fix the header
*/
fixedHeader
:
true
,
/**
* @type {boolean} true | false
* @description Whether show the logo in sidebar
*/
sidebarLogo
:
true
,
/**
* @type {boolean} true | false
* @description Whether support pinyin search in headerSearch
* Bundle size minified 47.3kb,minified + gzipped 63kb
*/
supportPinyinSearch
:
true
,
/**
* @type {string | array} 'production' | ['production', 'development']
* @description Need show err logs component.
* The default is only used in the production env
* If you want to also use it in dev, you can pass ['production', 'development']
*/
errorLog
:
'
production
'
}
front-end/mall4cloud-multishop-master/src/store/getters.js
0 → 100644
View file @
a21f5a9a
const
getters
=
{
sidebar
:
state
=>
state
.
app
.
sidebar
,
language
:
state
=>
state
.
app
.
language
,
size
:
state
=>
state
.
app
.
size
,
device
:
state
=>
state
.
app
.
device
,
visitedViews
:
state
=>
state
.
tagsView
.
visitedViews
,
cachedViews
:
state
=>
state
.
tagsView
.
cachedViews
,
token
:
state
=>
state
.
user
.
token
,
avatar
:
state
=>
state
.
user
.
avatar
,
isAdmin
:
state
=>
state
.
user
.
isAdmin
,
name
:
state
=>
state
.
user
.
name
,
introduction
:
state
=>
state
.
user
.
introduction
,
roles
:
state
=>
state
.
user
.
roles
,
permission_routes
:
state
=>
state
.
permission
.
routes
}
export
default
getters
front-end/mall4cloud-multishop-master/src/store/index.js
0 → 100644
View file @
a21f5a9a
import
Vue
from
'
vue
'
import
Vuex
from
'
vuex
'
import
getters
from
'
./getters
'
Vue
.
use
(
Vuex
)
// https://webpack.js.org/guides/dependency-management/#requirecontext
const
modulesFiles
=
require
.
context
(
'
./modules
'
,
true
,
/
\.
js$/
)
// you do not need `import app from './modules/app'`
// it will auto require all vuex module from modules file
const
modules
=
modulesFiles
.
keys
().
reduce
((
modules
,
modulePath
)
=>
{
// set './app.js' => 'app'
const
moduleName
=
modulePath
.
replace
(
/^
\.\/(
.*
)\.\w
+$/
,
'
$1
'
)
const
value
=
modulesFiles
(
modulePath
)
modules
[
moduleName
]
=
value
.
default
return
modules
},
{})
const
store
=
new
Vuex
.
Store
({
modules
,
getters
})
export
default
store
Prev
1
…
12
13
14
15
16
17
18
Next
Write
Preview
Markdown
is supported
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