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
2491 additions
and
0 deletions
+2491
-0
front-end/mall4cloud-multishop-master/src/components/Tinymce/plugins.js
...4cloud-multishop-master/src/components/Tinymce/plugins.js
+7
-0
front-end/mall4cloud-multishop-master/src/components/Tinymce/toolbar.js
...4cloud-multishop-master/src/components/Tinymce/toolbar.js
+6
-0
front-end/mall4cloud-multishop-master/src/components/Verifition/Verify.vue
...oud-multishop-master/src/components/Verifition/Verify.vue
+465
-0
front-end/mall4cloud-multishop-master/src/components/Verifition/Verify/VerifyPoints.vue
...-master/src/components/Verifition/Verify/VerifyPoints.vue
+246
-0
front-end/mall4cloud-multishop-master/src/components/Verifition/Verify/VerifySlide.vue
...p-master/src/components/Verifition/Verify/VerifySlide.vue
+348
-0
front-end/mall4cloud-multishop-master/src/components/Verifition/api/index.js
...d-multishop-master/src/components/Verifition/api/index.js
+19
-0
front-end/mall4cloud-multishop-master/src/components/Verifition/utils/ase.js
...d-multishop-master/src/components/Verifition/utils/ase.js
+11
-0
front-end/mall4cloud-multishop-master/src/components/Verifition/utils/axios.js
...multishop-master/src/components/Verifition/utils/axios.js
+30
-0
front-end/mall4cloud-multishop-master/src/components/Verifition/utils/util.js
...-multishop-master/src/components/Verifition/utils/util.js
+37
-0
front-end/mall4cloud-multishop-master/src/components/imgbox/index.vue
...ll4cloud-multishop-master/src/components/imgbox/index.vue
+1151
-0
front-end/mall4cloud-multishop-master/src/directive/permission/index.js
...4cloud-multishop-master/src/directive/permission/index.js
+13
-0
front-end/mall4cloud-multishop-master/src/directive/permission/permission.js
...d-multishop-master/src/directive/permission/permission.js
+35
-0
front-end/mall4cloud-multishop-master/src/filters/index.js
front-end/mall4cloud-multishop-master/src/filters/index.js
+68
-0
front-end/mall4cloud-multishop-master/src/icons/index.js
front-end/mall4cloud-multishop-master/src/icons/index.js
+9
-0
front-end/mall4cloud-multishop-master/src/icons/svg/analysis.svg
...nd/mall4cloud-multishop-master/src/icons/svg/analysis.svg
+21
-0
front-end/mall4cloud-multishop-master/src/icons/svg/dashboard.svg
...d/mall4cloud-multishop-master/src/icons/svg/dashboard.svg
+2
-0
front-end/mall4cloud-multishop-master/src/icons/svg/distribution.svg
...all4cloud-multishop-master/src/icons/svg/distribution.svg
+17
-0
front-end/mall4cloud-multishop-master/src/icons/svg/example.svg
...end/mall4cloud-multishop-master/src/icons/svg/example.svg
+2
-0
front-end/mall4cloud-multishop-master/src/icons/svg/eye-open.svg
...nd/mall4cloud-multishop-master/src/icons/svg/eye-open.svg
+2
-0
front-end/mall4cloud-multishop-master/src/icons/svg/eye.svg
front-end/mall4cloud-multishop-master/src/icons/svg/eye.svg
+2
-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/components/Tinymce/plugins.js
0 → 100644
View file @
a21f5a9a
// Any plugins you want to use has to be imported
// Detail plugins list see https://www.tinymce.com/docs/plugins/
// Custom builds see https://www.tinymce.com/download/custom-builds/
const
plugins
=
[
'
advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount
'
]
export
default
plugins
front-end/mall4cloud-multishop-master/src/components/Tinymce/toolbar.js
0 → 100644
View file @
a21f5a9a
// Here is a list of the toolbar
// Detail list see https://www.tinymce.com/docs/advanced/editor-control-identifiers/#toolbarcontrols
const
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
'
]
export
default
toolbar
front-end/mall4cloud-multishop-master/src/components/Verifition/Verify.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<div
:class=
"mode=='pop'?'mask':''"
v-show=
"showBox"
>
<div
:class=
"mode=='pop'?'verifybox':''"
:style=
"
{'max-width':parseInt(imgSize.width)+30+'px'}">
<div
class=
"verifybox-top"
v-if=
"mode=='pop'"
>
请完成安全验证
<span
class=
"verifybox-close"
@
click=
"closeBox"
>
<i
class=
"iconfont icon-close"
></i>
</span>
</div>
<div
class=
"verifybox-bottom"
:style=
"
{padding:mode=='pop'?'15px':'0'}">
<!-- 验证码容器 -->
<components
v-if=
"componentType"
:is=
"componentType"
:captchaType=
"captchaType"
:type=
"verifyType"
:figure=
"figure"
:arith=
"arith"
:mode=
"mode"
:vSpace=
"vSpace"
:explain=
"explain"
:imgSize=
"imgSize"
:blockSize=
"blockSize"
:barSize=
"barSize"
ref=
"instance"
></components>
</div>
</div>
</div>
</
template
>
<
script
type=
"text/babel"
>
/**
* Verify 验证码组件
* @description 分发验证码使用
* */
import
VerifySlide
from
'
./Verify/VerifySlide
'
import
VerifyPoints
from
'
./Verify/VerifyPoints
'
export
default
{
name
:
'
Vue2Verify
'
,
props
:
{
// 双语化
locale
:
{
require
:
false
,
type
:
String
,
default
()
{
// 默认语言不输入为浏览器语言
if
(
navigator
.
language
)
{
var
language
=
navigator
.
language
;
}
else
{
var
language
=
navigator
.
browserLanguage
;
}
return
language
}
},
captchaType
:
{
type
:
String
,
required
:
true
},
figure
:
{
type
:
Number
},
arith
:
{
type
:
Number
},
mode
:
{
type
:
String
,
default
:
'
pop
'
},
vSpace
:
{
type
:
Number
},
explain
:
{
type
:
String
},
imgSize
:
{
type
:
Object
,
default
()
{
return
{
width
:
'
310px
'
,
height
:
'
155px
'
}
}
},
blockSize
:
{
type
:
Object
},
barSize
:
{
type
:
Object
},
},
data
()
{
return
{
// showBox:true,
clickShow
:
false
,
// 内部类型
verifyType
:
undefined
,
// 所用组件类型
componentType
:
undefined
}
},
methods
:
{
/**
* i18n
* @description 兼容vue-i18n 调用$t来转换ok
* @param {String} text-被转换的目标
* @return {String} i18n的结果
* */
i18n
(
text
)
{
if
(
this
.
$t
)
{
return
this
.
$t
(
text
)
}
else
{
// 兼容不存在的语言
let
i18n
=
this
.
$options
.
i18n
.
messages
[
this
.
locale
]
||
this
.
$options
.
i18n
.
messages
[
'
en-US
'
]
return
i18n
[
text
]
}
},
/**
* refresh
* @description 刷新
* */
refresh
()
{
if
(
this
.
instance
.
refresh
)
{
this
.
instance
.
refresh
()
}
},
closeBox
()
{
this
.
clickShow
=
false
this
.
refresh
()
},
show
()
{
if
(
this
.
mode
==
"
pop
"
)
{
this
.
clickShow
=
true
}
}
},
computed
:
{
instance
()
{
return
this
.
$refs
.
instance
||
{}
},
showBox
()
{
if
(
this
.
mode
==
'
pop
'
)
{
return
this
.
clickShow
}
else
{
return
true
;
}
}
},
watch
:
{
captchaType
:
{
immediate
:
true
,
handler
(
captchaType
)
{
switch
(
captchaType
.
toString
())
{
case
'
blockPuzzle
'
:
this
.
verifyType
=
'
2
'
this
.
componentType
=
'
VerifySlide
'
break
case
'
clickWord
'
:
this
.
verifyType
=
''
this
.
componentType
=
'
VerifyPoints
'
break
}
}
}
},
components
:
{
VerifySlide
,
VerifyPoints
}
}
</
script
>
<
style
>
.verifybox
{
position
:
relative
;
box-sizing
:
border-box
;
border-radius
:
2px
;
border
:
1px
solid
#e4e7eb
;
background-color
:
#fff
;
box-shadow
:
0
0
10px
rgba
(
0
,
0
,
0
,
0.3
);
left
:
50%
;
top
:
50%
;
transform
:
translate
(
-50%
,
-50%
);
}
.verifybox-top
{
padding
:
0
15px
;
height
:
50px
;
line-height
:
50px
;
text-align
:
left
;
font-size
:
16px
;
color
:
#45494c
;
border-bottom
:
1px
solid
#e4e7eb
;
box-sizing
:
border-box
;
}
.verifybox-bottom
{
padding
:
15px
;
box-sizing
:
border-box
;
}
.verifybox-close
{
position
:
absolute
;
top
:
13px
;
right
:
9px
;
width
:
24px
;
height
:
24px
;
text-align
:
center
;
cursor
:
pointer
;
}
.mask
{
position
:
fixed
;
top
:
0
;
left
:
0
;
z-index
:
1001
;
width
:
100%
;
height
:
100vh
;
background
:
rgba
(
0
,
0
,
0
,
0.3
);
/* display: none; */
transition
:
all
0.5s
;
}
.verify-tips
{
position
:
absolute
;
left
:
0px
;
bottom
:
0px
;
width
:
100%
;
height
:
30px
;
line-height
:
30px
;
color
:
#fff
;
}
.suc-bg
{
background-color
:
rgba
(
92
,
184
,
92
,
0.5
);
filter
:
progid
:
DXImageTransform
.
Microsoft
.
gradient
(
startcolorstr
=
#7f5CB85
C
,
endcolorstr
=
#7f5CB85
C
);
}
.err-bg
{
background-color
:
rgba
(
217
,
83
,
79
,
0.5
);
filter
:
progid
:
DXImageTransform
.
Microsoft
.
gradient
(
startcolorstr
=
#7fD9534
F
,
endcolorstr
=
#7fD9534
F
);
}
.tips-enter
,
.tips-leave-to
{
bottom
:
-30px
;
}
.tips-enter-active
,
.tips-leave-active
{
transition
:
bottom
0.5s
;
}
/* ---------------------------- */
/*常规验证码*/
.verify-code
{
font-size
:
20px
;
text-align
:
center
;
cursor
:
pointer
;
margin-bottom
:
5px
;
border
:
1px
solid
#ddd
;
}
.cerify-code-panel
{
height
:
100%
;
overflow
:
hidden
;
}
.verify-code-area
{
float
:
left
;
}
.verify-input-area
{
float
:
left
;
width
:
60%
;
padding-right
:
10px
;
}
.verify-change-area
{
line-height
:
30px
;
float
:
left
;
}
.varify-input-code
{
display
:
inline-block
;
width
:
100%
;
height
:
25px
;
}
.verify-change-code
{
color
:
#337ab7
;
cursor
:
pointer
;
}
.verify-btn
{
width
:
200px
;
height
:
30px
;
background-color
:
#337ab7
;
color
:
#ffffff
;
border
:
none
;
margin-top
:
10px
;
}
/*滑动验证码*/
.verify-bar-area
{
position
:
relative
;
background
:
#ffffff
;
text-align
:
center
;
-webkit-box-sizing
:
content-box
;
-moz-box-sizing
:
content-box
;
box-sizing
:
content-box
;
border
:
1px
solid
#ddd
;
-webkit-border-radius
:
4px
;
}
.verify-bar-area
.verify-move-block
{
position
:
absolute
;
top
:
0px
;
left
:
0
;
background
:
#fff
;
cursor
:
pointer
;
-webkit-box-sizing
:
content-box
;
-moz-box-sizing
:
content-box
;
box-sizing
:
content-box
;
box-shadow
:
0
0
2px
#888888
;
-webkit-border-radius
:
1px
;
}
.verify-bar-area
.verify-move-block
:hover
{
background-color
:
#337ab7
;
color
:
#ffffff
;
}
.verify-bar-area
.verify-left-bar
{
position
:
absolute
;
top
:
-1px
;
left
:
-1px
;
background
:
#f0fff0
;
cursor
:
pointer
;
-webkit-box-sizing
:
content-box
;
-moz-box-sizing
:
content-box
;
box-sizing
:
content-box
;
border
:
1px
solid
#ddd
;
}
.verify-img-panel
{
margin
:
0
;
-webkit-box-sizing
:
content-box
;
-moz-box-sizing
:
content-box
;
box-sizing
:
content-box
;
border-top
:
1px
solid
#ddd
;
border-bottom
:
1px
solid
#ddd
;
border-radius
:
3px
;
position
:
relative
;
}
.verify-img-panel
.verify-refresh
{
width
:
25px
;
height
:
25px
;
text-align
:
center
;
padding
:
5px
;
cursor
:
pointer
;
position
:
absolute
;
top
:
0
;
right
:
0
;
z-index
:
2
;
}
.verify-img-panel
.icon-refresh
{
font-size
:
20px
;
color
:
#fff
;
}
.verify-img-panel
.verify-gap
{
background-color
:
#fff
;
position
:
relative
;
z-index
:
2
;
border
:
1px
solid
#fff
;
}
.verify-bar-area
.verify-move-block
.verify-sub-block
{
position
:
absolute
;
text-align
:
center
;
z-index
:
3
;
/* border: 1px solid #fff; */
}
.verify-bar-area
.verify-move-block
.verify-icon
{
font-size
:
18px
;
}
.verify-bar-area
.verify-msg
{
z-index
:
3
;
}
/*字体图标的css*/
/*@font-face {font-family: "iconfont";*/
/*src: url('../fonts/iconfont.eot?t=1508229193188'); !* IE9*!*/
/*src: url('../fonts/iconfont.eot?t=1508229193188#iefix') format('embedded-opentype'), !* IE6-IE8 *!*/
/*url('data:application/x-font-woff;charset=utf-8;base64,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') format('woff'),*/
/*url('../fonts/iconfont.ttf?t=1508229193188') format('truetype'), !* chrome, firefox, opera, Safari, Android, iOS 4.2+*!*/
/*url('../fonts/iconfont.svg?t=1508229193188#iconfont') format('svg'); !* iOS 4.1- *!*/
/*}*/
.iconfont
{
font-family
:
"iconfont"
!important
;
font-size
:
16px
;
font-style
:
normal
;
-webkit-font-smoothing
:
antialiased
;
-moz-osx-font-smoothing
:
grayscale
;
}
.icon-check
:before
{
content
:
" "
;
display
:
block
;
width
:
16px
;
height
:
16px
;
position
:
absolute
;
margin
:
auto
;
left
:
0
;
right
:
0
;
top
:
0
;
bottom
:
0
;
z-index
:
9999
;
background-image
:
url("data:image/png;base64,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")
;
background-size
:
contain
;
}
.icon-close
:before
{
content
:
" "
;
display
:
block
;
width
:
16px
;
height
:
16px
;
position
:
absolute
;
margin
:
auto
;
left
:
0
;
right
:
0
;
top
:
0
;
bottom
:
0
;
z-index
:
9999
;
background-image
:
url("data:image/png;base64,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")
;
background-size
:
contain
;
}
.icon-right
:before
{
content
:
" "
;
display
:
block
;
width
:
16px
;
height
:
16px
;
position
:
absolute
;
margin
:
auto
;
left
:
0
;
right
:
0
;
top
:
0
;
bottom
:
0
;
background-size
:
cover
;
z-index
:
9999
;
background-image
:
url("data:image/png;base64,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")
;
background-size
:
contain
;
}
.icon-refresh
:before
{
content
:
" "
;
display
:
block
;
width
:
16px
;
height
:
16px
;
position
:
absolute
;
margin
:
auto
;
left
:
0
;
right
:
0
;
top
:
0
;
bottom
:
0
;
z-index
:
9999
;
background-image
:
url("data:image/png;base64,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")
;
background-size
:
contain
;
}
</
style
>
front-end/mall4cloud-multishop-master/src/components/Verifition/Verify/VerifyPoints.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<div
style=
"position: relative"
>
<div
class=
"verify-img-out"
>
<div
class=
"verify-img-panel"
:style=
"
{'width': setSize.imgWidth,
'height': setSize.imgHeight,
'background-size' : setSize.imgWidth + ' '+ setSize.imgHeight,
'margin-bottom': vSpace + 'px'}"
>
<div
class=
"verify-refresh"
style=
"z-index:3"
@
click=
"refresh"
v-show=
"showRefresh"
>
<i
class=
"iconfont icon-refresh"
></i>
</div>
<img
:src=
"'data:image/png;base64,'+pointBackImgBase"
ref=
"canvas"
alt=
""
style=
"width:100%;height:100%;display:block"
@
click=
"bindingClick?canvasClick($event):undefined"
>
<div
v-for=
"(tempPoint, index) in tempPoints"
:key=
"index"
class=
"point-area"
:style=
"
{
'background-color':'#1abd6c',
color:'#fff',
'z-index':9999,
width:'20px',
height:'20px',
'text-align':'center',
'line-height':'20px',
'border-radius': '50%',
position:'absolute',
top:parseInt(tempPoint.y-10) + 'px',
left:parseInt(tempPoint.x-10) + 'px'
}">
{{
index
+
1
}}
</div>
</div>
</div>
<!-- 'height': this.barSize.height, -->
<div
class=
"verify-bar-area"
:style=
"
{'width': setSize.imgWidth,
'color': this.barAreaColor,
'border-color': this.barAreaBorderColor,
'line-height':this.barSize.height}">
<span
class=
"verify-msg"
>
{{
text
}}
</span>
</div>
</div>
</
template
>
<
script
type=
"text/babel"
>
/**
* VerifyPoints
* @description 点选
* */
import
{
resetSize
,
_code_chars
,
_code_color1
,
_code_color2
}
from
'
./../utils/util
'
import
{
aesEncrypt
}
from
"
./../utils/ase
"
import
{
reqGet
,
reqCheck
}
from
"
./../api/index
"
export
default
{
name
:
'
VerifyPoints
'
,
props
:
{
//弹出式pop,固定fixed
mode
:
{
type
:
String
,
default
:
'
fixed
'
},
captchaType
:{
type
:
String
,
},
//间隔
vSpace
:
{
type
:
Number
,
default
:
5
},
imgSize
:
{
type
:
Object
,
default
()
{
return
{
width
:
'
310px
'
,
height
:
'
155px
'
}
}
},
barSize
:
{
type
:
Object
,
default
()
{
return
{
width
:
'
310px
'
,
height
:
'
40px
'
}
}
}
},
data
()
{
return
{
secretKey
:
''
,
//后端返回的ase加密秘钥
checkNum
:
3
,
//默认需要点击的字数
fontPos
:
[],
//选中的坐标信息
checkPosArr
:
[],
//用户点击的坐标
num
:
1
,
//点击的记数
pointBackImgBase
:
''
,
//后端获取到的背景图片
poinTextList
:[],
//后端返回的点击字体顺序
backToken
:
''
,
//后端返回的token值
setSize
:
{
imgHeight
:
0
,
imgWidth
:
0
,
barHeight
:
0
,
barWidth
:
0
},
tempPoints
:
[],
text
:
''
,
barAreaColor
:
undefined
,
barAreaBorderColor
:
undefined
,
showRefresh
:
true
,
bindingClick
:
true
}
},
computed
:
{
resetSize
()
{
return
resetSize
}
},
methods
:
{
init
()
{
//加载页面
this
.
fontPos
.
splice
(
0
,
this
.
fontPos
.
length
)
this
.
checkPosArr
.
splice
(
0
,
this
.
checkPosArr
.
length
)
this
.
num
=
1
this
.
getPictrue
();
this
.
$nextTick
(()
=>
{
this
.
setSize
=
this
.
resetSize
(
this
)
//重新设置宽度高度
this
.
$parent
.
$emit
(
'
ready
'
,
this
)
})
},
canvasClick
(
e
)
{
this
.
checkPosArr
.
push
(
this
.
getMousePos
(
this
.
$refs
.
canvas
,
e
));
if
(
this
.
num
==
this
.
checkNum
)
{
this
.
num
=
this
.
createPoint
(
this
.
getMousePos
(
this
.
$refs
.
canvas
,
e
));
//按比例转换坐标值
this
.
checkPosArr
=
this
.
pointTransfrom
(
this
.
checkPosArr
,
this
.
setSize
);
//等创建坐标执行完
setTimeout
(()
=>
{
// var flag = this.comparePos(this.fontPos, this.checkPosArr);
//发送后端请求
var
captchaVerification
=
this
.
secretKey
?
aesEncrypt
(
this
.
backToken
+
'
---
'
+
JSON
.
stringify
(
this
.
checkPosArr
),
this
.
secretKey
):
this
.
backToken
+
'
---
'
+
JSON
.
stringify
(
this
.
checkPosArr
)
let
data
=
{
captchaType
:
this
.
captchaType
,
"
pointJson
"
:
this
.
secretKey
?
aesEncrypt
(
JSON
.
stringify
(
this
.
checkPosArr
),
this
.
secretKey
):
JSON
.
stringify
(
this
.
checkPosArr
),
"
token
"
:
this
.
backToken
}
reqCheck
(
data
).
then
(
res
=>
{
if
(
res
.
repCode
==
"
0000
"
)
{
this
.
barAreaColor
=
'
#4cae4c
'
this
.
barAreaBorderColor
=
'
#5cb85c
'
this
.
text
=
'
验证成功
'
this
.
bindingClick
=
false
if
(
this
.
mode
==
'
pop
'
)
{
setTimeout
(()
=>
{
this
.
$parent
.
clickShow
=
false
;
this
.
refresh
();
},
1500
)
}
this
.
$parent
.
$emit
(
'
success
'
,
{
captchaVerification
})
}
else
{
this
.
$parent
.
$emit
(
'
error
'
,
this
)
this
.
barAreaColor
=
'
#d9534f
'
this
.
barAreaBorderColor
=
'
#d9534f
'
this
.
text
=
'
验证失败
'
setTimeout
(()
=>
{
this
.
refresh
();
},
700
);
}
})
},
400
);
}
if
(
this
.
num
<
this
.
checkNum
)
{
this
.
num
=
this
.
createPoint
(
this
.
getMousePos
(
this
.
$refs
.
canvas
,
e
));
}
},
//获取坐标
getMousePos
:
function
(
obj
,
e
)
{
var
x
=
e
.
offsetX
var
y
=
e
.
offsetY
return
{
x
,
y
}
},
//创建坐标点
createPoint
:
function
(
pos
)
{
this
.
tempPoints
.
push
(
Object
.
assign
({},
pos
))
return
++
this
.
num
;
},
refresh
:
function
()
{
this
.
tempPoints
.
splice
(
0
,
this
.
tempPoints
.
length
)
this
.
barAreaColor
=
'
#000
'
this
.
barAreaBorderColor
=
'
#ddd
'
this
.
bindingClick
=
true
this
.
fontPos
.
splice
(
0
,
this
.
fontPos
.
length
)
this
.
checkPosArr
.
splice
(
0
,
this
.
checkPosArr
.
length
)
this
.
num
=
1
this
.
getPictrue
();
this
.
text
=
'
验证失败
'
this
.
showRefresh
=
true
},
// 请求背景图片和验证图片
getPictrue
(){
let
data
=
{
captchaType
:
this
.
captchaType
}
reqGet
(
data
).
then
(
res
=>
{
if
(
res
.
repCode
==
"
0000
"
)
{
this
.
pointBackImgBase
=
res
.
repData
.
originalImageBase64
this
.
backToken
=
res
.
repData
.
token
this
.
secretKey
=
res
.
repData
.
secretKey
this
.
poinTextList
=
res
.
repData
.
wordList
this
.
text
=
'
请依次点击【
'
+
this
.
poinTextList
.
join
(
"
,
"
)
+
'
】
'
}
else
{
this
.
text
=
res
.
repMsg
;
}
})
},
//坐标转换函数
pointTransfrom
(
pointArr
,
imgSize
){
var
newPointArr
=
pointArr
.
map
(
p
=>
{
let
x
=
Math
.
round
(
310
*
p
.
x
/
parseInt
(
imgSize
.
imgWidth
))
let
y
=
Math
.
round
(
155
*
p
.
y
/
parseInt
(
imgSize
.
imgHeight
))
return
{
x
,
y
}
})
// console.log(newPointArr,"newPointArr");
return
newPointArr
}
},
watch
:
{
// type变化则全面刷新
type
:
{
immediate
:
true
,
handler
()
{
this
.
init
()
}
}
},
mounted
()
{
// 禁止拖拽
this
.
$el
.
onselectstart
=
function
()
{
return
false
}
},
}
</
script
>
\ No newline at end of file
front-end/mall4cloud-multishop-master/src/components/Verifition/Verify/VerifySlide.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<div
style=
"position: relative;"
>
<div
v-if=
"type === '2'"
class=
"verify-img-out"
:style=
"
{height: (parseInt(setSize.imgHeight) + vSpace) + 'px'}"
>
<div
class=
"verify-img-panel"
:style=
"
{width: setSize.imgWidth,
height: setSize.imgHeight,}">
<img
:src=
"'data:image/png;base64,'+backImgBase"
alt=
""
style=
"width:100%;height:100%;display:block"
>
<div
class=
"verify-refresh"
@
click=
"refresh"
v-show=
"showRefresh"
><i
class=
"iconfont icon-refresh"
></i>
</div>
<transition
name=
"tips"
>
<span
class=
"verify-tips"
v-if=
"tipWords"
:class=
"passFlag ?'suc-bg':'err-bg'"
>
{{
tipWords
}}
</span>
</transition>
</div>
</div>
<!-- 公共部分 -->
<div
class=
"verify-bar-area"
:style=
"
{width: setSize.imgWidth,
height: barSize.height,
'line-height':barSize.height}">
<span
class=
"verify-msg"
v-text=
"text"
></span>
<div
class=
"verify-left-bar"
:style=
"
{width: (leftBarWidth!==undefined)?leftBarWidth: barSize.height, height: barSize.height, 'border-color': leftBarBorderColor, transaction: transitionWidth}">
<span
class=
"verify-msg"
v-text=
"finishText"
></span>
<div
class=
"verify-move-block"
@
touchstart=
"start"
@
mousedown=
"start"
:style=
"
{width: barSize.height, height: barSize.height, 'background-color': moveBlockBackgroundColor, left: moveBlockLeft, transition: transitionLeft}">
<i
:class=
"['verify-icon iconfont', iconClass]"
:style=
"
{color: iconColor}">
</i>
<div
v-if=
"type === '2'"
class=
"verify-sub-block"
:style=
"
{'width':Math.floor(parseInt(setSize.imgWidth)*47/310)+ 'px',
'height': setSize.imgHeight,
'top':'-' + (parseInt(setSize.imgHeight) + vSpace) + 'px',
'background-size': setSize.imgWidth + ' ' + setSize.imgHeight,
}">
<img
:src=
"'data:image/png;base64,'+blockBackImgBase"
alt=
""
style=
"width:100%;height:100%;display:block"
>
</div>
</div>
</div>
</div>
</div>
</
template
>
<
script
type=
"text/babel"
>
/**
* VerifySlide
* @description 滑块
* */
import
{
aesEncrypt
}
from
"
./../utils/ase
"
import
{
resetSize
}
from
'
./../utils/util
'
import
{
reqGet
,
reqCheck
}
from
"
./../api/index
"
// "captchaType":"blockPuzzle",
export
default
{
name
:
'
VerifySlide
'
,
props
:
{
captchaType
:{
type
:
String
,
},
type
:
{
type
:
String
,
default
:
'
1
'
},
//弹出式pop,固定fixed
mode
:
{
type
:
String
,
default
:
'
fixed
'
},
vSpace
:
{
type
:
Number
,
default
:
5
},
explain
:
{
type
:
String
,
default
:
'
向右滑动完成验证
'
},
imgSize
:
{
type
:
Object
,
default
()
{
return
{
width
:
'
310px
'
,
height
:
'
155px
'
}
}
},
blockSize
:
{
type
:
Object
,
default
()
{
return
{
width
:
'
50px
'
,
height
:
'
50px
'
}
}
},
barSize
:
{
type
:
Object
,
default
()
{
return
{
width
:
'
310px
'
,
height
:
'
40px
'
}
}
}
},
data
()
{
return
{
secretKey
:
''
,
//后端返回的加密秘钥 字段
passFlag
:
''
,
//是否通过的标识
backImgBase
:
''
,
//验证码背景图片
blockBackImgBase
:
''
,
//验证滑块的背景图片
backToken
:
""
,
//后端返回的唯一token值
startMoveTime
:
""
,
//移动开始的时间
endMovetime
:
''
,
//移动结束的时间
tipsBackColor
:
''
,
//提示词的背景颜色
tipWords
:
''
,
text
:
''
,
finishText
:
''
,
setSize
:
{
imgHeight
:
0
,
imgWidth
:
0
,
barHeight
:
0
,
barWidth
:
0
},
top
:
0
,
left
:
0
,
moveBlockLeft
:
undefined
,
leftBarWidth
:
undefined
,
// 移动中样式
moveBlockBackgroundColor
:
undefined
,
leftBarBorderColor
:
'
#ddd
'
,
iconColor
:
undefined
,
iconClass
:
'
icon-right
'
,
status
:
false
,
//鼠标状态
isEnd
:
false
,
//是够验证完成
showRefresh
:
true
,
transitionLeft
:
''
,
transitionWidth
:
''
}
},
computed
:
{
barArea
()
{
return
this
.
$el
.
querySelector
(
'
.verify-bar-area
'
)
},
resetSize
()
{
return
resetSize
}
},
methods
:
{
init
()
{
this
.
text
=
this
.
explain
this
.
getPictrue
();
this
.
$nextTick
(()
=>
{
let
setSize
=
this
.
resetSize
(
this
)
//重新设置宽度高度
for
(
let
key
in
setSize
)
{
this
.
$set
(
this
.
setSize
,
key
,
setSize
[
key
])
}
this
.
$parent
.
$emit
(
'
ready
'
,
this
)
})
var
_this
=
this
window
.
removeEventListener
(
"
touchmove
"
,
function
(
e
)
{
_this
.
move
(
e
);
});
window
.
removeEventListener
(
"
mousemove
"
,
function
(
e
)
{
_this
.
move
(
e
);
});
//鼠标松开
window
.
removeEventListener
(
"
touchend
"
,
function
()
{
_this
.
end
();
});
window
.
removeEventListener
(
"
mouseup
"
,
function
()
{
_this
.
end
();
});
window
.
addEventListener
(
"
touchmove
"
,
function
(
e
)
{
_this
.
move
(
e
);
});
window
.
addEventListener
(
"
mousemove
"
,
function
(
e
)
{
_this
.
move
(
e
);
});
//鼠标松开
window
.
addEventListener
(
"
touchend
"
,
function
()
{
_this
.
end
();
});
window
.
addEventListener
(
"
mouseup
"
,
function
()
{
_this
.
end
();
});
},
//鼠标按下
start
:
function
(
e
)
{
e
=
e
||
window
.
event
if
(
!
e
.
touches
)
{
//兼容PC端
var
x
=
e
.
clientX
;
}
else
{
//兼容移动端
var
x
=
e
.
touches
[
0
].
pageX
;
}
this
.
startLeft
=
Math
.
floor
(
x
-
this
.
barArea
.
getBoundingClientRect
().
left
);
this
.
startMoveTime
=
+
new
Date
();
//开始滑动的时间
if
(
this
.
isEnd
==
false
)
{
this
.
text
=
''
this
.
moveBlockBackgroundColor
=
'
#337ab7
'
this
.
leftBarBorderColor
=
'
#337AB7
'
this
.
iconColor
=
'
#fff
'
e
.
stopPropagation
();
this
.
status
=
true
;
}
},
//鼠标移动
move
:
function
(
e
)
{
e
=
e
||
window
.
event
if
(
this
.
status
&&
this
.
isEnd
==
false
)
{
if
(
!
e
.
touches
)
{
//兼容PC端
var
x
=
e
.
clientX
;
}
else
{
//兼容移动端
var
x
=
e
.
touches
[
0
].
pageX
;
}
var
bar_area_left
=
this
.
barArea
.
getBoundingClientRect
().
left
;
var
move_block_left
=
x
-
bar_area_left
//小方块相对于父元素的left值
if
(
move_block_left
>=
this
.
barArea
.
offsetWidth
-
parseInt
(
parseInt
(
this
.
blockSize
.
width
)
/
2
)
-
2
)
{
move_block_left
=
this
.
barArea
.
offsetWidth
-
parseInt
(
parseInt
(
this
.
blockSize
.
width
)
/
2
)
-
2
;
}
if
(
move_block_left
<=
0
)
{
move_block_left
=
parseInt
(
parseInt
(
this
.
blockSize
.
width
)
/
2
);
}
//拖动后小方块的left值
this
.
moveBlockLeft
=
(
move_block_left
-
this
.
startLeft
)
+
"
px
"
this
.
leftBarWidth
=
(
move_block_left
-
this
.
startLeft
)
+
"
px
"
}
},
//鼠标松开
end
:
function
()
{
this
.
endMovetime
=
+
new
Date
();
var
_this
=
this
;
//判断是否重合
if
(
this
.
status
&&
this
.
isEnd
==
false
)
{
var
moveLeftDistance
=
parseInt
((
this
.
moveBlockLeft
||
''
).
replace
(
'
px
'
,
''
));
moveLeftDistance
=
moveLeftDistance
*
310
/
parseInt
(
this
.
setSize
.
imgWidth
)
let
data
=
{
captchaType
:
this
.
captchaType
,
"
pointJson
"
:
this
.
secretKey
?
aesEncrypt
(
JSON
.
stringify
({
x
:
moveLeftDistance
,
y
:
5.0
}),
this
.
secretKey
):
JSON
.
stringify
({
x
:
moveLeftDistance
,
y
:
5.0
}),
"
token
"
:
this
.
backToken
}
reqCheck
(
data
).
then
(
res
=>
{
if
(
res
.
repCode
==
"
0000
"
)
{
this
.
moveBlockBackgroundColor
=
'
#5cb85c
'
this
.
leftBarBorderColor
=
'
#5cb85c
'
this
.
iconColor
=
'
#fff
'
this
.
iconClass
=
'
icon-check
'
this
.
showRefresh
=
false
this
.
isEnd
=
true
;
if
(
this
.
mode
==
'
pop
'
)
{
setTimeout
(()
=>
{
this
.
$parent
.
clickShow
=
false
;
this
.
refresh
();
},
1500
)
}
this
.
passFlag
=
true
this
.
tipWords
=
`
${((
this
.
endMovetime
-
this
.
startMoveTime
)
/
1000
).
toFixed
(
2
)}
s验证成功`
var
captchaVerification
=
this
.
secretKey
?
aesEncrypt
(
this
.
backToken
+
'
---
'
+
JSON
.
stringify
({
x
:
moveLeftDistance
,
y
:
5.0
}),
this
.
secretKey
):
this
.
backToken
+
'
---
'
+
JSON
.
stringify
({
x
:
moveLeftDistance
,
y
:
5.0
})
setTimeout
(()
=>
{
this
.
tipWords
=
""
this
.
$parent
.
closeBox
();
this
.
$parent
.
$emit
(
'
success
'
,
{
captchaVerification
})
},
1000
)
}
else
{
this
.
moveBlockBackgroundColor
=
'
#d9534f
'
this
.
leftBarBorderColor
=
'
#d9534f
'
this
.
iconColor
=
'
#fff
'
this
.
iconClass
=
'
icon-close
'
this
.
passFlag
=
false
setTimeout
(
function
()
{
_this
.
refresh
();
},
1000
);
this
.
$parent
.
$emit
(
'
error
'
,
this
)
this
.
tipWords
=
"
验证失败
"
setTimeout
(()
=>
{
this
.
tipWords
=
""
},
1000
)
}
})
this
.
status
=
false
;
}
},
refresh
:
function
()
{
this
.
showRefresh
=
true
this
.
finishText
=
''
this
.
transitionLeft
=
'
left .3s
'
this
.
moveBlockLeft
=
0
this
.
leftBarWidth
=
undefined
this
.
transitionWidth
=
'
width .3s
'
this
.
leftBarBorderColor
=
'
#ddd
'
this
.
moveBlockBackgroundColor
=
'
#fff
'
this
.
iconColor
=
'
#000
'
this
.
iconClass
=
'
icon-right
'
this
.
isEnd
=
false
this
.
getPictrue
()
setTimeout
(()
=>
{
this
.
transitionWidth
=
''
this
.
transitionLeft
=
''
this
.
text
=
this
.
explain
},
300
)
},
// 请求背景图片和验证图片
getPictrue
(){
let
data
=
{
captchaType
:
this
.
captchaType
}
reqGet
(
data
).
then
(
res
=>
{
if
(
res
.
repCode
==
"
0000
"
)
{
this
.
backImgBase
=
res
.
repData
.
originalImageBase64
this
.
blockBackImgBase
=
res
.
repData
.
jigsawImageBase64
this
.
backToken
=
res
.
repData
.
token
this
.
secretKey
=
res
.
repData
.
secretKey
}
else
{
this
.
tipWords
=
res
.
repMsg
;
}
})
},
},
watch
:
{
// type变化则全面刷新
type
:
{
immediate
:
true
,
handler
()
{
this
.
init
()
}
}
},
mounted
()
{
// 禁止拖拽
this
.
$el
.
onselectstart
=
function
()
{
return
false
}
},
}
</
script
>
front-end/mall4cloud-multishop-master/src/components/Verifition/api/index.js
0 → 100644
View file @
a21f5a9a
import
request
from
'
@/utils/request
'
// 获取验证图片 以及token
export
function
reqGet
(
data
)
{
return
request
({
url
:
'
/mall4cloud_auth/ua/captcha/get
'
,
method
:
'
post
'
,
data
})
}
// 滑动或者点选验证
export
function
reqCheck
(
data
)
{
return
request
({
url
:
'
/mall4cloud_auth/ua/captcha/check
'
,
method
:
'
post
'
,
data
})
}
front-end/mall4cloud-multishop-master/src/components/Verifition/utils/ase.js
0 → 100644
View file @
a21f5a9a
import
CryptoJS
from
'
crypto-js
'
/**
* @word 要加密的内容
* @keyWord String 服务器随机返回的关键字
* */
export
function
aesEncrypt
(
word
,
keyWord
=
"
XwKsGlMcdPMEhR1B
"
){
var
key
=
CryptoJS
.
enc
.
Utf8
.
parse
(
keyWord
);
var
srcs
=
CryptoJS
.
enc
.
Utf8
.
parse
(
word
);
var
encrypted
=
CryptoJS
.
AES
.
encrypt
(
srcs
,
key
,
{
mode
:
CryptoJS
.
mode
.
ECB
,
padding
:
CryptoJS
.
pad
.
Pkcs7
});
return
encrypted
.
toString
();
}
front-end/mall4cloud-multishop-master/src/components/Verifition/utils/axios.js
0 → 100644
View file @
a21f5a9a
import
axios
from
'
axios
'
axios
.
defaults
.
baseURL
=
process
.
env
.
VUE_APP_BASE_API
const
service
=
axios
.
create
({
timeout
:
40000
,
headers
:
{
'
X-Requested-With
'
:
'
XMLHttpRequest
'
,
'
Content-Type
'
:
'
application/json; charset=UTF-8
'
},
})
service
.
interceptors
.
request
.
use
(
config
=>
{
return
config
},
error
=>
{
Promise
.
reject
(
error
)
}
)
// response interceptor
service
.
interceptors
.
response
.
use
(
response
=>
{
const
res
=
response
.
data
;
return
res
},
error
=>
{
}
)
export
default
service
front-end/mall4cloud-multishop-master/src/components/Verifition/utils/util.js
0 → 100644
View file @
a21f5a9a
export
function
resetSize
(
vm
)
{
var
img_width
,
img_height
,
bar_width
,
bar_height
;
//图片的宽度、高度,移动条的宽度、高度
var
parentWidth
=
vm
.
$el
.
parentNode
.
offsetWidth
||
window
.
offsetWidth
var
parentHeight
=
vm
.
$el
.
parentNode
.
offsetHeight
||
window
.
offsetHeight
if
(
vm
.
imgSize
.
width
.
indexOf
(
'
%
'
)
!=
-
1
)
{
img_width
=
parseInt
(
this
.
imgSize
.
width
)
/
100
*
parentWidth
+
'
px
'
}
else
{
img_width
=
this
.
imgSize
.
width
;
}
if
(
vm
.
imgSize
.
height
.
indexOf
(
'
%
'
)
!=
-
1
)
{
img_height
=
parseInt
(
this
.
imgSize
.
height
)
/
100
*
parentHeight
+
'
px
'
}
else
{
img_height
=
this
.
imgSize
.
height
}
if
(
vm
.
barSize
.
width
.
indexOf
(
'
%
'
)
!=
-
1
)
{
bar_width
=
parseInt
(
this
.
barSize
.
width
)
/
100
*
parentWidth
+
'
px
'
}
else
{
bar_width
=
this
.
barSize
.
width
}
if
(
vm
.
barSize
.
height
.
indexOf
(
'
%
'
)
!=
-
1
)
{
bar_height
=
parseInt
(
this
.
barSize
.
height
)
/
100
*
parentHeight
+
'
px
'
}
else
{
bar_height
=
this
.
barSize
.
height
}
return
{
imgWidth
:
img_width
,
imgHeight
:
img_height
,
barWidth
:
bar_width
,
barHeight
:
bar_height
}
}
export
const
_code_chars
=
[
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
'
a
'
,
'
b
'
,
'
c
'
,
'
d
'
,
'
e
'
,
'
f
'
,
'
g
'
,
'
h
'
,
'
i
'
,
'
j
'
,
'
k
'
,
'
l
'
,
'
m
'
,
'
n
'
,
'
o
'
,
'
p
'
,
'
q
'
,
'
r
'
,
'
s
'
,
'
t
'
,
'
u
'
,
'
v
'
,
'
w
'
,
'
x
'
,
'
y
'
,
'
z
'
,
'
A
'
,
'
B
'
,
'
C
'
,
'
D
'
,
'
E
'
,
'
F
'
,
'
G
'
,
'
H
'
,
'
I
'
,
'
J
'
,
'
K
'
,
'
L
'
,
'
M
'
,
'
N
'
,
'
O
'
,
'
P
'
,
'
Q
'
,
'
R
'
,
'
S
'
,
'
T
'
,
'
U
'
,
'
V
'
,
'
W
'
,
'
X
'
,
'
Y
'
,
'
Z
'
]
export
const
_code_color1
=
[
'
#fffff0
'
,
'
#f0ffff
'
,
'
#f0fff0
'
,
'
#fff0f0
'
]
export
const
_code_color2
=
[
'
#FF0033
'
,
'
#006699
'
,
'
#993366
'
,
'
#FF9900
'
,
'
#66CC66
'
,
'
#FF33CC
'
]
\ No newline at end of file
front-end/mall4cloud-multishop-master/src/components/imgbox/index.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<div
class=
"elx-imgbox"
>
<el-dialog
:title=
"$t('biz.imgbox.picManager')"
:visible.sync=
"visible"
class=
"elx-imgbox-dialog"
top=
"10vh"
:append-to-body=
"visible"
>
<div
class=
"file-group"
>
<div
class=
"upload-btn"
>
<div
class=
"up-btn"
>
<el-button
type=
"primary"
plain
size=
"medium"
class=
"el-icon-top"
@
click=
"uploadFileBtn"
>
上传图片
</el-button>
<el-button
size=
"medium"
@
click=
"selectOrCreateGroup(1)"
class=
"el-icon-plus"
>
新建分组
</el-button>
</div>
<!-- 搜索 -->
<el-form
:inline=
"true"
:model=
"dataForm"
class=
"demo-form-inline form"
>
<el-form-item>
<el-input
v-model=
"fileName"
size=
"medium"
:placeholder=
"$t('biz.imgbox.picName')"
clearable
></el-input>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
@
click=
"searchImg"
icon=
"el-icon-search"
size=
"medium"
>
{{
$t
(
"
biz.imgbox.query
"
)
}}
</el-button>
</el-form-item>
</el-form>
</div>
<div
class=
"img-group-box"
>
<!-- 左侧栏 -->
<div
class=
"left-sidebar"
>
<div
class=
"group-list"
>
<div
:class=
"['group-item', dataForm.attachFileGroupId===0?'active':'']"
>
<span
class=
"group-name"
@
click=
"clickOneGroup(0)"
>
全部图片
</span>
</div>
<div
:class=
"['group-item', dataForm.attachFileGroupId===gItem.attachFileGroupId?'active':'']"
v-for=
"(gItem, gIdx) in groupList"
:key=
"gIdx"
>
<span
class=
"group-name"
@
click=
"clickOneGroup(gItem.attachFileGroupId)"
>
{{
gItem
.
name
}}
</span>
<span
class=
"sidebar-operate"
>
<i
class=
"el-icon-edit"
@
click=
"selectOrCreateGroup(1,gItem.attachFileGroupId,gIdx)"
></i>
<i
class=
"el-icon-delete"
@
click=
"deleteFileGroup(gItem.attachFileGroupId)"
></i>
</span>
</div>
</div>
</div>
<!-- 图片列表 -->
<div
v-if=
"options.activeTab==='pick'"
class=
"pick-block"
name=
"pick"
>
<div
class=
"elx-main elx-img-list"
>
<div
class=
"elx-img-list-loading"
v-if=
"isLoading"
>
<div
class=
"el-icon-loading"
></div>
</div>
<div
class=
"img-item"
v-for=
"(img, itemIndex) in imgRes"
:key=
"itemIndex"
>
<div
class=
"thumb-wp"
@
click=
"onClickListImage(img)"
>
<img
:src=
"(img.filePath).indexOf('http')===-1 ? resourcesUrl + img.filePath : img.filePath"
alt=
"img.name"
/>
</div>
<div
class=
"title"
@
click=
"onClickListImage(img)"
>
{{
img
.
fileName
}}
</div>
<div
class=
"operate"
>
<el-link
type=
"info"
class=
"edit"
@
click=
"changeName(img)"
>
{{
$t
(
"
table.edit
"
)
}}
</el-link>
<el-link
type=
"danger"
class=
"del"
@
click=
"delectImg(img.fileId)"
>
{{
$t
(
"
table.delete
"
)
}}
</el-link>
</div>
<!--
<div
class=
"label"
v-if=
"img.label"
>
{{
img
.
label
}}
</div>
-->
<span
class=
"selected"
v-if=
"img.selected"
@
click=
"onClickListImage(img)"
>
<span
class=
"icon el-icon-check"
></span>
</span>
</div>
<div
class=
"empty"
v-if=
"!imgRes.length"
>
暂无图片
</div>
</div>
<el-pagination
layout=
"total, prev, pager, next"
:current-page=
"page.current"
:page-size=
"page.size"
:total=
"page.total"
@
current-change=
"onPageNumChange"
></el-pagination>
<div
class=
"elx-foot"
>
<el-badge
:value=
"images.length"
class=
"item"
v-if=
"!type"
>
<el-button
type=
"primary"
size=
"medium"
:disabled=
"images.length == 0"
@
click=
"onConfirm"
>
{{
$t
(
"
table.confirm
"
)
}}
</el-button>
</el-badge>
<el-button
type=
"primary"
size=
"medium"
:disabled=
"disabled"
@
click=
"onConfirm"
v-else
>
{{
$t
(
"
table.confirm
"
)
}}
</el-button>
<el-button
type=
"primary"
size=
"medium"
@
click=
"uploadFileBtn"
plain
>
{{
$t
(
"
biz.imgbox.uploadPic
"
)
}}
</el-button>
</div>
</div>
<!-- 上传图片 -->
<div
v-if=
"options.activeTab==='upload'"
class=
"upload-block"
name=
"upload"
>
<div
class=
"elx-main"
>
<div
class=
"upload-title"
>
{{
$t
(
"
biz.imgbox.selectLocalPic
"
)
}}
</div>
<el-upload
ref=
"upload"
class=
"upload-img-preview"
list-type=
"picture-card"
accept=
"image/*"
action=
""
:http-request=
"httpRequest"
:multiple=
"true"
:auto-upload=
"false"
:limit=
"uploadNumberLimit()"
:before-upload=
"beforeUpload"
:on-success=
"onUploadSuccess"
:on-error=
"onUploadError"
:on-exceed=
"onUploadExceedTip"
>
<i
class=
"el-icon-plus"
></i>
</el-upload>
<div
class=
"file-gropu-btn"
>
<span
v-if=
"groupForm.name"
class=
"sel-group-name"
>
{{
groupForm
.
name
}}
</span><el-button
type=
"text"
size=
"medium"
@
click=
"selectOrCreateGroup(0)"
>
选择分组
</el-button>
<el-button
type=
"text"
size=
"medium"
@
click=
"selectOrCreateGroup(1)"
>
新建分组
</el-button>
</div>
<div
class=
"upload-tip"
>
{{
uploadTips
()
}}
</div>
<div
class=
"elx-foot"
>
<el-button
type=
"primary"
size=
"medium"
@
click=
"onUploadConfirm"
>
{{
$t
(
"
biz.imgbox.confirmUpload
"
)
}}
</el-button>
</div>
</div>
</div>
</div>
<!-- 选择/创建/修改分组 -->
<el-dialog
:title=
"selectGroup?'选择分组':createGroup?'新建分组':''"
:visible.sync=
"showGroupVisible"
:append-to-body=
"showGroupVisible"
>
<el-form
:model=
"groupForm"
ref=
"groupForm"
label-width=
"90px"
style=
"width:400px"
>
<el-form-item
v-if=
"createGroup"
label=
"分组名称"
prop=
"name"
>
<el-input
placeholder=
"请输入分组名称"
v-model=
"groupForm.name"
></el-input>
</el-form-item>
<el-form-item
v-if=
"selectGroup"
label=
"选择分组"
>
<el-select
v-model=
"groupForm.attachFileGroupId"
placeholder=
"请选择"
>
<el-option
v-for=
"item in groupList"
:key=
"item.attachFileGroupId"
:label=
"item.name"
:value=
"item.attachFileGroupId"
>
</el-option>
</el-select>
</el-form-item>
</el-form>
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"showGroupVisible = false"
>
{{
$t
(
'
table.cancel
'
)
}}
</el-button>
<el-button
type=
"primary"
@
click=
"groupFormSubmit()"
>
{{
$t
(
'
table.confirm
'
)
}}
</el-button>
</div>
</el-dialog>
</div>
<!-- 修改图片名称 -->
<el-dialog
:title=
"$t('biz.imgbox.revisePicName')"
:close-on-click-modal=
"false"
:visible.sync=
"changeNameVisible"
top=
"200px"
:append-to-body=
"visible"
width=
"600px"
>
<el-form
:model=
"imageObject"
ref=
"imgDataForm"
label-width=
"80px"
v-if=
"changeNameVisible"
>
<el-form-item
:label=
"$t('biz.imgbox.oldName')"
>
<span>
{{
imageObject
.
fileName
}}
</span>
</el-form-item>
<el-form-item
:label=
"$t('biz.imgbox.revName')"
>
<el-input
:placeholder=
"$t('biz.imgbox.inputNewName')"
v-model=
"newImgName"
clearable
></el-input>
</el-form-item>
<el-form-item
label=
"选择分组"
>
<el-select
v-model=
"groupForm.attachFileGroupId"
placeholder=
"请选择"
>
<el-option
v-for=
"item in groupList"
:key=
"item.attachFileGroupId"
:label=
"item.name"
:value=
"item.attachFileGroupId"
>
</el-option>
</el-select>
</el-form-item>
</el-form>
<span
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"changeNameVisible = false"
>
{{
$t
(
"
table.cancel
"
)
}}
</el-button>
<el-button
@
click=
"submitImgName()"
>
{{
$t
(
"
table.confirm
"
)
}}
</el-button>
</span>
</el-dialog>
<!-- /修改图片名称 -->
</el-dialog>
</div>
</
template
>
<
script
type=
"text/babel"
>
import
{
ossInfo
,
pageFileGroup
,
saveFileGroup
,
updateFileGroup
,
deleteFileGroup
,
aliImgUpdate
,
minIoImgUpdate
}
from
'
@/api/biz/oss
'
import
{
save
,
page
,
updateFileName
,
deleteFile
}
from
'
@/api/biz/attach-file
'
import
{
getUUID
}
from
'
@/utils/index
'
export
default
{
name
:
'
ElxImgbox
'
,
data
()
{
return
{
images
:
[],
// 已选图片
dataForm
:
{
policy
:
''
,
signature
:
''
,
key
:
''
,
ossaccessKeyId
:
''
,
dir
:
''
,
host
:
''
,
attachFileGroupId
:
0
,
},
groupList
:
[],
// 分组列表
attachFiles
:
[],
resourcesUrl
:
process
.
env
.
VUE_APP_RESOURCES_URL
,
resourcesActionType
:
process
.
env
.
VUE_APP_RESOURCES_TYPE
,
showGroupVisible
:
false
,
// 选择/创建分组弹窗
selectGroup
:
false
,
// 选择分组
createGroup
:
false
,
// 创建分组
groupForm
:
{
attachFileGroupId
:
''
,
// 选择分组的值
name
:
''
,
// 分组名称
},
groupId
:
null
,
oriImgName
:
null
,
// 图片原名称
rules
:
{
name
:
[
{
required
:
true
,
message
:
'
分组名称不能为空
'
,
trigger
:
'
blur
'
},
{
min
:
0
,
max
:
6
,
message
:
'
长度在1-6个字符
'
,
trigger
:
'
blur
'
}
],
attachFileGroupId
:
[
{
required
:
true
,
message
:
'
请选择分组
'
,
trigger
:
'
change
'
}
]
},
options
:
{
multiple
:
true
,
// 是否支持选取多个图片
limit
:
20
,
// 最多可选择图片数量
maxSize
:
2
,
// 最大尺寸(M)
activeTab
:
'
pick
'
,
enableUpload
:
false
,
// 是否启用图片上传
callback
:
null
},
newImgName
:
''
,
ossList
:
null
,
isTrue
:
true
,
imageObject
:
null
,
changeNameVisible
:
false
,
type
:
2
,
fileName
:
''
,
listType
:
'
picture
'
,
isLoading
:
true
,
visible
:
false
,
disabled
:
false
,
notImg
:
false
,
uploadSuccessCount
:
0
,
imgRes
:
[],
page
:
{
current
:
1
,
size
:
15
,
total
:
0
}
}
},
methods
:
{
/**
* 初始化
* type 1:单图 2:多图
*/
init
(
type
,
limit
)
{
this
.
visible
=
true
this
.
isLoading
=
false
this
.
images
=
[]
this
.
type
=
type
if
(
type
===
1
)
{
this
.
type
=
true
this
.
disabled
=
true
}
else
{
this
.
type
=
false
this
.
limit
=
limit
}
if
(
this
.
$refs
.
upload
)
{
this
.
$refs
.
upload
.
uploadFiles
=
[]
}
// 获取产品数据 - 第一页的数据
this
.
page
.
current
=
1
this
.
loadImageGroup
()
// 分组
this
.
loadListImage
()
// 图片列表
},
show
()
{
this
.
visible
=
true
},
hide
()
{
this
.
visible
=
false
},
/**
* 加载图片分组列表
*/
loadImageGroup
()
{
pageFileGroup
().
then
((
data
)
=>
{
this
.
groupList
=
data
})
},
/**
* 点击图片分组item
*/
clickOneGroup
(
id
)
{
this
.
dataForm
.
attachFileGroupId
=
id
this
.
options
.
activeTab
=
'
pick
'
this
.
loadListImage
()
},
/**
* 打开选择/新建分组
*/
selectOrCreateGroup
(
st
,
groupId
,
gIdx
)
{
if
(
!
groupId
)
{
this
.
groupForm
.
attachFileGroupId
=
null
this
.
groupForm
.
name
=
null
}
if
(
st
===
0
)
{
// 选择分组
if
(
!
this
.
groupList
.
length
)
{
this
.
$message
({
message
:
'
当前暂无分组可选择,请先创建分组
'
,
duration
:
1500
})
this
.
showGroupVisible
=
false
return
}
else
{
this
.
selectGroup
=
true
this
.
createGroup
=
false
}
}
else
if
(
st
===
1
)
{
// 编辑/创建分组
this
.
createGroup
=
true
this
.
selectGroup
=
false
if
(
groupId
)
{
this
.
groupForm
.
name
=
this
.
groupList
[
gIdx
].
name
this
.
groupForm
.
attachFileGroupId
=
groupId
this
.
groupId
=
groupId
}
}
this
.
showGroupVisible
=
true
},
/**
* 提交选择/创建/修改分组
*/
groupFormSubmit
()
{
this
.
$refs
.
groupForm
.
validate
(
valid
=>
{
if
(
!
valid
)
{
return
}
if
(
this
.
selectGroup
)
{
if
(
!
this
.
groupForm
.
attachFileGroupId
)
{
this
.
$message
({
message
:
'
请选择分组
'
,
type
:
'
warning
'
,
duration
:
1000
})
return
}
this
.
groupList
.
forEach
(
el
=>
{
if
(
this
.
groupForm
.
attachFileGroupId
==
el
.
attachFileGroupId
)
{
this
.
groupForm
.
name
=
el
.
name
}
})
this
.
showGroupVisible
=
false
return
}
if
(
this
.
createGroup
)
{
if
(
!
this
.
groupForm
.
name
)
{
this
.
$message
({
message
:
'
分组名称不能为空
'
,
type
:
'
warning
'
,
duration
:
1000
})
}
var
param
=
{
attachFileGroupId
:
this
.
groupForm
.
attachFileGroupId
,
name
:
this
.
groupForm
.
name
}
const
request
=
this
.
groupId
?
updateFileGroup
(
param
)
:
saveFileGroup
(
param
)
request
.
then
(
data
=>
{
this
.
$message
({
message
:
this
.
$t
(
'
table.actionSuccess
'
),
type
:
'
success
'
,
duration
:
1500
,
onClose
:
()
=>
{
this
.
showGroupVisible
=
false
this
.
loadImageGroup
()
}
})
})
return
}
})
},
/**
* 删除分组
*/
deleteFileGroup
(
groupId
)
{
this
.
$confirm
(
this
.
$t
(
'
table.sureToDelete
'
),
this
.
$t
(
'
table.tips
'
),
{
confirmButtonText
:
this
.
$t
(
'
table.confirm
'
),
cancelButtonText
:
this
.
$t
(
'
table.cancel
'
),
type
:
'
warning
'
}).
then
(()
=>
{
const
data
=
{
attachFileGroupId
:
groupId
}
deleteFileGroup
(
data
).
then
((
delData
)
=>
{
this
.
$message
({
message
:
this
.
$t
(
'
table.actionSuccess
'
),
type
:
'
success
'
,
duration
:
1500
,
onClose
:
()
=>
{
this
.
loadImageGroup
()
this
.
searchImg
()
}
})
})
})
},
/**
* 加载图片列表数据
* @param page
*/
loadListImage
()
{
this
.
isLoading
=
true
const
param
=
{
pageNum
:
this
.
page
.
current
?
this
.
page
.
current
:
1
,
pageSize
:
this
.
page
.
size
,
fileName
:
this
.
fileName
?
this
.
fileName
:
null
,
fileGroupId
:
this
.
dataForm
.
attachFileGroupId
||
0
}
page
(
param
).
then
(
response
=>
{
this
.
imgRes
=
response
.
list
this
.
page
.
pages
=
response
.
pages
this
.
page
.
total
=
response
.
total
this
.
isLoading
=
false
})
},
onConfirm
()
{
if
(
this
.
type
)
{
this
.
$emit
(
'
refreshPic
'
,
this
.
images
[
0
].
filePath
)
}
else
{
let
imgPaths
=
this
.
images
.
map
(
file
=>
{
return
file
.
filePath
}).
join
(
'
,
'
)
this
.
$emit
(
'
refreshPic
'
,
imgPaths
)
}
this
.
visible
=
false
},
/**
* 修改图片名称
*/
changeName
(
img
)
{
this
.
newImgName
=
''
this
.
imageObject
=
img
this
.
isTrue
=
true
this
.
changeNameVisible
=
true
this
.
oriImgName
=
img
.
fileName
this
.
groupList
.
forEach
(
el
=>
{
if
(
img
.
attachFileGroupId
==
el
.
attachFileGroupId
)
{
this
.
groupForm
.
name
=
el
.
name
this
.
groupForm
.
attachFileGroupId
=
el
.
attachFileGroupId
return
}
else
{
this
.
groupForm
.
name
=
null
this
.
groupForm
.
attachFileGroupId
=
null
}
})
},
/**
* 提交修改后的图片名称
*/
submitImgName
()
{
if
(
!
this
.
isTrue
)
{
return
false
}
this
.
isTrue
=
false
const
data
=
{
fileId
:
this
.
imageObject
.
fileId
,
fileName
:
this
.
newImgName
?
this
.
newImgName
:
this
.
oriImgName
,
attachFileGroupId
:
this
.
groupForm
.
attachFileGroupId
}
updateFileName
(
data
).
then
(({
data
})
=>
{
this
.
newImgName
=
''
this
.
isTrue
=
true
this
.
changeNameVisible
=
false
this
.
loadListImage
()
}).
catch
(({
e
})
=>
{
this
.
isTrue
=
true
})
},
/**
* 删除图片
*/
delectImg
(
fileId
)
{
this
.
$confirm
(
this
.
$t
(
'
table.sureToDelete
'
),
this
.
$t
(
'
table.tips
'
),
{
confirmButtonText
:
this
.
$t
(
'
table.confirm
'
),
cancelButtonText
:
this
.
$t
(
'
table.cancel
'
),
type
:
'
warning
'
}).
then
(()
=>
{
// this.$http({
// url: this.$http.adornUrl('/admin/file/deleteFile/' + fileId),
// method: 'delete'
// }).then(({ data }) => {
// this.images = []
// this.loadListImage()
// })
const
data
=
{
fileId
:
fileId
}
deleteFile
(
data
).
then
((
data
)
=>
{
this
.
images
=
[]
this
.
searchImg
()
})
})
},
/**
* 点击上传图片按钮
*/
uploadFileBtn
()
{
this
.
options
.
activeTab
=
'
upload
'
this
.
dataForm
.
attachFileGroupId
=
null
},
/**
* 点击图片时选中或取消选中图片
* @param img object
*/
onClickListImage
(
img
)
{
console
.
log
(
img
)
if
(
this
.
type
)
{
this
.
clearListSelected
()
this
.
images
=
[]
this
.
disabled
=
false
}
else
{
var
imgIndex
=
this
.
selectedImageIndex
(
img
)
// 取消图片已选状态
img
.
selected
=
false
this
.
images
.
splice
(
imgIndex
,
1
)
}
if
(
!
this
.
type
&&
this
.
images
.
length
>=
this
.
limit
)
{
this
.
message
(
this
.
$t
(
'
biz.imgbox.superiorLimit
'
))
return
false
}
this
.
images
.
push
(
JSON
.
parse
(
JSON
.
stringify
(
img
)))
img
.
selected
=
true
this
.
$forceUpdate
()
},
/**
* 清除所有已点击图片样式
*/
clearListSelected
()
{
if
(
this
.
type
)
{
let
list
=
this
.
imgRes
list
.
forEach
(
element
=>
{
element
.
selected
=
false
})
}
},
/**
* 按图片名称搜索图片
*/
searchImg
()
{
this
.
page
.
current
=
1
this
.
loadListImage
()
},
/**
* 图片已选则返回下标,未选则返回-1
*/
selectedImageIndex
(
img
)
{
for
(
let
i
=
0
;
i
<
this
.
images
.
length
;
i
++
)
{
var
selectedImg
=
this
.
images
[
i
]
if
(
selectedImg
.
fileId
===
img
.
fileId
)
{
return
i
}
}
return
-
1
},
/**
* 分页页面变化时刷新数据
* @param page
*/
onPageNumChange
(
page
)
{
this
.
page
.
current
=
page
this
.
loadListImage
()
},
/**
* 获取上传图片数据
*/
onUploadConfirm
()
{
let
fileNum
=
this
.
$refs
.
upload
.
uploadFiles
.
length
ossInfo
(
fileNum
).
then
(
response
=>
{
console
.
log
(
'
选择图片response:
'
,
response
)
if
(
this
.
resourcesActionType
===
'
0
'
)
{
this
.
dataForm
.
policy
=
response
.
policy
this
.
dataForm
.
signature
=
response
.
signature
this
.
dataForm
.
ossaccessKeyId
=
response
.
accessid
this
.
dataForm
.
dir
=
response
.
dir
}
this
.
ossList
=
response
.
ossList
this
.
notImg
=
true
this
.
$nextTick
(()
=>
{
this
.
$refs
.
upload
.
submit
()
})
})
},
/**
* 上传图片
*/
httpRequest
(
event
)
{
console
.
log
(
'
上传图片event:
'
,
event
)
let
file
=
event
.
file
let
typeArray
=
file
.
type
.
split
(
'
/
'
)
const
attachFile
=
Object
.
assign
({
fileType
:
typeArray
[
1
],
fileName
:
file
.
name
,
fileSize
:
file
.
size
,
type
:
1
,
})
if
(
this
.
ossList
.
length
<=
0
)
{
this
.
message
(
'
数据异常,请刷洗后重试
'
)
}
// aliOss 上传
if
(
this
.
resourcesActionType
===
'
0
'
)
{
attachFile
.
filePath
=
'
/
'
+
this
.
dataForm
.
dir
+
this
.
ossList
[
0
].
fileName
const
formdata
=
new
FormData
();
formdata
.
append
(
'
policy
'
,
this
.
dataForm
.
policy
);
formdata
.
append
(
'
signature
'
,
this
.
dataForm
.
signature
);
formdata
.
append
(
'
ossaccessKeyId
'
,
this
.
dataForm
.
ossaccessKeyId
);
formdata
.
append
(
'
dir
'
,
this
.
dataForm
.
dir
);
formdata
.
append
(
'
host
'
,
this
.
resourcesUrl
);
formdata
.
append
(
'
key
'
,
this
.
ossList
[
0
].
dir
+
this
.
ossList
[
0
].
fileName
);
formdata
.
append
(
'
file
'
,
file
);
aliImgUpdate
(
this
.
resourcesUrl
,
formdata
).
then
(
data
=>
{
}).
catch
(
error
=>
{
if
(
!
error
)
{
event
.
onError
()
}
})
}
// mioIo 上传
else
{
attachFile
.
filePath
=
'
/
'
+
this
.
ossList
[
0
].
dir
+
this
.
ossList
[
0
].
fileName
console
.
log
(
'
mioIo 上传 file:
'
,
file
)
minIoImgUpdate
(
this
.
ossList
[
0
].
actionUrl
,
file
).
then
(
data
=>
{
})
}
this
.
attachFiles
.
push
(
attachFile
)
this
.
ossList
.
splice
(
0
,
1
)
if
(
this
.
ossList
<=
0
)
{
event
.
onSuccess
()
}
},
/**
* 上传图片前检查合法性
* @param file
* @returns {boolean}
*/
beforeUpload
(
file
)
{
let
typeArray
=
file
.
type
.
split
(
'
/
'
)
if
(
typeArray
[
0
]
!==
'
image
'
)
{
if
(
this
.
notImg
)
{
this
.
message
(
this
.
$t
(
'
biz.imgbox.onlyPictures
'
),
true
)
this
.
notImg
=
false
}
return
false
}
const
isSize
=
file
.
size
/
(
1024
*
1024
)
<
2
if
(
!
isSize
)
{
this
.
message
(
this
.
uploadSizeTip
())
return
false
}
// this.dataForm.key = this.dataForm.dir + getUUID()
// const attachFile = Object.assign({
// filePath: '/' + this.dataForm.key,
// fileType: typeArray[1],
// fileName: file.name,
// fileSize: file.size,
// type: 1,
// })
// this.attachFiles.push(attachFile)
return
true
},
uploadNumberLimit
()
{
if
(
!
this
.
options
.
multiple
)
{
return
1
}
return
this
.
options
.
limit
-
this
.
images
.
length
},
uploadTypeTip
()
{
return
this
.
$t
(
'
biz.imgbox.onlySupported
'
)
+
'
jpg/png/gif
'
+
this
.
$t
(
'
biz.imgbox.pic
'
)
},
uploadSizeTip
()
{
return
this
.
$t
(
'
biz.imgbox.notExceed
'
)
+
'
2M
'
},
uploadTips
()
{
let
tips
=
[
this
.
uploadTypeTip
(),
this
.
uploadSizeTip
()]
if
(
!
this
.
options
.
multiple
)
{
return
tips
.
join
(
'
,
'
)
}
if
(
this
.
images
.
length
>
0
)
{
tips
.
push
(
this
.
$t
(
'
biz.imgbox.alreadyExist
'
)
+
this
.
images
.
length
+
this
.
$t
(
'
biz.imgbox.unit
'
))
}
const
uploadFileNum
=
this
.
$refs
.
upload
?
this
.
$refs
.
upload
.
uploadFiles
.
length
:
0
if
(
uploadFileNum
>
0
)
{
tips
.
push
(
this
.
$t
(
'
biz.imgbox.soonUpload
'
)
+
uploadFileNum
+
this
.
$t
(
'
biz.imgbox.unit
'
))
}
tips
.
push
(
this
.
$t
(
'
biz.imgbox.remainder
'
)
+
(
this
.
options
.
limit
-
this
.
images
.
length
-
uploadFileNum
)
+
this
.
$t
(
'
biz.imgbox.unit
'
)
+
this
.
$t
(
'
biz.imgbox.upload
'
))
return
tips
.
join
(
'
,
'
)
},
/**
* 上传错误处理
* @param err
* @param file
* @param fileList
*/
onUploadError
(
err
,
file
,
fileList
)
{
this
.
message
(
this
.
$t
(
'
biz.imgbox.requestError
'
),
true
)
throw
err
},
/**
* 上传成功处理,并提交图片数据
* @param response
* @param file
* @param fileList
* @returns {boolean}
*/
onUploadSuccess
(
response
,
file
,
fileList
)
{
var
filesNames
=
[]
fileList
.
forEach
(
file
=>
{
filesNames
.
push
(
file
.
name
)
})
var
uploadFile
=
[]
this
.
attachFiles
.
forEach
(
file
=>
{
if
(
filesNames
.
indexOf
(
file
.
fileName
)
!==
-
1
)
{
file
.
attachFileGroupId
=
this
.
groupForm
.
attachFileGroupId
uploadFile
.
push
(
file
)
}
})
console
.
log
(
'
上传成功处理attachFiles:
'
,
this
.
attachFiles
)
console
.
log
(
'
上传成功处理uploadFile:
'
,
uploadFile
)
save
(
uploadFile
).
then
(
response
=>
{
this
.
attachFiles
=
[]
this
.
options
.
activeTab
=
'
pick
'
this
.
dataForm
.
attachFileGroupId
=
0
this
.
loadListImage
()
})
this
.
disabled
=
true
this
.
$refs
.
upload
.
uploadFiles
=
[]
this
.
page
.
current
=
1
},
/**
* 选择上传文件超过限制文件个数提示
*/
onUploadExceedTip
()
{
this
.
message
(
this
.
$t
(
'
biz.imgbox.maxSelect
'
)
+
this
.
uploadNumberLimit
()
+
this
.
$t
(
'
biz.imgbox.unit
'
)
+
this
.
$t
(
'
biz.imgbox.upload
'
))
},
message
(
msg
,
isInfo
)
{
var
type
=
'
error
'
if
(
isInfo
)
{
type
=
'
info
'
}
this
.
$message
({
message
:
msg
,
type
:
type
,
duration
:
1500
})
}
},
// mounted() {
// this.loadListImage()
// },
computed
:
{
}
}
</
script
>
<
style
lang=
"scss"
>
.elx-images
{
.el-upload-list__item
,
.el-upload--picture-card
{
width
:
78px
;
height
:
78px
;
line-height
:
82px
;
border-radius
:
5px
;
}
}
.elx-imgbox-dialog
{
$bg
:
#f6f6f6
;
// top: 100px;
.el-badge
{
vertical-align
:
bottom
;
}
.el-dialog
{
width
:
820px
;
.el-dialog__header
{
border-bottom
:
1px
solid
#e8e8e8
;
}
.el-dialog__body
{
padding
:
0
;
// background: $bg;
}
}
.elx-foot
{
padding
:
15px
0
0
10px
;
.el-button
{
margin
:
0
0
0
10px
;
}
}
.file-group
{
padding
:
20px
0
;
.upload-btn
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
padding
:
0
10px
;
margin-bottom
:
15px
;
}
.img-group-box
{
display
:
flex
;
// 左侧栏
.left-sidebar
{
display
:
block
;
height
:
620px
;
font-size
:
13px
;
color
:
#666
;
.group-list
{
height
:
100%
;
border-right
:
1px
solid
#f2f3f5
;
overflow
:
auto
;
.group-item
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
width
:
190px
;
padding
:
0
10px
;
height
:
38px
;
line-height
:
38px
;
text-align
:
left
;
box-sizing
:
border-box
;
.group-name
{
margin-right
:
6px
;
min-width
:
100px
;
max-width
:
118px
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
cursor
:
pointer
;
}
.sidebar-operate
{
// display: none;
.el-icon-delete
,
.el-icon-edit
{
margin-left
:
10px
;
cursor
:
pointer
;
}
}
}
.group-item
:hover
,
.group-item.active
{
background
:
#f2f3f5
;
// .sidebar-operate {
// display: block;
// }
}
}
}
// 图片列表
.pick-block
{
position
:
relative
;
width
:
620px
;
height
:
620px
;
.elx-img-list-loading
{
position
:
absolute
;
// top: 60px;
left
:
0
;
right
:
0
;
z-index
:
9
;
width
:
100%
;
height
:
520px
;
// 加载层高度
background
:
#fff
;
text-align
:
center
;
.el-icon-loading
{
font-size
:
50px
;
color
:
#409eff
;
line-height
:
460px
;
}
}
.elx-img-list
{
padding
:
10px
;
// 图片列表高度
height
:
520px
;
.img-item
{
$imgSize
:
100px
;
$size
:
104px
;
float
:
left
;
margin
:
10px
;
width
:
$imgSize
;
cursor
:
pointer
;
position
:
relative
;
font-size
:
12px
;
img
{
width
:
$imgSize
;
height
:
$imgSize
;
display
:
block
;
}
.title
{
line-height
:
24px
;
height
:
24px
;
display
:
block
;
overflow
:
hidden
;
background
:
$bg
;
padding
:
0
5px
;
}
.title
{
line-height
:
24px
;
height
:
24px
;
display
:
block
;
overflow
:
hidden
;
background
:
$bg
;
padding
:
0
5px
;
}
.operate
{
line-height
:
24px
;
height
:
24px
;
display
:
block
;
overflow
:
hidden
;
// background: $bg;
margin-top
:
2px
;
padding
:
0
5px
;
.edit
{
float
:
left
;
padding-left
:
5px
;
}
.del
{
float
:
right
;
padding-right
:
5px
;
}
}
.label
{
position
:
absolute
;
z-index
:
9
;
left
:
0
;
bottom
:
24px
;
width
:
100%
;
height
:
21px
;
line-height
:
21px
;
text-align
:
center
;
color
:
#fff
;
&
:after
{
content
:
" "
;
position
:
absolute
;
left
:
0
;
bottom
:
0
;
width
:
100%
;
height
:
21px
;
background
:
#000
;
opacity
:
0
.3
;
z-index
:
-1
;
}
}
.selected
{
position
:
absolute
;
right
:
-3px
;
top
:
-3px
;
width
:
$size
;
height
:
130px
;
border
:
3px
solid
#409eff
;
border-radius
:
3px
;
text-align
:
right
;
.icon
{
background
:
#409eff
;
text-align
:
center
;
height
:
24px
;
width
:
24px
;
line-height
:
24px
;
display
:
inline-block
;
font-size
:
16px
;
color
:
#fff
;
border-radius
:
0
0
0
3px
;
position
:
absolute
;
right
:
0
;
top
:
0
;
}
}
}
&
::after
{
content
:
" "
;
display
:
table
;
height
:
0
;
clear
:
both
;
visibility
:
hidden
;
}
.empty
{
display
:
block
;
width
:
100%
;
margin-top
:
150px
;
color
:
#bbb
;
text-align
:
center
;
}
}
.el-pagination
{
background
:
#f9f9f9
;
position
:
relative
;
padding
:
5px
;
margin
:
5px
24px
0
20px
;
text-align
:
right
;
float
:
none
;
*
{
background
:
none
;
}
}
}
}
}
.upload-block
{
.upload-img-preview
{
padding
:
20px
;
/* 上传图片预览改为使用背景图片按比例缩放方式 */
.el-upload--picture-card
,
.el-upload-list--picture-card
.el-upload-list__item
,
.el-upload-list--picture-card
.el-upload-list__item
.wp
{
width
:
90px
;
height
:
90px
;
line-height
:
98px
;
background-size
:
cover
;
background-position
:
50%
50%
;
}
.el-upload-list--picture-card
.el-upload-list__item-status-label
i
{
margin-top
:
12px
;
vertical-align
:
top
;
}
}
.upload-tip
{
padding
:
0
20px
;
font-size
:
13px
;
color
:
#999
;
}
.upload-title
{
font-size
:
16px
;
color
:
#666
;
padding
:
20px
0
0
20px
;
}
.file-gropu-btn
{
padding
:
0
20px
;
margin-bottom
:
10px
;
.sel-group-name
{
margin-right
:
10px
;
}
}
}
}
.form
{
// padding: 15px 0px 0px 20px;
margin-left
:
50px
;
.el-form-item
{
margin-bottom
:
0
;
}
}
.el-upload-list__item-actions
{
a
{
i
{
color
:
#fff
;
}
}
}
</
style
>
front-end/mall4cloud-multishop-master/src/directive/permission/index.js
0 → 100644
View file @
a21f5a9a
import
permission
from
'
./permission
'
const
install
=
function
(
Vue
)
{
Vue
.
directive
(
'
permission
'
,
permission
)
}
if
(
window
.
Vue
)
{
window
[
'
permission
'
]
=
permission
Vue
.
use
(
install
);
// eslint-disable-line
}
permission
.
install
=
install
export
default
permission
front-end/mall4cloud-multishop-master/src/directive/permission/permission.js
0 → 100644
View file @
a21f5a9a
import
store
from
'
@/store
'
function
checkPermission
(
el
,
binding
)
{
const
{
value
}
=
binding
const
roles
=
store
.
getters
&&
store
.
getters
.
roles
const
isAdmin
=
store
.
getters
&&
store
.
getters
.
isAdmin
if
(
isAdmin
)
{
return
true
}
if
(
value
&&
value
instanceof
Array
)
{
if
(
value
.
length
>
0
)
{
const
permissionRoles
=
value
const
hasPermission
=
roles
.
some
(
role
=>
{
console
.
log
(
permissionRoles
.
includes
(
role
))
return
permissionRoles
.
includes
(
role
)
})
if
(
!
hasPermission
)
{
el
.
parentNode
&&
el
.
parentNode
.
removeChild
(
el
)
}
}
}
else
{
throw
new
Error
(
`need roles! Like v-permission="['admin','editor']"`
)
}
}
export
default
{
inserted
(
el
,
binding
)
{
checkPermission
(
el
,
binding
)
},
update
(
el
,
binding
)
{
checkPermission
(
el
,
binding
)
}
}
front-end/mall4cloud-multishop-master/src/filters/index.js
0 → 100644
View file @
a21f5a9a
// import parseTime, formatTime and set to filter
export
{
parseTime
,
formatTime
}
from
'
@/utils
'
/**
* Show plural label if time is plural number
* @param {number} time
* @param {string} label
* @return {string}
*/
function
pluralize
(
time
,
label
)
{
if
(
time
===
1
)
{
return
time
+
label
}
return
time
+
label
+
'
s
'
}
/**
* @param {number} time
*/
export
function
timeAgo
(
time
)
{
const
between
=
Date
.
now
()
/
1000
-
Number
(
time
)
if
(
between
<
3600
)
{
return
pluralize
(
~~
(
between
/
60
),
'
minute
'
)
}
else
if
(
between
<
86400
)
{
return
pluralize
(
~~
(
between
/
3600
),
'
hour
'
)
}
else
{
return
pluralize
(
~~
(
between
/
86400
),
'
day
'
)
}
}
/**
* Number formatting
* like 10000 => 10k
* @param {number} num
* @param {number} digits
*/
export
function
numberFormatter
(
num
,
digits
)
{
const
si
=
[
{
value
:
1
E18
,
symbol
:
'
E
'
},
{
value
:
1
E15
,
symbol
:
'
P
'
},
{
value
:
1
E12
,
symbol
:
'
T
'
},
{
value
:
1
E9
,
symbol
:
'
G
'
},
{
value
:
1
E6
,
symbol
:
'
M
'
},
{
value
:
1
E3
,
symbol
:
'
k
'
}
]
for
(
let
i
=
0
;
i
<
si
.
length
;
i
++
)
{
if
(
num
>=
si
[
i
].
value
)
{
return
(
num
/
si
[
i
].
value
).
toFixed
(
digits
).
replace
(
/
\.
0+$|
(\.[
0-9
]
*
[
1-9
])
0+$/
,
'
$1
'
)
+
si
[
i
].
symbol
}
}
return
num
.
toString
()
}
/**
* 10000 => "10,000"
* @param {number} num
*/
export
function
toThousandFilter
(
num
)
{
return
(
+
num
||
0
).
toString
().
replace
(
/^-
?\d
+/g
,
m
=>
m
.
replace
(
/
(?=(?!\b)(\d{3})
+$
)
/g
,
'
,
'
))
}
/**
* Upper case first char
* @param {String} string
*/
export
function
uppercaseFirst
(
string
)
{
return
string
.
charAt
(
0
).
toUpperCase
()
+
string
.
slice
(
1
)
}
front-end/mall4cloud-multishop-master/src/icons/index.js
0 → 100644
View file @
a21f5a9a
import
Vue
from
'
vue
'
import
SvgIcon
from
'
@/components/SvgIcon
'
// svg component
// register globally
Vue
.
component
(
'
svg-icon
'
,
SvgIcon
)
const
req
=
require
.
context
(
'
./svg
'
,
false
,
/
\.
svg$/
)
const
requireAll
=
requireContext
=>
requireContext
.
keys
().
map
(
requireContext
)
requireAll
(
req
)
front-end/mall4cloud-multishop-master/src/icons/svg/analysis.svg
0 → 100644
View file @
a21f5a9a
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg
version=
"1.0"
xmlns=
"http://www.w3.org/2000/svg"
width=
"14.000000pt"
height=
"14.000000pt"
viewBox=
"0 0 14.000000 14.000000"
preserveAspectRatio=
"xMidYMid meet"
>
<g
transform=
"translate(0.000000,14.000000) scale(0.100000,-0.100000)"
fill=
"#000000"
stroke=
"none"
>
<path
d=
"M60 100 l0 -40 40 0 c32 0 40 4 39 18 0 10 -3 12 -6 5 -2 -7 -18 -13
-34 -13 -25 0 -29 4 -29 29 0 16 6 32 13 34 7 3 5 6 -5 6 -14 1 -18 -7 -18
-39z"
/>
<path
d=
"M19 113 c-13 -16 -12 -17 4 -4 9 7 17 15 17 17 0 8 -8 3 -21 -13z"
/>
<path
d=
"M100 126 c0 -2 8 -10 18 -17 15 -13 16 -12 3 4 -13 16 -21 21 -21 13z"
/>
<path
d=
"M2 70 c0 -14 2 -19 5 -12 2 6 2 18 0 25 -3 6 -5 1 -5 -13z"
/>
<path
d=
"M10 36 c0 -2 8 -10 18 -17 15 -13 16 -12 3 4 -13 16 -21 21 -21 13z"
/>
<path
d=
"M109 23 c-13 -16 -12 -17 4 -4 16 13 21 21 13 21 -2 0 -10 -8 -17
-17z"
/>
<path
d=
"M58 3 c6 -2 18 -2 25 0 6 3 1 5 -13 5 -14 0 -19 -2 -12 -5z"
/>
</g>
</svg>
front-end/mall4cloud-multishop-master/src/icons/svg/dashboard.svg
0 → 100644
View file @
a21f5a9a
<svg
width=
"128"
height=
"100"
xmlns=
"http://www.w3.org/2000/svg"
><path
d=
"M27.429 63.638c0-2.508-.893-4.65-2.679-6.424-1.786-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.465 2.662-1.785 1.774-2.678 3.916-2.678 6.424 0 2.508.893 4.65 2.678 6.424 1.786 1.775 3.94 2.662 6.465 2.662 2.524 0 4.678-.887 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zm13.714-31.801c0-2.508-.893-4.65-2.679-6.424-1.785-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zM71.714 65.98l7.215-27.116c.285-1.23.107-2.378-.536-3.443-.643-1.064-1.56-1.762-2.75-2.094-1.19-.33-2.333-.177-3.429.462-1.095.639-1.81 1.573-2.143 2.804l-7.214 27.116c-2.857.237-5.405 1.266-7.643 3.088-2.238 1.822-3.738 4.152-4.5 6.992-.952 3.644-.476 7.098 1.429 10.364 1.905 3.265 4.69 5.37 8.357 6.317 3.667.947 7.143.474 10.429-1.42 3.285-1.892 5.404-4.66 6.357-8.305.762-2.84.619-5.607-.429-8.305-1.047-2.697-2.762-4.85-5.143-6.46zm47.143-2.342c0-2.508-.893-4.65-2.678-6.424-1.786-1.775-3.94-2.662-6.465-2.662-2.524 0-4.678.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.786 1.775 3.94 2.662 6.464 2.662 2.524 0 4.679-.887 6.465-2.662 1.785-1.775 2.678-3.916 2.678-6.424zm-45.714-45.43c0-2.509-.893-4.65-2.679-6.425C68.68 10.01 66.524 9.122 64 9.122c-2.524 0-4.679.887-6.464 2.661-1.786 1.775-2.679 3.916-2.679 6.425 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zm32 13.629c0-2.508-.893-4.65-2.679-6.424-1.785-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zM128 63.638c0 12.351-3.357 23.78-10.071 34.286-.905 1.372-2.19 2.058-3.858 2.058H13.93c-1.667 0-2.953-.686-3.858-2.058C3.357 87.465 0 76.037 0 63.638c0-8.613 1.69-16.847 5.071-24.703C8.452 31.08 13 24.312 18.714 18.634c5.715-5.68 12.524-10.199 20.429-13.559C47.048 1.715 55.333.035 64 .035c8.667 0 16.952 1.68 24.857 5.04 7.905 3.36 14.714 7.88 20.429 13.559 5.714 5.678 10.262 12.446 13.643 20.301 3.38 7.856 5.071 16.09 5.071 24.703z"
/></svg>
\ No newline at end of file
front-end/mall4cloud-multishop-master/src/icons/svg/distribution.svg
0 → 100644
View file @
a21f5a9a
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg
version=
"1.0"
xmlns=
"http://www.w3.org/2000/svg"
width=
"14.000000pt"
height=
"14.000000pt"
viewBox=
"0 0 14.000000 14.000000"
preserveAspectRatio=
"xMidYMid meet"
>
<g
transform=
"translate(0.000000,14.000000) scale(0.100000,-0.100000)"
fill=
"#000000"
stroke=
"none"
>
<path
d=
"M75 133 c54 -8 52 -23 -4 -23 -38 0 -51 3 -46 13 4 6 -1 3 -9 -7 -9
-11 -16 -25 -15 -30 0 -6 3 -5 6 2 3 8 26 12 64 12 l59 0 0 -45 0 -45 -59 0
c-33 0 -62 5 -64 10 -3 6 -4 5 -3 -2 2 -9 23 -13 67 -13 l64 0 3 43 c4 60 -18
92 -61 91 l-32 -2 30 -4z"
/>
<path
d=
"M13 63 c9 -2 25 -2 35 0 9 3 1 5 -18 5 -19 0 -27 -2 -17 -5z"
/>
<path
d=
"M7 43 c7 -2 19 -2 26 0 6 3 1 5 -13 5 -14 0 -19 -2 -13 -5z"
/>
</g>
</svg>
front-end/mall4cloud-multishop-master/src/icons/svg/example.svg
0 → 100644
View file @
a21f5a9a
<svg
width=
"128"
height=
"128"
xmlns=
"http://www.w3.org/2000/svg"
><path
d=
"M96.258 57.462h31.421C124.794 27.323 100.426 2.956 70.287.07v31.422a32.856 32.856 0 0 1 25.971 25.97zm-38.796-25.97V.07C27.323 2.956 2.956 27.323.07 57.462h31.422a32.856 32.856 0 0 1 25.97-25.97zm12.825 64.766v31.421c30.46-2.885 54.507-27.253 57.713-57.712H96.579c-2.886 13.466-13.146 23.726-26.292 26.291zM31.492 70.287H.07c2.886 30.46 27.253 54.507 57.713 57.713V96.579c-13.466-2.886-23.726-13.146-26.291-26.292z"
/></svg>
\ No newline at end of file
front-end/mall4cloud-multishop-master/src/icons/svg/eye-open.svg
0 → 100644
View file @
a21f5a9a
<svg
class=
"icon"
viewBox=
"0 0 1024 1024"
xmlns=
"http://www.w3.org/2000/svg"
width=
"128"
height=
"128"
><defs><style/></defs><path
d=
"M512 128q69.675 0 135.51 21.163t115.498 54.997 93.483 74.837 73.685 82.006 51.67 74.837 32.17 54.827L1024 512q-2.347 4.992-6.315 13.483T998.87 560.17t-31.658 51.669-44.331 59.99-56.832 64.34-69.504 60.16-82.347 51.5-94.848 34.687T512 896q-69.675 0-135.51-21.163t-115.498-54.826-93.483-74.326-73.685-81.493-51.67-74.496-32.17-54.997L0 513.707q2.347-4.992 6.315-13.483t18.816-34.816 31.658-51.84 44.331-60.33 56.832-64.683 69.504-60.331 82.347-51.84 94.848-34.816T512 128.085zm0 85.333q-46.677 0-91.648 12.331t-81.152 31.83-70.656 47.146-59.648 54.485-48.853 57.686-37.675 52.821-26.325 43.99q12.33 21.674 26.325 43.52t37.675 52.351 48.853 57.003 59.648 53.845T339.2 767.02t81.152 31.488T512 810.667t91.648-12.331 81.152-31.659 70.656-46.848 59.648-54.186 48.853-57.344 37.675-52.651T927.957 512q-12.33-21.675-26.325-43.648t-37.675-52.65-48.853-57.345-59.648-54.186-70.656-46.848-81.152-31.659T512 213.334zm0 128q70.656 0 120.661 50.006T682.667 512 632.66 632.661 512 682.667 391.339 632.66 341.333 512t50.006-120.661T512 341.333zm0 85.334q-35.328 0-60.33 25.002T426.666 512t25.002 60.33T512 597.334t60.33-25.002T597.334 512t-25.002-60.33T512 426.666z"
/></svg>
\ No newline at end of file
front-end/mall4cloud-multishop-master/src/icons/svg/eye.svg
0 → 100644
View file @
a21f5a9a
<svg
width=
"128"
height=
"64"
xmlns=
"http://www.w3.org/2000/svg"
><path
d=
"M127.072 7.994c1.37-2.208.914-5.152-.914-6.87-2.056-1.717-4.797-1.226-6.396.982-.229.245-25.586 32.382-55.74 32.382-29.24 0-55.74-32.382-55.968-32.627-1.6-1.963-4.57-2.208-6.397-.49C-.17 3.086-.399 6.275 1.2 8.238c.457.736 5.94 7.36 14.62 14.72L4.17 35.96c-1.828 1.963-1.6 5.152.228 6.87.457.98 1.6 1.471 2.742 1.471s2.284-.49 3.198-1.472l12.564-13.983c5.94 4.416 13.021 8.587 20.788 11.53l-4.797 17.418c-.685 2.699.686 5.397 3.198 6.133h1.37c2.057 0 3.884-1.472 4.341-3.68L52.6 42.83c3.655.736 7.538 1.227 11.422 1.227 3.883 0 7.767-.49 11.422-1.227l4.797 17.173c.457 2.208 2.513 3.68 4.34 3.68.457 0 .914 0 1.143-.246 2.513-.736 3.883-3.434 3.198-6.133l-4.797-17.172c7.767-2.944 14.848-7.114 20.788-11.53l12.336 13.738c.913.981 2.056 1.472 3.198 1.472s2.284-.49 3.198-1.472c1.828-1.963 1.828-4.906.228-6.87l-11.65-13.001c9.366-7.36 14.849-14.474 14.849-14.474z"
/></svg>
\ No newline at end of file
Prev
1
…
8
9
10
11
12
13
14
15
16
…
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