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
6c14c43c
Commit
6c14c43c
authored
Mar 23, 2018
by
Junling Bu
Browse files
V 0.1.0, 项目架构基本完成。
parents
Changes
346
Hide whitespace changes
Inline
Side-by-side
Too many changes to show.
To preserve performance only
20 of 346+
files are displayed.
Plain diff
Email patch
litemall-admin/src/store/getters.js
0 → 100644
View file @
6c14c43c
const
getters
=
{
sidebar
:
state
=>
state
.
app
.
sidebar
,
language
:
state
=>
state
.
app
.
language
,
visitedViews
:
state
=>
state
.
tagsView
.
visitedViews
,
cachedViews
:
state
=>
state
.
tagsView
.
cachedViews
,
token
:
state
=>
state
.
user
.
token
,
avatar
:
state
=>
state
.
user
.
avatar
,
name
:
state
=>
state
.
user
.
name
,
introduction
:
state
=>
state
.
user
.
introduction
,
status
:
state
=>
state
.
user
.
status
,
roles
:
state
=>
state
.
user
.
roles
,
setting
:
state
=>
state
.
user
.
setting
,
permission_routers
:
state
=>
state
.
permission
.
routers
,
addRouters
:
state
=>
state
.
permission
.
addRouters
}
export
default
getters
litemall-admin/src/store/index.js
0 → 100644
View file @
6c14c43c
import
Vue
from
'
vue
'
import
Vuex
from
'
vuex
'
import
app
from
'
./modules/app
'
import
permission
from
'
./modules/permission
'
import
tagsView
from
'
./modules/tagsView
'
import
user
from
'
./modules/user
'
import
getters
from
'
./getters
'
Vue
.
use
(
Vuex
)
const
store
=
new
Vuex
.
Store
({
modules
:
{
app
,
permission
,
tagsView
,
user
},
getters
})
export
default
store
litemall-admin/src/store/modules/app.js
0 → 100644
View file @
6c14c43c
import
Cookies
from
'
js-cookie
'
const
app
=
{
state
:
{
sidebar
:
{
opened
:
!+
Cookies
.
get
(
'
sidebarStatus
'
)
},
language
:
Cookies
.
get
(
'
language
'
)
||
'
zh
'
},
mutations
:
{
TOGGLE_SIDEBAR
:
state
=>
{
if
(
state
.
sidebar
.
opened
)
{
Cookies
.
set
(
'
sidebarStatus
'
,
1
)
}
else
{
Cookies
.
set
(
'
sidebarStatus
'
,
0
)
}
state
.
sidebar
.
opened
=
!
state
.
sidebar
.
opened
},
SET_LANGUAGE
:
(
state
,
language
)
=>
{
state
.
language
=
language
Cookies
.
set
(
'
language
'
,
language
)
}
},
actions
:
{
toggleSideBar
({
commit
})
{
commit
(
'
TOGGLE_SIDEBAR
'
)
},
setLanguage
({
commit
},
language
)
{
commit
(
'
SET_LANGUAGE
'
,
language
)
}
}
}
export
default
app
litemall-admin/src/store/modules/permission.js
0 → 100644
View file @
6c14c43c
import
{
asyncRouterMap
,
constantRouterMap
}
from
'
@/router
'
/**
* 通过meta.role判断是否与当前用户权限匹配
* @param roles
* @param route
*/
function
hasPermission
(
roles
,
route
)
{
if
(
route
.
meta
&&
route
.
meta
.
roles
)
{
return
roles
.
some
(
role
=>
route
.
meta
.
roles
.
indexOf
(
role
)
>=
0
)
}
else
{
return
true
}
}
/**
* 递归过滤异步路由表,返回符合用户角色权限的路由表
* @param asyncRouterMap
* @param roles
*/
function
filterAsyncRouter
(
asyncRouterMap
,
roles
)
{
const
accessedRouters
=
asyncRouterMap
.
filter
(
route
=>
{
if
(
hasPermission
(
roles
,
route
))
{
if
(
route
.
children
&&
route
.
children
.
length
)
{
route
.
children
=
filterAsyncRouter
(
route
.
children
,
roles
)
}
return
true
}
return
false
})
return
accessedRouters
}
const
permission
=
{
state
:
{
routers
:
constantRouterMap
,
addRouters
:
[]
},
mutations
:
{
SET_ROUTERS
:
(
state
,
routers
)
=>
{
state
.
addRouters
=
routers
state
.
routers
=
constantRouterMap
.
concat
(
routers
)
}
},
actions
:
{
GenerateRoutes
({
commit
},
data
)
{
return
new
Promise
(
resolve
=>
{
const
{
roles
}
=
data
let
accessedRouters
if
(
roles
.
indexOf
(
'
admin
'
)
>=
0
)
{
accessedRouters
=
asyncRouterMap
}
else
{
accessedRouters
=
filterAsyncRouter
(
asyncRouterMap
,
roles
)
}
commit
(
'
SET_ROUTERS
'
,
accessedRouters
)
resolve
()
})
}
}
}
export
default
permission
litemall-admin/src/store/modules/tagsView.js
0 → 100644
View file @
6c14c43c
const
tagsView
=
{
state
:
{
visitedViews
:
[],
cachedViews
:
[]
},
mutations
:
{
ADD_VISITED_VIEWS
:
(
state
,
view
)
=>
{
if
(
state
.
visitedViews
.
some
(
v
=>
v
.
path
===
view
.
path
))
return
state
.
visitedViews
.
push
({
name
:
view
.
name
,
path
:
view
.
path
,
title
:
view
.
meta
.
title
||
'
no-name
'
})
if
(
!
view
.
meta
.
noCache
)
{
state
.
cachedViews
.
push
(
view
.
name
)
}
},
DEL_VISITED_VIEWS
:
(
state
,
view
)
=>
{
for
(
const
[
i
,
v
]
of
state
.
visitedViews
.
entries
())
{
if
(
v
.
path
===
view
.
path
)
{
state
.
visitedViews
.
splice
(
i
,
1
)
break
}
}
for
(
const
i
of
state
.
cachedViews
)
{
if
(
i
===
view
.
name
)
{
const
index
=
state
.
cachedViews
.
indexOf
(
i
)
state
.
cachedViews
.
splice
(
index
,
1
)
break
}
}
},
DEL_OTHERS_VIEWS
:
(
state
,
view
)
=>
{
for
(
const
[
i
,
v
]
of
state
.
visitedViews
.
entries
())
{
if
(
v
.
path
===
view
.
path
)
{
state
.
visitedViews
=
state
.
visitedViews
.
slice
(
i
,
i
+
1
)
break
}
}
for
(
const
i
of
state
.
cachedViews
)
{
if
(
i
===
view
.
name
)
{
const
index
=
state
.
cachedViews
.
indexOf
(
i
)
state
.
cachedViews
=
state
.
cachedViews
.
slice
(
index
,
i
+
1
)
break
}
}
},
DEL_ALL_VIEWS
:
(
state
)
=>
{
state
.
visitedViews
=
[]
state
.
cachedViews
=
[]
}
},
actions
:
{
addVisitedViews
({
commit
},
view
)
{
commit
(
'
ADD_VISITED_VIEWS
'
,
view
)
},
delVisitedViews
({
commit
,
state
},
view
)
{
return
new
Promise
((
resolve
)
=>
{
commit
(
'
DEL_VISITED_VIEWS
'
,
view
)
resolve
([...
state
.
visitedViews
])
})
},
delOthersViews
({
commit
,
state
},
view
)
{
return
new
Promise
((
resolve
)
=>
{
commit
(
'
DEL_OTHERS_VIEWS
'
,
view
)
resolve
([...
state
.
visitedViews
])
})
},
delAllViews
({
commit
,
state
})
{
return
new
Promise
((
resolve
)
=>
{
commit
(
'
DEL_ALL_VIEWS
'
)
resolve
([...
state
.
visitedViews
])
})
}
}
}
export
default
tagsView
litemall-admin/src/store/modules/user.js
0 → 100644
View file @
6c14c43c
import
{
loginByUsername
,
logout
,
getUserInfo
}
from
'
@/api/login
'
import
{
getToken
,
setToken
,
removeToken
}
from
'
@/utils/auth
'
const
user
=
{
state
:
{
user
:
''
,
status
:
''
,
code
:
''
,
token
:
getToken
(),
name
:
''
,
avatar
:
''
,
introduction
:
''
,
roles
:
[],
setting
:
{
articlePlatform
:
[]
}
},
mutations
:
{
SET_CODE
:
(
state
,
code
)
=>
{
state
.
code
=
code
},
SET_TOKEN
:
(
state
,
token
)
=>
{
state
.
token
=
token
},
SET_INTRODUCTION
:
(
state
,
introduction
)
=>
{
state
.
introduction
=
introduction
},
SET_SETTING
:
(
state
,
setting
)
=>
{
state
.
setting
=
setting
},
SET_STATUS
:
(
state
,
status
)
=>
{
state
.
status
=
status
},
SET_NAME
:
(
state
,
name
)
=>
{
state
.
name
=
name
},
SET_AVATAR
:
(
state
,
avatar
)
=>
{
state
.
avatar
=
avatar
},
SET_ROLES
:
(
state
,
roles
)
=>
{
state
.
roles
=
roles
}
},
actions
:
{
// 用户名登录
LoginByUsername
({
commit
},
userInfo
)
{
const
username
=
userInfo
.
username
.
trim
()
return
new
Promise
((
resolve
,
reject
)
=>
{
loginByUsername
(
username
,
userInfo
.
password
).
then
(
response
=>
{
const
token
=
response
.
data
.
data
commit
(
'
SET_TOKEN
'
,
token
)
setToken
(
token
)
resolve
()
}).
catch
(
error
=>
{
reject
(
error
)
})
})
},
// 获取用户信息
GetUserInfo
({
commit
,
state
})
{
return
new
Promise
((
resolve
,
reject
)
=>
{
getUserInfo
(
state
.
token
).
then
(
response
=>
{
const
data
=
response
.
data
.
data
commit
(
'
SET_ROLES
'
,
data
.
roles
)
commit
(
'
SET_NAME
'
,
data
.
name
)
commit
(
'
SET_AVATAR
'
,
data
.
avatar
)
commit
(
'
SET_INTRODUCTION
'
,
data
.
introduction
)
resolve
(
response
)
}).
catch
(
error
=>
{
reject
(
error
)
})
})
},
// 第三方验证登录
// LoginByThirdparty({ commit, state }, code) {
// return new Promise((resolve, reject) => {
// commit('SET_CODE', code)
// loginByThirdparty(state.status, state.email, state.code).then(response => {
// commit('SET_TOKEN', response.data.token)
// setToken(response.data.token)
// resolve()
// }).catch(error => {
// reject(error)
// })
// })
// },
// 登出
LogOut
({
commit
,
state
})
{
return
new
Promise
((
resolve
,
reject
)
=>
{
logout
(
state
.
token
).
then
(()
=>
{
commit
(
'
SET_TOKEN
'
,
''
)
commit
(
'
SET_ROLES
'
,
[])
removeToken
()
resolve
()
}).
catch
(
error
=>
{
reject
(
error
)
})
})
},
// 前端 登出
FedLogOut
({
commit
})
{
return
new
Promise
(
resolve
=>
{
commit
(
'
SET_TOKEN
'
,
''
)
removeToken
()
resolve
()
})
},
// 动态修改权限
ChangeRoles
({
commit
},
role
)
{
return
new
Promise
(
resolve
=>
{
commit
(
'
SET_TOKEN
'
,
role
)
setToken
(
role
)
getUserInfo
(
role
).
then
(
response
=>
{
const
data
=
response
.
data
.
data
commit
(
'
SET_ROLES
'
,
data
.
roles
)
commit
(
'
SET_NAME
'
,
data
.
name
)
commit
(
'
SET_AVATAR
'
,
data
.
avatar
)
commit
(
'
SET_INTRODUCTION
'
,
data
.
introduction
)
resolve
()
})
})
}
}
}
export
default
user
litemall-admin/src/styles/btn.scss
0 → 100644
View file @
6c14c43c
@import
'./variables.scss'
;
@mixin
colorBtn
(
$color
)
{
background
:
$color
;
&
:hover
{
color
:
$color
;
&
:before
,
&
:after
{
background
:
$color
;
}
}
}
.blue-btn
{
@include
colorBtn
(
$blue
)
}
.light-blue-btn
{
@include
colorBtn
(
$light-blue
)
}
.red-btn
{
@include
colorBtn
(
$red
)
}
.pink-btn
{
@include
colorBtn
(
$pink
)
}
.green-btn
{
@include
colorBtn
(
$green
)
}
.tiffany-btn
{
@include
colorBtn
(
$tiffany
)
}
.yellow-btn
{
@include
colorBtn
(
$yellow
)
}
.pan-btn
{
font-size
:
14px
;
color
:
#fff
;
padding
:
14px
36px
;
border-radius
:
8px
;
border
:
none
;
outline
:
none
;
margin-right
:
25px
;
transition
:
600ms
ease
all
;
position
:
relative
;
display
:
inline-block
;
&
:hover
{
background
:
#fff
;
&
:before
,
&
:after
{
width
:
100%
;
transition
:
600ms
ease
all
;
}
}
&
:before
,
&
:after
{
content
:
''
;
position
:
absolute
;
top
:
0
;
right
:
0
;
height
:
2px
;
width
:
0
;
transition
:
400ms
ease
all
;
}
&
::after
{
right
:
inherit
;
top
:
inherit
;
left
:
0
;
bottom
:
0
;
}
}
.custom-button
{
display
:
inline-block
;
line-height
:
1
;
white-space
:
nowrap
;
cursor
:
pointer
;
background
:
#fff
;
color
:
#fff
;
-webkit-appearance
:
none
;
text-align
:
center
;
box-sizing
:
border-box
;
outline
:
0
;
margin
:
0
;
padding
:
10px
15px
;
font-size
:
14px
;
border-radius
:
4px
;
}
litemall-admin/src/styles/element-ui.scss
0 → 100644
View file @
6c14c43c
//覆盖一些element-ui样式
.el-breadcrumb__inner
,
.el-breadcrumb__inner
a
{
font-weight
:
400
!
important
;
}
.el-upload
{
input
[
type
=
"file"
]
{
display
:
none
!
important
;
}
}
.el-upload__input
{
display
:
none
;
}
.cell
{
.el-tag
{
margin-right
:
0px
;
}
}
.small-padding
{
.cell
{
padding-left
:
5px
;
padding-right
:
5px
;
}
}
.fixed-width
{
.el-button--mini
{
padding
:
7px
10px
;
width
:
60px
;
}
}
.status-col
{
.cell
{
padding
:
0
10px
;
text-align
:
center
;
.el-tag
{
margin-right
:
0px
;
}
}
}
//暂时性解决diolag 问题 https://github.com/ElemeFE/element/issues/2461
.el-dialog
{
transform
:
none
;
left
:
0
;
position
:
relative
;
margin
:
0
auto
;
}
//文章页textarea修改样式
.article-textarea
{
textarea
{
padding-right
:
40px
;
resize
:
none
;
border
:
none
;
border-radius
:
0px
;
border-bottom
:
1px
solid
#bfcbd9
;
}
}
//element ui upload
.upload-container
{
.el-upload
{
width
:
100%
;
.el-upload-dragger
{
width
:
100%
;
height
:
200px
;
}
}
}
litemall-admin/src/styles/index.scss
0 → 100644
View file @
6c14c43c
@import
'./variables.scss'
;
@import
'./mixin.scss'
;
@import
'./transition.scss'
;
@import
'./element-ui.scss'
;
@import
'./sidebar.scss'
;
@import
'./btn.scss'
;
body
{
height
:
100%
;
-moz-osx-font-smoothing
:
grayscale
;
-webkit-font-smoothing
:
antialiased
;
text-rendering
:
optimizeLegibility
;
font-family
:
Helvetica
Neue
,
Helvetica
,
PingFang
SC
,
Hiragino
Sans
GB
,
Microsoft
YaHei
,
Arial
,
sans-serif
;
}
label
{
font-weight
:
700
;
}
html
{
height
:
100%
;
box-sizing
:
border-box
;
}
#app
{
height
:
100%
;
}
*,
*
:before
,
*
:after
{
box-sizing
:
inherit
;
}
.no-padding
{
padding
:
0px
!
important
;
}
.padding-content
{
padding
:
4px
0
;
}
a
:focus
,
a
:active
{
outline
:
none
;
}
a
,
a
:focus
,
a
:hover
{
cursor
:
pointer
;
color
:
inherit
;
text-decoration
:
none
;
}
div
:focus
{
outline
:
none
;
}
.fr
{
float
:
right
;
}
.fl
{
float
:
left
;
}
.pr-5
{
padding-right
:
5px
;
}
.pl-5
{
padding-left
:
5px
;
}
.block
{
display
:
block
;
}
.pointer
{
cursor
:
pointer
;
}
.inlineBlock
{
display
:
block
;
}
.clearfix
{
&
:after
{
visibility
:
hidden
;
display
:
block
;
font-size
:
0
;
content
:
" "
;
clear
:
both
;
height
:
0
;
}
}
code
{
background
:
#eef1f6
;
padding
:
15px
16px
;
margin-bottom
:
20px
;
display
:
block
;
line-height
:
36px
;
font-size
:
15px
;
font-family
:
"Source Sans Pro"
,
"Helvetica Neue"
,
Arial
,
sans-serif
;
a
{
color
:
#337ab7
;
cursor
:
pointer
;
&
:hover
{
color
:
rgb
(
32
,
160
,
255
);
}
}
}
.warn-content
{
background
:
rgba
(
66
,
185
,
131
,.
1
);
border-radius
:
2px
;
padding
:
16px
;
padding
:
1rem
;
line-height
:
1
.6rem
;
word-spacing
:
.05rem
;
a
{
color
:
#42b983
;
font-weight
:
600
;
}
}
//main-container全局样式
.app-container
{
padding
:
20px
;
}
.components-container
{
margin
:
30px
50px
;
position
:
relative
;
}
.pagination-container
{
margin-top
:
30px
;
}
.text-center
{
text-align
:
center
}
.sub-navbar
{
height
:
50px
;
line-height
:
50px
;
position
:
relative
;
width
:
100%
;
text-align
:
right
;
padding-right
:
20px
;
transition
:
600ms
ease
position
;
background
:
linear-gradient
(
90deg
,
rgba
(
32
,
182
,
249
,
1
)
0%
,
rgba
(
32
,
182
,
249
,
1
)
0%
,
rgba
(
33
,
120
,
241
,
1
)
100%
,
rgba
(
33
,
120
,
241
,
1
)
100%
);
.subtitle
{
font-size
:
20px
;
color
:
#fff
;
}
&
.draft
{
background
:
#d0d0d0
;
}
&
.deleted
{
background
:
#d0d0d0
;
}
}
.link-type
,
.link-type
:focus
{
color
:
#337ab7
;
cursor
:
pointer
;
&
:hover
{
color
:
rgb
(
32
,
160
,
255
);
}
}
.filter-container
{
padding-bottom
:
10px
;
.filter-item
{
display
:
inline-block
;
vertical-align
:
middle
;
margin-bottom
:
10px
;
}
}
//refine vue-multiselect plugin
.multiselect
{
line-height
:
16px
;
}
.multiselect--active
{
z-index
:
1000
!
important
;
}
litemall-admin/src/styles/mixin.scss
0 → 100644
View file @
6c14c43c
@mixin
clearfix
{
&
:after
{
content
:
""
;
display
:
table
;
clear
:
both
;
}
}
@mixin
scrollBar
{
&
::-webkit-scrollbar-track-piece
{
background
:
#d3dce6
;
}
&
::-webkit-scrollbar
{
width
:
6px
;
}
&
::-webkit-scrollbar-thumb
{
background
:
#99a9bf
;
border-radius
:
20px
;
}
}
@mixin
relative
{
position
:
relative
;
width
:
100%
;
height
:
100%
;
}
@mixin
pct
(
$pct
)
{
width
:
#{
$pct
}
;
position
:
relative
;
margin
:
0
auto
;
}
@mixin
triangle
(
$width
,
$height
,
$color
,
$direction
)
{
$width
:
$width
/
2
;
$color-border-style
:
$height
solid
$color
;
$transparent-border-style
:
$width
solid
transparent
;
height
:
0
;
width
:
0
;
@if
$direction
==
up
{
border-bottom
:
$color-border-style
;
border-left
:
$transparent-border-style
;
border-right
:
$transparent-border-style
;
}
@else
if
$direction
==
right
{
border-left
:
$color-border-style
;
border-top
:
$transparent-border-style
;
border-bottom
:
$transparent-border-style
;
}
@else
if
$direction
==
down
{
border-top
:
$color-border-style
;
border-left
:
$transparent-border-style
;
border-right
:
$transparent-border-style
;
}
@else
if
$direction
==
left
{
border-right
:
$color-border-style
;
border-top
:
$transparent-border-style
;
border-bottom
:
$transparent-border-style
;
}
}
litemall-admin/src/styles/sidebar.scss
0 → 100644
View file @
6c14c43c
#app
{
// 主体区域
.main-container
{
min-height
:
100%
;
transition
:
margin-left
0
.28s
;
margin-left
:
180px
;
}
// 侧边栏
.sidebar-container
{
transition
:
width
0
.28s
;
width
:
180px
!
important
;
height
:
100%
;
position
:
fixed
;
top
:
0
;
bottom
:
0
;
left
:
0
;
z-index
:
1001
;
a
{
display
:
inline-block
;
width
:
100%
;
}
.svg-icon
{
margin-right
:
16px
;
}
.el-menu
{
border
:
none
;
width
:
100%
;
}
}
.hideSidebar
{
.sidebar-container
,
.sidebar-container
.el-menu
{
width
:
36px
!
important
;
// overflow: inherit;
}
.main-container
{
margin-left
:
36px
;
}
}
.hideSidebar
{
.submenu-title-noDropdown
{
padding-left
:
10px
!
important
;
position
:
relative
;
span
{
height
:
0
;
width
:
0
;
overflow
:
hidden
;
visibility
:
hidden
;
transition
:
opacity
.3s
cubic-bezier
(
.55
,
0
,
.1
,
1
);
opacity
:
0
;
display
:
inline-block
;
}
&
:hover
{
span
{
display
:
block
;
border-radius
:
3px
;
z-index
:
1002
;
width
:
140px
;
height
:
56px
;
visibility
:
visible
;
position
:
absolute
;
right
:
-145px
;
text-align
:
left
;
text-indent
:
20px
;
top
:
0px
;
background-color
:
$subMenuBg
!
important
;
opacity
:
1
;
}
}
}
.el-submenu
{
&
>
.el-submenu__title
{
padding-left
:
10px
!
important
;
&
>
span
{
display
:
none
;
}
.el-submenu__icon-arrow
{
display
:
none
;
}
}
.nest-menu
{
.el-submenu__icon-arrow
{
display
:
block
!
important
;
}
span
{
display
:
inline-block
!
important
;
}
}
}
}
.nest-menu
.el-submenu
>
.el-submenu__title
,
.el-submenu
.el-menu-item
{
min-width
:
180px
!
important
;
background-color
:
$subMenuBg
!
important
;
&
:hover
{
background-color
:
$menuHover
!
important
;
}
}
.el-menu--collapse
.el-menu
.el-submenu
{
min-width
:
180px
!
important
;
}
}
litemall-admin/src/styles/transition.scss
0 → 100644
View file @
6c14c43c
//globl transition css
/*fade*/
.fade-enter-active
,
.fade-leave-active
{
transition
:
opacity
0
.28s
;
}
.fade-enter
,
.fade-leave-active
{
opacity
:
0
;
}
/*fade*/
.breadcrumb-enter-active
,
.breadcrumb-leave-active
{
transition
:
all
.5s
;
}
.breadcrumb-enter
,
.breadcrumb-leave-active
{
opacity
:
0
;
transform
:
translateX
(
20px
);
}
.breadcrumb-move
{
transition
:
all
.5s
;
}
.breadcrumb-leave-active
{
position
:
absolute
;
}
litemall-admin/src/styles/variables.scss
0 → 100644
View file @
6c14c43c
$blue
:
#324157
;
$light-blue
:
#3A71A8
;
$red
:
#C03639
;
$pink
:
#E65D6E
;
$green
:
#30B08F
;
$tiffany
:
#4AB7BD
;
$yellow
:
#FEC171
;
$panGreen
:
#30B08F
;
//sidebar
$menuBg
:
#304156
;
$subMenuBg
:
#1f2d3d
;
$menuHover
:
#001528
;
litemall-admin/src/utils/auth.js
0 → 100644
View file @
6c14c43c
import
Cookies
from
'
js-cookie
'
const
TokenKey
=
'
Admin-Token
'
export
function
getToken
()
{
return
Cookies
.
get
(
TokenKey
)
}
export
function
setToken
(
token
)
{
return
Cookies
.
set
(
TokenKey
,
token
)
}
export
function
removeToken
()
{
return
Cookies
.
remove
(
TokenKey
)
}
litemall-admin/src/utils/index.js
0 → 100644
View file @
6c14c43c
/**
* Created by jiachenpan on 16/11/18.
*/
export
function
parseTime
(
time
,
cFormat
)
{
if
(
arguments
.
length
===
0
)
{
return
null
}
const
format
=
cFormat
||
'
{y}-{m}-{d} {h}:{i}:{s}
'
let
date
if
(
typeof
time
===
'
object
'
)
{
date
=
time
}
else
{
if
((
''
+
time
).
length
===
10
)
time
=
parseInt
(
time
)
*
1000
date
=
new
Date
(
time
)
}
const
formatObj
=
{
y
:
date
.
getFullYear
(),
m
:
date
.
getMonth
()
+
1
,
d
:
date
.
getDate
(),
h
:
date
.
getHours
(),
i
:
date
.
getMinutes
(),
s
:
date
.
getSeconds
(),
a
:
date
.
getDay
()
}
const
time_str
=
format
.
replace
(
/{
(
y|m|d|h|i|s|a
)
+}/g
,
(
result
,
key
)
=>
{
let
value
=
formatObj
[
key
]
if
(
key
===
'
a
'
)
return
[
'
一
'
,
'
二
'
,
'
三
'
,
'
四
'
,
'
五
'
,
'
六
'
,
'
日
'
][
value
-
1
]
if
(
result
.
length
>
0
&&
value
<
10
)
{
value
=
'
0
'
+
value
}
return
value
||
0
})
return
time_str
}
export
function
formatTime
(
time
,
option
)
{
time
=
+
time
*
1000
const
d
=
new
Date
(
time
)
const
now
=
Date
.
now
()
const
diff
=
(
now
-
d
)
/
1000
if
(
diff
<
30
)
{
return
'
刚刚
'
}
else
if
(
diff
<
3600
)
{
// less 1 hour
return
Math
.
ceil
(
diff
/
60
)
+
'
分钟前
'
}
else
if
(
diff
<
3600
*
24
)
{
return
Math
.
ceil
(
diff
/
3600
)
+
'
小时前
'
}
else
if
(
diff
<
3600
*
24
*
2
)
{
return
'
1天前
'
}
if
(
option
)
{
return
parseTime
(
time
,
option
)
}
else
{
return
d
.
getMonth
()
+
1
+
'
月
'
+
d
.
getDate
()
+
'
日
'
+
d
.
getHours
()
+
'
时
'
+
d
.
getMinutes
()
+
'
分
'
}
}
// 格式化时间
export
function
getQueryObject
(
url
)
{
url
=
url
==
null
?
window
.
location
.
href
:
url
const
search
=
url
.
substring
(
url
.
lastIndexOf
(
'
?
'
)
+
1
)
const
obj
=
{}
const
reg
=
/
([^
?&=
]
+
)
=
([^
?&=
]
*
)
/g
search
.
replace
(
reg
,
(
rs
,
$1
,
$2
)
=>
{
const
name
=
decodeURIComponent
(
$1
)
let
val
=
decodeURIComponent
(
$2
)
val
=
String
(
val
)
obj
[
name
]
=
val
return
rs
})
return
obj
}
/**
*get getByteLen
* @param {Sting} val input value
* @returns {number} output value
*/
export
function
getByteLen
(
val
)
{
let
len
=
0
for
(
let
i
=
0
;
i
<
val
.
length
;
i
++
)
{
if
(
val
[
i
].
match
(
/
[^\x
00-
\x
ff
]
/ig
)
!=
null
)
{
len
+=
1
}
else
{
len
+=
0.5
}
}
return
Math
.
floor
(
len
)
}
export
function
cleanArray
(
actual
)
{
const
newArray
=
[]
for
(
let
i
=
0
;
i
<
actual
.
length
;
i
++
)
{
if
(
actual
[
i
])
{
newArray
.
push
(
actual
[
i
])
}
}
return
newArray
}
export
function
param
(
json
)
{
if
(
!
json
)
return
''
return
cleanArray
(
Object
.
keys
(
json
).
map
(
key
=>
{
if
(
json
[
key
]
===
undefined
)
return
''
return
encodeURIComponent
(
key
)
+
'
=
'
+
encodeURIComponent
(
json
[
key
])
})).
join
(
'
&
'
)
}
export
function
param2Obj
(
url
)
{
const
search
=
url
.
split
(
'
?
'
)[
1
]
if
(
!
search
)
{
return
{}
}
return
JSON
.
parse
(
'
{"
'
+
decodeURIComponent
(
search
).
replace
(
/"/g
,
'
\\
"
'
).
replace
(
/&/g
,
'
","
'
).
replace
(
/=/g
,
'
":"
'
)
+
'
"}
'
)
}
export
function
html2Text
(
val
)
{
const
div
=
document
.
createElement
(
'
div
'
)
div
.
innerHTML
=
val
return
div
.
textContent
||
div
.
innerText
}
export
function
objectMerge
(
target
,
source
)
{
/* Merges two objects,
giving the last one precedence */
if
(
typeof
target
!==
'
object
'
)
{
target
=
{}
}
if
(
Array
.
isArray
(
source
))
{
return
source
.
slice
()
}
for
(
const
property
in
source
)
{
if
(
source
.
hasOwnProperty
(
property
))
{
const
sourceProperty
=
source
[
property
]
if
(
typeof
sourceProperty
===
'
object
'
)
{
target
[
property
]
=
objectMerge
(
target
[
property
],
sourceProperty
)
continue
}
target
[
property
]
=
sourceProperty
}
}
return
target
}
export
function
scrollTo
(
element
,
to
,
duration
)
{
if
(
duration
<=
0
)
return
const
difference
=
to
-
element
.
scrollTop
const
perTick
=
difference
/
duration
*
10
setTimeout
(()
=>
{
console
.
log
(
new
Date
())
element
.
scrollTop
=
element
.
scrollTop
+
perTick
if
(
element
.
scrollTop
===
to
)
return
scrollTo
(
element
,
to
,
duration
-
10
)
},
10
)
}
export
function
toggleClass
(
element
,
className
)
{
if
(
!
element
||
!
className
)
{
return
}
let
classString
=
element
.
className
const
nameIndex
=
classString
.
indexOf
(
className
)
if
(
nameIndex
===
-
1
)
{
classString
+=
''
+
className
}
else
{
classString
=
classString
.
substr
(
0
,
nameIndex
)
+
classString
.
substr
(
nameIndex
+
className
.
length
)
}
element
.
className
=
classString
}
export
const
pickerOptions
=
[
{
text
:
'
今天
'
,
onClick
(
picker
)
{
const
end
=
new
Date
()
const
start
=
new
Date
(
new
Date
().
toDateString
())
end
.
setTime
(
start
.
getTime
())
picker
.
$emit
(
'
pick
'
,
[
start
,
end
])
}
},
{
text
:
'
最近一周
'
,
onClick
(
picker
)
{
const
end
=
new
Date
(
new
Date
().
toDateString
())
const
start
=
new
Date
()
start
.
setTime
(
end
.
getTime
()
-
3600
*
1000
*
24
*
7
)
picker
.
$emit
(
'
pick
'
,
[
start
,
end
])
}
},
{
text
:
'
最近一个月
'
,
onClick
(
picker
)
{
const
end
=
new
Date
(
new
Date
().
toDateString
())
const
start
=
new
Date
()
start
.
setTime
(
start
.
getTime
()
-
3600
*
1000
*
24
*
30
)
picker
.
$emit
(
'
pick
'
,
[
start
,
end
])
}
},
{
text
:
'
最近三个月
'
,
onClick
(
picker
)
{
const
end
=
new
Date
(
new
Date
().
toDateString
())
const
start
=
new
Date
()
start
.
setTime
(
start
.
getTime
()
-
3600
*
1000
*
24
*
90
)
picker
.
$emit
(
'
pick
'
,
[
start
,
end
])
}
}]
export
function
getTime
(
type
)
{
if
(
type
===
'
start
'
)
{
return
new
Date
().
getTime
()
-
3600
*
1000
*
24
*
90
}
else
{
return
new
Date
(
new
Date
().
toDateString
())
}
}
export
function
debounce
(
func
,
wait
,
immediate
)
{
let
timeout
,
args
,
context
,
timestamp
,
result
const
later
=
function
()
{
// 据上一次触发时间间隔
const
last
=
+
new
Date
()
-
timestamp
// 上次被包装函数被调用时间间隔last小于设定时间间隔wait
if
(
last
<
wait
&&
last
>
0
)
{
timeout
=
setTimeout
(
later
,
wait
-
last
)
}
else
{
timeout
=
null
// 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
if
(
!
immediate
)
{
result
=
func
.
apply
(
context
,
args
)
if
(
!
timeout
)
context
=
args
=
null
}
}
}
return
function
(...
args
)
{
context
=
this
timestamp
=
+
new
Date
()
const
callNow
=
immediate
&&
!
timeout
// 如果延时不存在,重新设定延时
if
(
!
timeout
)
timeout
=
setTimeout
(
later
,
wait
)
if
(
callNow
)
{
result
=
func
.
apply
(
context
,
args
)
context
=
args
=
null
}
return
result
}
}
export
function
deepClone
(
source
)
{
if
(
!
source
&&
typeof
source
!==
'
object
'
)
{
throw
new
Error
(
'
error arguments
'
,
'
shallowClone
'
)
}
const
targetObj
=
source
.
constructor
===
Array
?
[]
:
{}
for
(
const
keys
in
source
)
{
if
(
source
.
hasOwnProperty
(
keys
))
{
if
(
source
[
keys
]
&&
typeof
source
[
keys
]
===
'
object
'
)
{
targetObj
[
keys
]
=
source
[
keys
].
constructor
===
Array
?
[]
:
{}
targetObj
[
keys
]
=
deepClone
(
source
[
keys
])
}
else
{
targetObj
[
keys
]
=
source
[
keys
]
}
}
}
return
targetObj
}
litemall-admin/src/utils/openWindow.js
0 → 100644
View file @
6c14c43c
/**
*Created by jiachenpan on 16/11/29.
* @param {Sting} url
* @param {Sting} title
* @param {Number} w
* @param {Number} h
*/
export
default
function
openWindow
(
url
,
title
,
w
,
h
)
{
// Fixes dual-screen position Most browsers Firefox
const
dualScreenLeft
=
window
.
screenLeft
!==
undefined
?
window
.
screenLeft
:
screen
.
left
const
dualScreenTop
=
window
.
screenTop
!==
undefined
?
window
.
screenTop
:
screen
.
top
const
width
=
window
.
innerWidth
?
window
.
innerWidth
:
document
.
documentElement
.
clientWidth
?
document
.
documentElement
.
clientWidth
:
screen
.
width
const
height
=
window
.
innerHeight
?
window
.
innerHeight
:
document
.
documentElement
.
clientHeight
?
document
.
documentElement
.
clientHeight
:
screen
.
height
const
left
=
((
width
/
2
)
-
(
w
/
2
))
+
dualScreenLeft
const
top
=
((
height
/
2
)
-
(
h
/
2
))
+
dualScreenTop
const
newWindow
=
window
.
open
(
url
,
title
,
'
toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=yes, copyhistory=no, width=
'
+
w
+
'
, height=
'
+
h
+
'
, top=
'
+
top
+
'
, left=
'
+
left
)
// Puts focus on the newWindow
if
(
window
.
focus
)
{
newWindow
.
focus
()
}
}
litemall-admin/src/utils/request.js
0 → 100644
View file @
6c14c43c
import
axios
from
'
axios
'
import
{
Message
}
from
'
element-ui
'
import
store
from
'
@/store
'
import
{
getToken
}
from
'
@/utils/auth
'
// create an axios instance
const
service
=
axios
.
create
({
baseURL
:
process
.
env
.
BASE_API
,
// api的base_url
timeout
:
5000
// request timeout
})
// request interceptor
service
.
interceptors
.
request
.
use
(
config
=>
{
// Do something before request is sent
if
(
store
.
getters
.
token
)
{
config
.
headers
[
'
X-Token
'
]
=
getToken
()
// 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改
}
return
config
},
error
=>
{
// Do something with request error
console
.
log
(
error
)
// for debug
Promise
.
reject
(
error
)
})
// respone interceptor
service
.
interceptors
.
response
.
use
(
response
=>
{
const
res
=
response
.
data
if
(
res
.
errno
!==
0
)
{
Message
({
message
:
res
.
errno
+
'
'
+
res
.
errmsg
,
type
:
'
error
'
,
duration
:
5
*
1000
})
// 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了;
// if (res.errno === 50008 || res.errno === 50012 || res.errno === 50014) {
// Message.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {
// confirmButtonText: '重新登录',
// cancelButtonText: '取消',
// type: 'warning'
// }).then(() => {
// store.dispatch('FedLogOut').then(() => {
// location.reload() // 为了重新实例化vue-router对象 避免bug
// })
// })
// }
return
Promise
.
reject
(
'
error
'
)
}
else
{
return
response
}
},
error
=>
{
console
.
log
(
'
err
'
+
error
)
// for debug
Message
({
message
:
error
.
message
,
type
:
'
error
'
,
duration
:
5
*
1000
})
return
Promise
.
reject
(
error
)
})
export
default
service
litemall-admin/src/utils/validate.js
0 → 100644
View file @
6c14c43c
/**
* Created by jiachenpan on 16/11/18.
*/
/* 合法uri*/
export
function
validateURL
(
textval
)
{
const
urlregex
=
/^
(
https
?
|ftp
)
:
\/\/([
a-zA-Z0-9.-
]
+
(
:
[
a-zA-Z0-9.&%$-
]
+
)
*@
)
*
((
25
[
0-5
]
|2
[
0-4
][
0-9
]
|1
[
0-9
]{2}
|
[
1-9
][
0-9
]?)(\.(
25
[
0-5
]
|2
[
0-4
][
0-9
]
|1
[
0-9
]{2}
|
[
1-9
]?[
0-9
])){3}
|
([
a-zA-Z0-9-
]
+
\.)
*
[
a-zA-Z0-9-
]
+
\.(
com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|
[
a-zA-Z
]{2}))(
:
[
0-9
]
+
)
*
(\/(
$|
[
a-zA-Z0-9.,?'
\\
+&%$#=~_-
]
+
))
*$/
return
urlregex
.
test
(
textval
)
}
/* 小写字母*/
export
function
validateLowerCase
(
str
)
{
const
reg
=
/^
[
a-z
]
+$/
return
reg
.
test
(
str
)
}
/* 大写字母*/
export
function
validateUpperCase
(
str
)
{
const
reg
=
/^
[
A-Z
]
+$/
return
reg
.
test
(
str
)
}
/* 大小写字母*/
export
function
validatAlphabets
(
str
)
{
const
reg
=
/^
[
A-Za-z
]
+$/
return
reg
.
test
(
str
)
}
/**
* validate email
* @param email
* @returns {boolean}
*/
export
function
validateEmail
(
email
)
{
const
re
=
/^
(([^
<>()
\[\]\\
.,;:
\s
@"
]
+
(\.[^
<>()
\[\]\\
.,;:
\s
@"
]
+
)
*
)
|
(
".+"
))
@
((\[[
0-9
]{1,3}\.[
0-9
]{1,3}\.[
0-9
]{1,3}\.[
0-9
]{1,3}\])
|
(([
a-zA-Z
\-
0-9
]
+
\.)
+
[
a-zA-Z
]{2,}))
$/
return
re
.
test
(
email
)
}
litemall-admin/src/vendor/Blob.js
0 → 100644
View file @
6c14c43c
/* eslint-disable */
/* Blob.js
* A Blob implementation.
* 2014-05-27
*
* By Eli Grey, http://eligrey.com
* By Devin Samarin, https://github.com/eboyjr
* License: X11/MIT
* See LICENSE.md
*/
/*global self, unescape */
/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
plusplus: true */
/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
(
function
(
view
)
{
"
use strict
"
;
view
.
URL
=
view
.
URL
||
view
.
webkitURL
;
if
(
view
.
Blob
&&
view
.
URL
)
{
try
{
new
Blob
;
return
;
}
catch
(
e
)
{}
}
// Internally we use a BlobBuilder implementation to base Blob off of
// in order to support older browsers that only have BlobBuilder
var
BlobBuilder
=
view
.
BlobBuilder
||
view
.
WebKitBlobBuilder
||
view
.
MozBlobBuilder
||
(
function
(
view
)
{
var
get_class
=
function
(
object
)
{
return
Object
.
prototype
.
toString
.
call
(
object
).
match
(
/^
\[
object
\s(
.*
)\]
$/
)[
1
];
}
,
FakeBlobBuilder
=
function
BlobBuilder
()
{
this
.
data
=
[];
}
,
FakeBlob
=
function
Blob
(
data
,
type
,
encoding
)
{
this
.
data
=
data
;
this
.
size
=
data
.
length
;
this
.
type
=
type
;
this
.
encoding
=
encoding
;
}
,
FBB_proto
=
FakeBlobBuilder
.
prototype
,
FB_proto
=
FakeBlob
.
prototype
,
FileReaderSync
=
view
.
FileReaderSync
,
FileException
=
function
(
type
)
{
this
.
code
=
this
[
this
.
name
=
type
];
}
,
file_ex_codes
=
(
"
NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR
"
+
"
NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR
"
).
split
(
"
"
)
,
file_ex_code
=
file_ex_codes
.
length
,
real_URL
=
view
.
URL
||
view
.
webkitURL
||
view
,
real_create_object_URL
=
real_URL
.
createObjectURL
,
real_revoke_object_URL
=
real_URL
.
revokeObjectURL
,
URL
=
real_URL
,
btoa
=
view
.
btoa
,
atob
=
view
.
atob
,
ArrayBuffer
=
view
.
ArrayBuffer
,
Uint8Array
=
view
.
Uint8Array
;
FakeBlob
.
fake
=
FB_proto
.
fake
=
true
;
while
(
file_ex_code
--
)
{
FileException
.
prototype
[
file_ex_codes
[
file_ex_code
]]
=
file_ex_code
+
1
;
}
if
(
!
real_URL
.
createObjectURL
)
{
URL
=
view
.
URL
=
{};
}
URL
.
createObjectURL
=
function
(
blob
)
{
var
type
=
blob
.
type
,
data_URI_header
;
if
(
type
===
null
)
{
type
=
"
application/octet-stream
"
;
}
if
(
blob
instanceof
FakeBlob
)
{
data_URI_header
=
"
data:
"
+
type
;
if
(
blob
.
encoding
===
"
base64
"
)
{
return
data_URI_header
+
"
;base64,
"
+
blob
.
data
;
}
else
if
(
blob
.
encoding
===
"
URI
"
)
{
return
data_URI_header
+
"
,
"
+
decodeURIComponent
(
blob
.
data
);
}
if
(
btoa
)
{
return
data_URI_header
+
"
;base64,
"
+
btoa
(
blob
.
data
);
}
else
{
return
data_URI_header
+
"
,
"
+
encodeURIComponent
(
blob
.
data
);
}
}
else
if
(
real_create_object_URL
)
{
return
real_create_object_URL
.
call
(
real_URL
,
blob
);
}
};
URL
.
revokeObjectURL
=
function
(
object_URL
)
{
if
(
object_URL
.
substring
(
0
,
5
)
!==
"
data:
"
&&
real_revoke_object_URL
)
{
real_revoke_object_URL
.
call
(
real_URL
,
object_URL
);
}
};
FBB_proto
.
append
=
function
(
data
/*, endings*/
)
{
var
bb
=
this
.
data
;
// decode data to a binary string
if
(
Uint8Array
&&
(
data
instanceof
ArrayBuffer
||
data
instanceof
Uint8Array
))
{
var
str
=
""
,
buf
=
new
Uint8Array
(
data
)
,
i
=
0
,
buf_len
=
buf
.
length
;
for
(;
i
<
buf_len
;
i
++
)
{
str
+=
String
.
fromCharCode
(
buf
[
i
]);
}
bb
.
push
(
str
);
}
else
if
(
get_class
(
data
)
===
"
Blob
"
||
get_class
(
data
)
===
"
File
"
)
{
if
(
FileReaderSync
)
{
var
fr
=
new
FileReaderSync
;
bb
.
push
(
fr
.
readAsBinaryString
(
data
));
}
else
{
// async FileReader won't work as BlobBuilder is sync
throw
new
FileException
(
"
NOT_READABLE_ERR
"
);
}
}
else
if
(
data
instanceof
FakeBlob
)
{
if
(
data
.
encoding
===
"
base64
"
&&
atob
)
{
bb
.
push
(
atob
(
data
.
data
));
}
else
if
(
data
.
encoding
===
"
URI
"
)
{
bb
.
push
(
decodeURIComponent
(
data
.
data
));
}
else
if
(
data
.
encoding
===
"
raw
"
)
{
bb
.
push
(
data
.
data
);
}
}
else
{
if
(
typeof
data
!==
"
string
"
)
{
data
+=
""
;
// convert unsupported types to strings
}
// decode UTF-16 to binary string
bb
.
push
(
unescape
(
encodeURIComponent
(
data
)));
}
};
FBB_proto
.
getBlob
=
function
(
type
)
{
if
(
!
arguments
.
length
)
{
type
=
null
;
}
return
new
FakeBlob
(
this
.
data
.
join
(
""
),
type
,
"
raw
"
);
};
FBB_proto
.
toString
=
function
()
{
return
"
[object BlobBuilder]
"
;
};
FB_proto
.
slice
=
function
(
start
,
end
,
type
)
{
var
args
=
arguments
.
length
;
if
(
args
<
3
)
{
type
=
null
;
}
return
new
FakeBlob
(
this
.
data
.
slice
(
start
,
args
>
1
?
end
:
this
.
data
.
length
)
,
type
,
this
.
encoding
);
};
FB_proto
.
toString
=
function
()
{
return
"
[object Blob]
"
;
};
FB_proto
.
close
=
function
()
{
this
.
size
=
this
.
data
.
length
=
0
;
};
return
FakeBlobBuilder
;
}(
view
));
view
.
Blob
=
function
Blob
(
blobParts
,
options
)
{
var
type
=
options
?
(
options
.
type
||
""
)
:
""
;
var
builder
=
new
BlobBuilder
();
if
(
blobParts
)
{
for
(
var
i
=
0
,
len
=
blobParts
.
length
;
i
<
len
;
i
++
)
{
builder
.
append
(
blobParts
[
i
]);
}
}
return
builder
.
getBlob
(
type
);
};
}(
typeof
self
!==
"
undefined
"
&&
self
||
typeof
window
!==
"
undefined
"
&&
window
||
this
.
content
||
this
));
litemall-admin/src/vendor/Export2Excel.js
0 → 100644
View file @
6c14c43c
/* eslint-disable */
require
(
'
script-loader!file-saver
'
);
require
(
'
script-loader!@/vendor/Blob
'
);
import
XLSX
from
'
xlsx
'
function
generateArray
(
table
)
{
var
out
=
[];
var
rows
=
table
.
querySelectorAll
(
'
tr
'
);
var
ranges
=
[];
for
(
var
R
=
0
;
R
<
rows
.
length
;
++
R
)
{
var
outRow
=
[];
var
row
=
rows
[
R
];
var
columns
=
row
.
querySelectorAll
(
'
td
'
);
for
(
var
C
=
0
;
C
<
columns
.
length
;
++
C
)
{
var
cell
=
columns
[
C
];
var
colspan
=
cell
.
getAttribute
(
'
colspan
'
);
var
rowspan
=
cell
.
getAttribute
(
'
rowspan
'
);
var
cellValue
=
cell
.
innerText
;
if
(
cellValue
!==
""
&&
cellValue
==
+
cellValue
)
cellValue
=
+
cellValue
;
//Skip ranges
ranges
.
forEach
(
function
(
range
)
{
if
(
R
>=
range
.
s
.
r
&&
R
<=
range
.
e
.
r
&&
outRow
.
length
>=
range
.
s
.
c
&&
outRow
.
length
<=
range
.
e
.
c
)
{
for
(
var
i
=
0
;
i
<=
range
.
e
.
c
-
range
.
s
.
c
;
++
i
)
outRow
.
push
(
null
);
}
});
//Handle Row Span
if
(
rowspan
||
colspan
)
{
rowspan
=
rowspan
||
1
;
colspan
=
colspan
||
1
;
ranges
.
push
({
s
:
{
r
:
R
,
c
:
outRow
.
length
},
e
:
{
r
:
R
+
rowspan
-
1
,
c
:
outRow
.
length
+
colspan
-
1
}});
}
;
//Handle Value
outRow
.
push
(
cellValue
!==
""
?
cellValue
:
null
);
//Handle Colspan
if
(
colspan
)
for
(
var
k
=
0
;
k
<
colspan
-
1
;
++
k
)
outRow
.
push
(
null
);
}
out
.
push
(
outRow
);
}
return
[
out
,
ranges
];
};
function
datenum
(
v
,
date1904
)
{
if
(
date1904
)
v
+=
1462
;
var
epoch
=
Date
.
parse
(
v
);
return
(
epoch
-
new
Date
(
Date
.
UTC
(
1899
,
11
,
30
)))
/
(
24
*
60
*
60
*
1000
);
}
function
sheet_from_array_of_arrays
(
data
,
opts
)
{
var
ws
=
{};
var
range
=
{
s
:
{
c
:
10000000
,
r
:
10000000
},
e
:
{
c
:
0
,
r
:
0
}};
for
(
var
R
=
0
;
R
!=
data
.
length
;
++
R
)
{
for
(
var
C
=
0
;
C
!=
data
[
R
].
length
;
++
C
)
{
if
(
range
.
s
.
r
>
R
)
range
.
s
.
r
=
R
;
if
(
range
.
s
.
c
>
C
)
range
.
s
.
c
=
C
;
if
(
range
.
e
.
r
<
R
)
range
.
e
.
r
=
R
;
if
(
range
.
e
.
c
<
C
)
range
.
e
.
c
=
C
;
var
cell
=
{
v
:
data
[
R
][
C
]};
if
(
cell
.
v
==
null
)
continue
;
var
cell_ref
=
XLSX
.
utils
.
encode_cell
({
c
:
C
,
r
:
R
});
if
(
typeof
cell
.
v
===
'
number
'
)
cell
.
t
=
'
n
'
;
else
if
(
typeof
cell
.
v
===
'
boolean
'
)
cell
.
t
=
'
b
'
;
else
if
(
cell
.
v
instanceof
Date
)
{
cell
.
t
=
'
n
'
;
cell
.
z
=
XLSX
.
SSF
.
_table
[
14
];
cell
.
v
=
datenum
(
cell
.
v
);
}
else
cell
.
t
=
'
s
'
;
ws
[
cell_ref
]
=
cell
;
}
}
if
(
range
.
s
.
c
<
10000000
)
ws
[
'
!ref
'
]
=
XLSX
.
utils
.
encode_range
(
range
);
return
ws
;
}
function
Workbook
()
{
if
(
!
(
this
instanceof
Workbook
))
return
new
Workbook
();
this
.
SheetNames
=
[];
this
.
Sheets
=
{};
}
function
s2ab
(
s
)
{
var
buf
=
new
ArrayBuffer
(
s
.
length
);
var
view
=
new
Uint8Array
(
buf
);
for
(
var
i
=
0
;
i
!=
s
.
length
;
++
i
)
view
[
i
]
=
s
.
charCodeAt
(
i
)
&
0xFF
;
return
buf
;
}
export
function
export_table_to_excel
(
id
)
{
var
theTable
=
document
.
getElementById
(
id
);
var
oo
=
generateArray
(
theTable
);
var
ranges
=
oo
[
1
];
/* original data */
var
data
=
oo
[
0
];
var
ws_name
=
"
SheetJS
"
;
var
wb
=
new
Workbook
(),
ws
=
sheet_from_array_of_arrays
(
data
);
/* add ranges to worksheet */
// ws['!cols'] = ['apple', 'banan'];
ws
[
'
!merges
'
]
=
ranges
;
/* add worksheet to workbook */
wb
.
SheetNames
.
push
(
ws_name
);
wb
.
Sheets
[
ws_name
]
=
ws
;
var
wbout
=
XLSX
.
write
(
wb
,
{
bookType
:
'
xlsx
'
,
bookSST
:
false
,
type
:
'
binary
'
});
saveAs
(
new
Blob
([
s2ab
(
wbout
)],
{
type
:
"
application/octet-stream
"
}),
"
test.xlsx
"
)
}
export
function
export_json_to_excel
(
th
,
jsonData
,
defaultTitle
)
{
/* original data */
var
data
=
jsonData
;
data
.
unshift
(
th
);
var
ws_name
=
"
SheetJS
"
;
var
wb
=
new
Workbook
(),
ws
=
sheet_from_array_of_arrays
(
data
);
/*设置worksheet每列的最大宽度*/
const
colWidth
=
data
.
map
(
row
=>
row
.
map
(
val
=>
{
/*先判断是否为null/undefined*/
if
(
val
==
null
)
{
return
{
'
wch
'
:
10
};
}
/*再判断是否为中文*/
else
if
(
val
.
toString
().
charCodeAt
(
0
)
>
255
)
{
return
{
'
wch
'
:
val
.
toString
().
length
*
2
};
}
else
{
return
{
'
wch
'
:
val
.
toString
().
length
};
}
}))
/*以第一行为初始值*/
let
result
=
colWidth
[
0
];
for
(
let
i
=
1
;
i
<
colWidth
.
length
;
i
++
)
{
for
(
let
j
=
0
;
j
<
colWidth
[
i
].
length
;
j
++
)
{
if
(
result
[
j
][
'
wch
'
]
<
colWidth
[
i
][
j
][
'
wch
'
])
{
result
[
j
][
'
wch
'
]
=
colWidth
[
i
][
j
][
'
wch
'
];
}
}
}
ws
[
'
!cols
'
]
=
result
;
/* add worksheet to workbook */
wb
.
SheetNames
.
push
(
ws_name
);
wb
.
Sheets
[
ws_name
]
=
ws
;
var
wbout
=
XLSX
.
write
(
wb
,
{
bookType
:
'
xlsx
'
,
bookSST
:
false
,
type
:
'
binary
'
});
var
title
=
defaultTitle
||
'
excel-list
'
saveAs
(
new
Blob
([
s2ab
(
wbout
)],
{
type
:
"
application/octet-stream
"
}),
title
+
"
.xlsx
"
)
}
function
formatJson
(
jsonSource
,
jsonFillter
)
{
return
jsonSource
.
map
(
v
=>
jsonFillter
.
map
(
j
=>
{
return
v
[
j
]
}))
}
export
function
export_json_to_excel2
(
th
,
jsonSource
,
jsonFillter
,
defaultTitle
)
{
const
data
=
formatJson
(
jsonSource
,
jsonFillter
)
export_json_to_excel
(
th
,
data
,
defaultTitle
)
}
\ No newline at end of file
Prev
1
…
6
7
8
9
10
11
12
13
14
…
18
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