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
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
2083 additions
and
0 deletions
+2083
-0
front-end/mall4cloud-multishop-master/src/utils/request.js
front-end/mall4cloud-multishop-master/src/utils/request.js
+111
-0
front-end/mall4cloud-multishop-master/src/utils/scroll-to.js
front-end/mall4cloud-multishop-master/src/utils/scroll-to.js
+58
-0
front-end/mall4cloud-multishop-master/src/utils/validate.js
front-end/mall4cloud-multishop-master/src/utils/validate.js
+136
-0
front-end/mall4cloud-multishop-master/src/views/common/error-page/401.vue
...loud-multishop-master/src/views/common/error-page/401.vue
+99
-0
front-end/mall4cloud-multishop-master/src/views/common/error-page/404.vue
...loud-multishop-master/src/views/common/error-page/404.vue
+228
-0
front-end/mall4cloud-multishop-master/src/views/common/login/index.vue
...l4cloud-multishop-master/src/views/common/login/index.vue
+302
-0
front-end/mall4cloud-multishop-master/src/views/common/redirect/index.vue
...loud-multishop-master/src/views/common/redirect/index.vue
+11
-0
front-end/mall4cloud-multishop-master/src/views/multishop/hot-search/add-or-update.vue
...p-master/src/views/multishop/hot-search/add-or-update.vue
+100
-0
front-end/mall4cloud-multishop-master/src/views/multishop/hot-search/index.vue
...multishop-master/src/views/multishop/hot-search/index.vue
+191
-0
front-end/mall4cloud-multishop-master/src/views/multishop/index-img/add-or-update.vue
...op-master/src/views/multishop/index-img/add-or-update.vue
+237
-0
front-end/mall4cloud-multishop-master/src/views/multishop/index-img/index.vue
...-multishop-master/src/views/multishop/index-img/index.vue
+155
-0
front-end/mall4cloud-multishop-master/src/views/multishop/notice/add-or-update.vue
...ishop-master/src/views/multishop/notice/add-or-update.vue
+111
-0
front-end/mall4cloud-multishop-master/src/views/multishop/notice/index.vue
...oud-multishop-master/src/views/multishop/notice/index.vue
+128
-0
front-end/mall4cloud-multishop-master/src/views/multishop/shop-user/account-add-or-update.vue
...r/src/views/multishop/shop-user/account-add-or-update.vue
+99
-0
front-end/mall4cloud-multishop-master/src/views/multishop/shop-user/add-or-update.vue
...op-master/src/views/multishop/shop-user/add-or-update.vue
+117
-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/utils/request.js
0 → 100644
View file @
a21f5a9a
import
axios
from
'
axios
'
import
{
MessageBox
,
Message
}
from
'
element-ui
'
import
store
from
'
@/store
'
import
{
getToken
}
from
'
@/utils/auth
'
// create an axios instance
const
service
=
axios
.
create
({
baseURL
:
process
.
env
.
VUE_APP_BASE_API
,
// url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests
timeout
:
50000
// request timeout
})
// request interceptor
service
.
interceptors
.
request
.
use
(
config
=>
{
// do something before request is sent
if
(
store
.
getters
.
token
)
{
// let each request carry token
// ['Authorization'] is a custom headers key
// please modify it according to the actual situation
config
.
headers
[
'
Authorization
'
]
=
getToken
()
}
return
config
},
error
=>
{
// do something with request error
console
.
log
(
error
)
// for debug
return
Promise
.
reject
(
error
)
}
)
// response interceptor
service
.
interceptors
.
response
.
use
(
/**
* If you want to get http information such as headers or status
* Please return response => response
*/
/**
* Determine the request status by custom code
* Here is just an example
* You can also judge the status by HTTP Status Code
*/
response
=>
{
const
res
=
response
.
data
// if the custom code is not 00000, it is judged as an error.
if
(
res
.
code
===
'
00000
'
)
{
return
res
.
data
}
// A00001 用于直接显示提示用户的错误,内容由输入内容决定
// A00003 无法读取获取请求参数
if
(
res
.
code
===
'
A00001
'
||
res
.
code
===
'
A00003
'
||
res
.
code
===
'
A00005
'
)
{
Message
({
message
:
res
.
msg
||
'
Error
'
,
type
:
'
error
'
,
duration
:
1.5
*
1000
})
return
Promise
.
reject
(
res
)
}
// A00002 方法参数没有校验,内容由输入内容决定
if
(
res
.
code
===
'
A00002
'
)
{
if
(
res
.
data
&&
res
.
data
.
length
)
{
res
.
data
.
forEach
(
errorMsg
=>
{
Message
({
message
:
errorMsg
||
'
Error
'
,
type
:
'
error
'
,
duration
:
1.5
*
1000
})
})
}
else
{
Message
({
message
:
res
.
msg
||
'
Error
'
,
type
:
'
error
'
,
duration
:
1.5
*
1000
})
}
return
Promise
.
reject
()
}
// A00004 未授权
if
(
res
.
code
===
'
A00004
'
)
{
// to re-login
MessageBox
.
confirm
(
'
您已注销,您可以取消停留在该页上,或重新登录
'
,
'
确认注销
'
,
{
confirmButtonText
:
'
重新登陆
'
,
cancelButtonText
:
'
取消
'
,
type
:
'
warning
'
}).
then
(()
=>
{
store
.
dispatch
(
'
user/resetToken
'
).
then
(()
=>
{
location
.
reload
()
})
})
return
Promise
.
reject
()
}
return
Promise
.
reject
(
res
)
},
error
=>
{
console
.
log
(
'
err
'
+
error
)
// for debug
Message
({
message
:
error
.
message
,
type
:
'
error
'
,
duration
:
1.5
*
1000
})
return
Promise
.
reject
(
error
)
}
)
export
default
service
front-end/mall4cloud-multishop-master/src/utils/scroll-to.js
0 → 100644
View file @
a21f5a9a
Math
.
easeInOutQuad
=
function
(
t
,
b
,
c
,
d
)
{
t
/=
d
/
2
if
(
t
<
1
)
{
return
c
/
2
*
t
*
t
+
b
}
t
--
return
-
c
/
2
*
(
t
*
(
t
-
2
)
-
1
)
+
b
}
// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
var
requestAnimFrame
=
(
function
()
{
return
window
.
requestAnimationFrame
||
window
.
webkitRequestAnimationFrame
||
window
.
mozRequestAnimationFrame
||
function
(
callback
)
{
window
.
setTimeout
(
callback
,
1000
/
60
)
}
})()
/**
* Because it's so fucking difficult to detect the scrolling element, just move them all
* @param {number} amount
*/
function
move
(
amount
)
{
document
.
documentElement
.
scrollTop
=
amount
document
.
body
.
parentNode
.
scrollTop
=
amount
document
.
body
.
scrollTop
=
amount
}
function
position
()
{
return
document
.
documentElement
.
scrollTop
||
document
.
body
.
parentNode
.
scrollTop
||
document
.
body
.
scrollTop
}
/**
* @param {number} to
* @param {number} duration
* @param {Function} callback
*/
export
function
scrollTo
(
to
,
duration
,
callback
)
{
const
start
=
position
()
const
change
=
to
-
start
const
increment
=
20
let
currentTime
=
0
duration
=
(
typeof
(
duration
)
===
'
undefined
'
)
?
500
:
duration
var
animateScroll
=
function
()
{
// increment the time
currentTime
+=
increment
// find the value with the quadratic in-out easing function
var
val
=
Math
.
easeInOutQuad
(
currentTime
,
start
,
change
,
duration
)
// move the document.body
move
(
val
)
// do the animation unless its over
if
(
currentTime
<
duration
)
{
requestAnimFrame
(
animateScroll
)
}
else
{
if
(
callback
&&
typeof
(
callback
)
===
'
function
'
)
{
// the animation is done so lets callback
callback
()
}
}
}
animateScroll
()
}
front-end/mall4cloud-multishop-master/src/utils/validate.js
0 → 100644
View file @
a21f5a9a
/**
* Created by PanJiaChen on 16/11/18.
*/
/**
* 以1开头,后面跟10位数
*/
export
const
MOBILE_REGEXP
=
/1
[
0-9
]{10}
/
/**
* 1. 用户名不能为纯数字
* 2. 由数字字母下划线 4-16位组成
*/
export
const
USER_NAME_REGEXP
=
/
(?!\d
+$
)([
a-zA-Z0-9_
]{4,16})
/
/**
* 邮箱正则
*/
export
const
EMAIL_REGEXP
=
/
[\w
!#$%&'*+
/
=?^_`{|}~-
]
+
(?:\.[\w
!#$%&'*+
/
=?^_`{|}~-
]
+
)
*@
(?:[\w](?:[\w
-
]
*
[\w])?\.)
+
[\w](?:[\w
-
]
*
[\w])?
/
/**
* @param {string} path
* @returns {Boolean}
*/
export
function
isExternal
(
path
)
{
return
/^
(
https
?
:|mailto:|tel:
)
/
.
test
(
path
)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export
function
validUsername
(
str
)
{
return
isEmail
(
str
)
||
isMobile
(
str
)
||
isUserName
(
str
)
}
/**
* 是否是手机号
* @param value 输入值
* @return 匹配结果
*/
export
function
isMobile
(
value
)
{
return
isMatching
(
MOBILE_REGEXP
,
value
)
}
/**
* 是否是用户名
* @param value 输入值
* @return 匹配结果
*/
export
function
isUserName
(
value
)
{
return
isMatching
(
USER_NAME_REGEXP
,
value
)
}
/**
* 是否是邮箱
* @param value 输入值
* @return 匹配结果
*/
export
function
isEmail
(
value
)
{
return
isMatching
(
EMAIL_REGEXP
,
value
)
}
export
function
isMatching
(
regexp
,
value
)
{
if
(
!
value
)
{
return
false
}
return
regexp
.
test
(
value
)
}
/**
* @param {string} url
* @returns {Boolean}
*/
export
function
validURL
(
url
)
{
const
reg
=
/^
(
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
reg
.
test
(
url
)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export
function
validLowerCase
(
str
)
{
const
reg
=
/^
[
a-z
]
+$/
return
reg
.
test
(
str
)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export
function
validUpperCase
(
str
)
{
const
reg
=
/^
[
A-Z
]
+$/
return
reg
.
test
(
str
)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export
function
validAlphabets
(
str
)
{
const
reg
=
/^
[
A-Za-z
]
+$/
return
reg
.
test
(
str
)
}
/**
* @param {string} email
* @returns {Boolean}
*/
export
function
validEmail
(
email
)
{
const
reg
=
/^
(([^
<>()
\[\]\\
.,;:
\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
reg
.
test
(
email
)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export
function
isString
(
str
)
{
if
(
typeof
str
===
'
string
'
||
str
instanceof
String
)
{
return
true
}
return
false
}
/**
* @param {Array} arg
* @returns {Boolean}
*/
export
function
isArray
(
arg
)
{
if
(
typeof
Array
.
isArray
===
'
undefined
'
)
{
return
Object
.
prototype
.
toString
.
call
(
arg
)
===
'
[object Array]
'
}
return
Array
.
isArray
(
arg
)
}
front-end/mall4cloud-multishop-master/src/views/common/error-page/401.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<div
class=
"errPage-container"
>
<el-button
icon=
"el-icon-arrow-left"
class=
"pan-back-btn"
@
click=
"back"
>
返回
</el-button>
<el-row>
<el-col
:span=
"12"
>
<h1
class=
"text-jumbo text-ginormous"
>
Oops!
</h1>
gif来源
<a
href=
"https://zh.airbnb.com/"
target=
"_blank"
>
airbnb
</a>
页面
<h2>
你没有权限去该页面
</h2>
<h6>
如有不满请联系你领导
</h6>
<ul
class=
"list-unstyled"
>
<li>
或者你可以去:
</li>
<li
class=
"link-type"
>
<router-link
to=
"/order/order"
>
回首页
</router-link>
</li>
<li
class=
"link-type"
>
<a
href=
"https://www.taobao.com/"
>
随便看看
</a>
</li>
<li><a
href=
"#"
@
click.prevent=
"dialogVisible=true"
>
点我看图
</a></li>
</ul>
</el-col>
<el-col
:span=
"12"
>
<img
:src=
"errGif"
width=
"313"
height=
"428"
alt=
"Girl has dropped her ice cream."
>
</el-col>
</el-row>
<el-dialog
:visible.sync=
"dialogVisible"
title=
"随便看"
>
<img
:src=
"ewizardClap"
class=
"pan-img"
>
</el-dialog>
</div>
</
template
>
<
script
>
import
errGif
from
'
@/assets/401_images/401.gif
'
export
default
{
name
:
'
Page401
'
,
data
()
{
return
{
errGif
:
errGif
+
'
?
'
+
+
new
Date
(),
ewizardClap
:
'
https://wpimg.wallstcn.com/007ef517-bafd-4066-aae4-6883632d9646
'
,
dialogVisible
:
false
}
},
methods
:
{
back
()
{
if
(
this
.
$route
.
query
.
noGoBack
)
{
this
.
$router
.
push
({
path
:
'
/order/order
'
})
}
else
{
this
.
$router
.
go
(
-
1
)
}
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.errPage-container
{
width
:
800px
;
max-width
:
100%
;
margin
:
100px
auto
;
.pan-back-btn
{
background
:
#008489
;
color
:
#fff
;
border
:
none
!
important
;
}
.pan-gif
{
margin
:
0
auto
;
display
:
block
;
}
.pan-img
{
display
:
block
;
margin
:
0
auto
;
width
:
100%
;
}
.text-jumbo
{
font-size
:
60px
;
font-weight
:
700
;
color
:
#484848
;
}
.list-unstyled
{
font-size
:
14px
;
li
{
padding-bottom
:
5px
;
}
a
{
color
:
#008489
;
text-decoration
:
none
;
&
:hover
{
text-decoration
:
underline
;
}
}
}
}
</
style
>
front-end/mall4cloud-multishop-master/src/views/common/error-page/404.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<div
class=
"wscn-http404-container"
>
<div
class=
"wscn-http404"
>
<div
class=
"pic-404"
>
<img
class=
"pic-404__parent"
src=
"@/assets/404_images/404.png"
alt=
"404"
>
<img
class=
"pic-404__child left"
src=
"@/assets/404_images/404_cloud.png"
alt=
"404"
>
<img
class=
"pic-404__child mid"
src=
"@/assets/404_images/404_cloud.png"
alt=
"404"
>
<img
class=
"pic-404__child right"
src=
"@/assets/404_images/404_cloud.png"
alt=
"404"
>
</div>
<div
class=
"bullshit"
>
<div
class=
"bullshit__oops"
>
OOPS!
</div>
<div
class=
"bullshit__info"
>
All rights reserved
<a
style=
"color:#20a0ff"
href=
"https://wallstreetcn.com"
target=
"_blank"
>
wallstreetcn
</a>
</div>
<div
class=
"bullshit__headline"
>
{{
message
}}
</div>
<div
class=
"bullshit__info"
>
Please check that the URL you entered is correct, or click the button below to return to the homepage.
</div>
<a
href=
""
class=
"bullshit__return-home"
>
Back to home
</a>
</div>
</div>
</div>
</
template
>
<
script
>
export
default
{
name
:
'
Page404
'
,
computed
:
{
message
()
{
return
'
The webmaster said that you can not enter this page...
'
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.wscn-http404-container
{
transform
:
translate
(
-50%
,-
50%
);
position
:
absolute
;
top
:
40%
;
left
:
50%
;
}
.wscn-http404
{
position
:
relative
;
width
:
1200px
;
padding
:
0
50px
;
overflow
:
hidden
;
.pic-404
{
position
:
relative
;
float
:
left
;
width
:
600px
;
overflow
:
hidden
;
&
__parent
{
width
:
100%
;
}
&
__child
{
position
:
absolute
;
&
.left
{
width
:
80px
;
top
:
17px
;
left
:
220px
;
opacity
:
0
;
animation-name
:
cloudLeft
;
animation-duration
:
2s
;
animation-timing-function
:
linear
;
animation-fill-mode
:
forwards
;
animation-delay
:
1s
;
}
&
.mid
{
width
:
46px
;
top
:
10px
;
left
:
420px
;
opacity
:
0
;
animation-name
:
cloudMid
;
animation-duration
:
2s
;
animation-timing-function
:
linear
;
animation-fill-mode
:
forwards
;
animation-delay
:
1
.2s
;
}
&
.right
{
width
:
62px
;
top
:
100px
;
left
:
500px
;
opacity
:
0
;
animation-name
:
cloudRight
;
animation-duration
:
2s
;
animation-timing-function
:
linear
;
animation-fill-mode
:
forwards
;
animation-delay
:
1s
;
}
@keyframes
cloudLeft
{
0
%
{
top
:
17px
;
left
:
220px
;
opacity
:
0
;
}
20
%
{
top
:
33px
;
left
:
188px
;
opacity
:
1
;
}
80
%
{
top
:
81px
;
left
:
92px
;
opacity
:
1
;
}
100
%
{
top
:
97px
;
left
:
60px
;
opacity
:
0
;
}
}
@keyframes
cloudMid
{
0
%
{
top
:
10px
;
left
:
420px
;
opacity
:
0
;
}
20
%
{
top
:
40px
;
left
:
360px
;
opacity
:
1
;
}
70
%
{
top
:
130px
;
left
:
180px
;
opacity
:
1
;
}
100
%
{
top
:
160px
;
left
:
120px
;
opacity
:
0
;
}
}
@keyframes
cloudRight
{
0
%
{
top
:
100px
;
left
:
500px
;
opacity
:
0
;
}
20
%
{
top
:
120px
;
left
:
460px
;
opacity
:
1
;
}
80
%
{
top
:
180px
;
left
:
340px
;
opacity
:
1
;
}
100
%
{
top
:
200px
;
left
:
300px
;
opacity
:
0
;
}
}
}
}
.bullshit
{
position
:
relative
;
float
:
left
;
width
:
300px
;
padding
:
30px
0
;
overflow
:
hidden
;
&
__oops
{
font-size
:
32px
;
font-weight
:
bold
;
line-height
:
40px
;
color
:
#1482f0
;
opacity
:
0
;
margin-bottom
:
20px
;
animation-name
:
slideUp
;
animation-duration
:
0
.5s
;
animation-fill-mode
:
forwards
;
}
&
__headline
{
font-size
:
20px
;
line-height
:
24px
;
color
:
#222
;
font-weight
:
bold
;
opacity
:
0
;
margin-bottom
:
10px
;
animation-name
:
slideUp
;
animation-duration
:
0
.5s
;
animation-delay
:
0
.1s
;
animation-fill-mode
:
forwards
;
}
&
__info
{
font-size
:
13px
;
line-height
:
21px
;
color
:
grey
;
opacity
:
0
;
margin-bottom
:
30px
;
animation-name
:
slideUp
;
animation-duration
:
0
.5s
;
animation-delay
:
0
.2s
;
animation-fill-mode
:
forwards
;
}
&
__return-home
{
display
:
block
;
float
:
left
;
width
:
110px
;
height
:
36px
;
background
:
#1482f0
;
border-radius
:
100px
;
text-align
:
center
;
color
:
#ffffff
;
opacity
:
0
;
font-size
:
14px
;
line-height
:
36px
;
cursor
:
pointer
;
animation-name
:
slideUp
;
animation-duration
:
0
.5s
;
animation-delay
:
0
.3s
;
animation-fill-mode
:
forwards
;
}
@keyframes
slideUp
{
0
%
{
transform
:
translateY
(
60px
);
opacity
:
0
;
}
100
%
{
transform
:
translateY
(
0
);
opacity
:
1
;
}
}
}
}
</
style
>
front-end/mall4cloud-multishop-master/src/views/common/login/index.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<div
class=
"login-container"
>
<div
class=
"login-frame"
>
<div
class=
"login-img"
>
<img
src=
"~@/assets/images/login-img.jpg"
>
</div>
<div
class=
"login-info"
>
<div
class=
"title"
>
蓝海商家端管理系统
</div>
<div
class=
"input-box"
>
<div
class=
"number inp-item"
:class=
"[selectItem==='username'? 'selected' : '', usernameErrTips? 'err-line' : '']"
>
<img
src=
"~@/assets/images/number.png"
>
<input
v-model=
"loginInfo.username"
type=
"text"
:placeholder=
"$t('login.username')"
@
focus=
"inputFocus('username')"
@
blur=
"inputDefocus('username')"
>
<div
v-if=
"usernameErrTips"
class=
"err-tips"
>
请输入正确的用户名
</div>
</div>
<div
class=
"password inp-item"
:class=
"[selectItem==='password'? 'selected' : '', passwordErrTips? 'err-line' : '']"
>
<img
src=
"~@/assets/images/password.png"
>
<input
v-model=
"loginInfo.password"
type=
"password"
:placeholder=
"$t('login.password')"
@
keyup.enter=
"handleLogin"
@
focus=
"inputFocus('password')"
@
blur=
"inputDefocus('password')"
>
<div
v-if=
"passwordErrTips"
class=
"err-tips"
>
密码不能少于6位
</div>
</div>
</div>
<div
class=
"login-btn"
:loading=
"loading"
@
click=
"handleLogin"
>
登录
</div>
</div>
<div
class=
"switch-language"
>
<el-dropdown
@
command=
"handleSetLanguage"
>
<span
class=
"el-dropdown-link"
>
语言
<i
class=
"el-icon-caret-bottom el-icon--right"
/>
</span>
<el-dropdown-menu
slot=
"dropdown"
>
<el-dropdown-item
:disabled=
"language==='zh'"
command=
"zh"
>
中文
</el-dropdown-item>
<el-dropdown-item
:disabled=
"language==='en'"
command=
"en"
>
English
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
<div
class=
"bottom"
>
Copyright 2018-2021 广州市蓝海创新科技有限公司
</div>
<Verify
v-if=
"initVerify"
ref=
"verify"
:captcha-type=
"'blockPuzzle'"
:img-size=
"
{width:'400px',height:'200px'}"
@success="login"
/>
</div>
</
template
>
<
script
>
import
{
validUsername
}
from
'
@/utils/validate
'
import
Verify
from
'
@/components/Verifition/Verify
'
export
default
{
name
:
'
Login
'
,
components
:
{
Verify
},
data
()
{
return
{
selectItem
:
''
,
// '':未选中;'username':用户名;'password':密码
usernameErrTips
:
false
,
passwordErrTips
:
false
,
loginInfo
:
{
username
:
''
,
// 用户名
password
:
''
,
// 密码
captcha
:
''
// 验证码
},
loading
:
false
,
initVerify
:
false
,
redirect
:
undefined
,
otherQuery
:
{}
}
},
computed
:
{
language
()
{
return
this
.
$store
.
getters
.
language
}
},
watch
:
{
$route
:
{
handler
:
function
(
route
)
{
const
query
=
route
.
query
if
(
query
)
{
this
.
redirect
=
query
.
redirect
this
.
otherQuery
=
this
.
getOtherQuery
(
query
)
}
},
immediate
:
true
}
},
methods
:
{
// 切换语言
handleSetLanguage
(
lang
)
{
this
.
$i18n
.
locale
=
lang
this
.
$store
.
dispatch
(
'
app/setLanguage
'
,
lang
)
this
.
$message
({
message
:
'
Switch Language Success
'
,
type
:
'
success
'
})
},
// 输入框聚焦监听
inputFocus
(
item
)
{
this
.
lightOutline
(
item
)
if
(
item
===
'
username
'
)
{
this
.
usernameErrTips
=
false
}
else
if
(
item
===
'
password
'
)
{
this
.
passwordErrTips
=
false
}
},
// 输入框失焦监听
inputDefocus
(
item
)
{
this
.
lightDisappear
()
this
.
judgeMonitorInput
(
item
)
},
// 底边框换颜色
lightOutline
(
item
)
{
this
.
selectItem
=
item
},
// 底边框恢复成灰色
lightDisappear
()
{
this
.
selectItem
=
''
},
// 判断监听的是哪个输入框
judgeMonitorInput
(
item
)
{
// if (item === 'username') {
// this.userNameVerification()
// } else if (item === 'password') {
// this.passwordVerification()
// }
},
// 用户名输入框验证
userNameVerification
()
{
const
username
=
this
.
loginInfo
.
username
if
(
!
validUsername
(
username
))
{
this
.
usernameErrTips
=
true
}
else
{
this
.
usernameErrTips
=
false
}
},
// 密码输入框验证
passwordVerification
()
{
const
password
=
this
.
loginInfo
.
password
if
(
password
.
length
<
6
)
{
this
.
passwordErrTips
=
true
}
else
{
this
.
passwordErrTips
=
false
}
},
handleLogin
()
{
// 验证用户名和密码是否符合规则
// this.userNameVerification()
// this.passwordVerification()
if
(
this
.
usernameErrTips
===
true
)
{
return
}
if
(
this
.
passwordErrTips
===
true
)
{
return
}
this
.
initVerify
=
true
this
.
$nextTick
(()
=>
{
this
.
$refs
.
verify
.
show
()
})
},
login
(
verifyResult
)
{
console
.
log
(
verifyResult
.
captchaVerification
)
this
.
loading
=
true
this
.
loginInfo
.
captcha
=
verifyResult
.
captchaVerification
this
.
$store
.
dispatch
(
'
user/login
'
,
this
.
loginInfo
)
.
then
(()
=>
{
this
.
$router
.
push
({
path
:
this
.
redirect
||
'
/
'
,
query
:
this
.
otherQuery
})
this
.
loading
=
false
})
.
catch
((
e
)
=>
{
console
.
log
(
e
)
this
.
loading
=
false
})
},
getOtherQuery
(
query
)
{
return
Object
.
keys
(
query
).
reduce
((
acc
,
cur
)
=>
{
if
(
cur
!==
'
redirect
'
)
{
acc
[
cur
]
=
query
[
cur
]
}
return
acc
},
{})
}
}
}
</
script
>
<
style
lang=
"scss"
>
.login-container
{
position
:
relative
;
width
:
100%
;
height
:
100vh
;
background
:
url(~@/assets/images/login-bg.jpg)
no-repeat
;
background-size
:
cover
;
.login-frame
{
position
:
fixed
;
top
:
0
;
bottom
:
0
;
left
:
0
;
right
:
0
;
display
:
flex
;
align-items
:
center
;
width
:
1200px
;
height
:
678px
;
background
:
#fff
;
box-shadow
:
0px
0px
80px
0px
rgba
(
0
,
0
,
0
,
0
.1
);
margin
:
auto
;
.login-img
{
margin-left
:
80px
;
}
.login-info
{
margin-left
:
80px
;
.title
{
font-size
:
30px
;
font-weight
:
400
;
color
:
#000000
;
}
.input-box
{
margin-top
:
75px
;
.inp-item
{
position
:
relative
;
display
:
flex
;
align-items
:
center
;
width
:
330px
;
height
:
40px
;
padding-bottom
:
8px
;
border-bottom
:
1px
solid
#eee
;
img
{
width
:
20px
;
height
:
20px
;
}
input
{
border
:
none
;
outline
:
none
;
width
:
100%
;
height
:
100%
;
padding
:
0
12px
;
}
.err-tips
{
position
:
absolute
;
bottom
:
-22px
;
font-size
:
14px
;
color
:
#d40000
;
}
}
.password
{
margin-top
:
35px
;
}
.selected
{
border-bottom
:
1px
solid
#007de4
;
}
.err-line
{
border-bottom
:
1px
solid
#d40000
;
}
}
.login-btn
{
width
:
334px
;
height
:
48px
;
line-height
:
48px
;
font-size
:
18px
;
font-weight
:
400
;
color
:
#FFFFFF
;
background
:
#007DE4
;
border-radius
:
24px
;
text-align
:
center
;
margin-top
:
80px
;
cursor
:
pointer
;
}
}
.switch-language
{
position
:
absolute
;
top
:
20px
;
right
:
20px
;
padding
:
0
8px
;
border
:
1px
solid
#0076FE
;
.el-dropdown-link
{
font-size
:
12px
;
color
:
#0076FE
;
cursor
:
pointer
;
}
}
}
.bottom
{
position
:
absolute
;
width
:
100%
;
bottom
:
63px
;
font-size
:
12px
;
color
:
#AAA
;
text-align
:
center
;
}
}
</
style
>
front-end/mall4cloud-multishop-master/src/views/common/redirect/index.vue
0 → 100644
View file @
a21f5a9a
<
script
>
export
default
{
created
()
{
console
.
log
(
111
)
this
.
$router
.
replace
({
path
:
'
/order/order
'
})
},
render
:
function
(
h
)
{
return
h
()
// avoid warning message
}
}
</
script
>
front-end/mall4cloud-multishop-master/src/views/multishop/hot-search/add-or-update.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<el-dialog
:title=
"dataForm.hotSearchId? $t('table.edit'): $t('table.create')"
:visible.sync=
"visible"
>
<el-form
ref=
"dataForm"
:rules=
"rules"
:model=
"dataForm"
label-position=
"right"
label-width=
"80px"
>
<!-- 热搜标题 -->
<el-form-item
:label=
"$t('multishop.hotSearch.title')"
prop=
"title"
>
<el-input
v-model=
"dataForm.title"
/>
</el-form-item>
<!-- 内容 -->
<el-form-item
:label=
"$t('multishop.hotSearch.content')"
prop=
"content"
>
<el-input
v-model=
"dataForm.content"
/>
</el-form-item>
<!-- 顺序 -->
<el-form-item
:label=
"$t('multishop.hotSearch.seq')"
prop=
"seq"
>
<el-input-number
v-model=
"dataForm.seq"
controls-position=
"right"
:precision=
"0"
/>
</el-form-item>
<!-- 状态 0下线 1上线 -->
<el-form-item
:label=
"$t('multishop.hotSearch.status')"
prop=
"status"
>
<el-radio-group
v-model=
"dataForm.status"
>
<el-radio
:label=
"0"
>
{{
'
下线
'
}}
</el-radio>
<el-radio
:label=
"1"
>
{{
'
启用
'
}}
</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"visible = false"
>
{{
$t
(
'
table.cancel
'
)
}}
</el-button>
<el-button
type=
"primary"
@
click=
"dataFormSubmit()"
>
{{
$t
(
'
table.confirm
'
)
}}
</el-button>
</div>
</el-dialog>
</
template
>
<
script
>
import
*
as
api
from
'
@/api/multishop/hot-search
'
export
default
{
data
()
{
return
{
visible
:
false
,
dataForm
:
{
hotSearchId
:
0
,
content
:
null
,
seq
:
null
,
status
:
1
,
title
:
null
},
rules
:
{
title
:
[
{
required
:
true
,
message
:
'
标题不能为空
'
,
trigger
:
'
blur
'
}
],
content
:
[
{
required
:
true
,
message
:
'
内容不能为空
'
,
trigger
:
'
blur
'
}
]
}
}
},
methods
:
{
init
(
hotSearchId
)
{
this
.
dataForm
.
hotSearchId
=
hotSearchId
||
0
this
.
visible
=
true
this
.
$nextTick
(()
=>
{
this
.
$refs
[
'
dataForm
'
].
resetFields
()
if
(
!
this
.
dataForm
.
hotSearchId
)
{
return
}
api
.
get
(
hotSearchId
).
then
(
data
=>
{
this
.
dataForm
=
data
})
})
},
// 表单提交
dataFormSubmit
()
{
this
.
$refs
.
dataForm
.
validate
(
valid
=>
{
if
(
!
valid
)
{
return
}
const
request
=
this
.
dataForm
.
hotSearchId
?
api
.
update
(
this
.
dataForm
)
:
api
.
save
(
this
.
dataForm
)
request
.
then
(
data
=>
{
this
.
$message
({
message
:
this
.
$t
(
'
table.actionSuccess
'
),
type
:
'
success
'
,
duration
:
1500
,
onClose
:
()
=>
{
this
.
visible
=
false
this
.
$emit
(
'
refreshDataList
'
)
this
.
$refs
[
'
dataForm
'
].
resetFields
()
}
})
})
})
}
}
}
</
script
>
front-end/mall4cloud-multishop-master/src/views/multishop/hot-search/index.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<div
class=
"app-container mod-hot-search"
>
<!-- 搜索相关区域 -->
<div
class=
"filter-container"
>
<el-form
:inline=
"true"
:model=
"pageQuery"
class=
"demo-form-inline"
>
<el-form-item
label=
"热搜标题"
>
<el-input
v-model=
"pageQuery.title"
size=
"mini"
placeholder=
"热搜标题"
/>
</el-form-item>
<el-form-item
label=
"热搜内容"
>
<el-input
v-model=
"pageQuery.content"
size=
"mini"
placeholder=
"热搜内容"
/>
</el-form-item>
<el-form-item
label=
"启用状态"
>
<el-select
v-model=
"pageQuery.status"
size=
"mini"
placeholder=
"启用状态"
clearable
>
<el-option
label=
"启用"
value=
"1"
/>
<el-option
label=
"未启用"
value=
"0"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
size=
"mini"
icon=
"el-icon-search"
@
click=
"getSearchList()"
>
查询
</el-button>
<el-button
size=
"mini"
icon=
"el-icon-delete"
@
click=
"clearSearchInfo()"
>
清空
</el-button>
</el-form-item>
</el-form>
<el-button
v-permission=
"['multishop:hotSearch:save']"
size=
"mini"
icon=
"el-icon-plus"
type=
"primary"
class=
"filter-item"
@
click=
"addOrUpdateHandle()"
>
{{
$t
(
'
table.create
'
)
}}
</el-button>
</div>
<!-- 列表相关区域 -->
<el-table
v-loading=
"pageLoading"
:data=
"pageVO.list"
border
fit
highlight-current-row
style=
"width: 100%;"
>
<!-- 热搜标题 -->
<el-table-column
:label=
"$t('multishop.hotSearch.title')"
prop=
"title"
align=
"center"
>
<template
slot-scope=
"
{row}">
<span>
{{
row
.
title
}}
</span>
</
template
>
</el-table-column>
<!-- 内容 -->
<el-table-column
:label=
"$t('multishop.hotSearch.content')"
prop=
"content"
align=
"center"
>
<
template
slot-scope=
"{row}"
>
<span>
{{
row
.
content
}}
</span>
</
template
>
</el-table-column>
<!-- 创建时间 -->
<el-table-column
:label=
"$t('multishop.hotSearch.createDate')"
prop=
"createTime"
align=
"center"
>
<
template
slot-scope=
"{row}"
>
<span>
{{
row
.
createTime
}}
</span>
</
template
>
</el-table-column>
<!-- 顺序 -->
<el-table-column
:label=
"$t('multishop.hotSearch.seq')"
prop=
"seq"
align=
"center"
>
<
template
slot-scope=
"{row}"
>
<span>
{{
row
.
seq
}}
</span>
</
template
>
</el-table-column>
<!-- 状态 0下线 1上线 -->
<el-table-column
:label=
"$t('multishop.hotSearch.status')"
prop=
"status"
align=
"center"
>
<
template
slot-scope=
"{row}"
>
<!--
<span>
{{
row
.
status
}}
</span>
-->
<el-tag
v-if=
"row.status === 0"
size=
"small"
type=
"danger"
>
{{
'
未启用
'
}}
</el-tag>
<el-tag
v-else
size=
"small"
>
{{
'
启用
'
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
:label=
"$t('table.actions')"
align=
"center"
width=
"230"
class-name=
"small-padding fixed-width"
>
<
template
slot-scope=
"{row}"
>
<el-button
v-permission=
"['multishop:hotSearch:update']"
type=
"primary"
size=
"mini"
icon=
"el-icon-edit"
@
click=
"addOrUpdateHandle(row.hotSearchId)"
>
{{
$t
(
'
table.edit
'
)
}}
</el-button>
<el-button
v-permission=
"['multishop:hotSearch:delete']"
type=
"danger"
size=
"mini"
icon=
"el-icon-delete"
@
click=
"deleteHandle(row.hotSearchId)"
>
{{
$t
(
'
table.delete
'
)
}}
</el-button>
</
template
>
</el-table-column>
</el-table>
<!-- 分页条 -->
<pagination
v-show=
"pageVO.total>0"
:total=
"pageVO.total"
:page.sync=
"pageQuery.pageNum"
:limit.sync=
"pageQuery.pageSize"
@
pagination=
"getPage()"
/>
<!-- 弹窗, 新增 / 修改 -->
<add-or-update
v-if=
"addOrUpdateVisible"
ref=
"addOrUpdate"
@
refreshDataList=
"getPage()"
/>
</div>
</template>
<
script
>
import
permission
from
'
@/directive/permission/index.js
'
import
Pagination
from
'
@/components/Pagination
'
import
AddOrUpdate
from
'
./add-or-update.vue
'
import
*
as
api
from
'
@/api/multishop/hot-search
'
export
default
{
name
:
''
,
components
:
{
Pagination
,
AddOrUpdate
},
directives
:
{
permission
},
data
()
{
return
{
// 查询的参数
pageQuery
:
{
pageSize
:
10
,
pageNum
:
1
,
title
:
null
,
content
:
null
,
status
:
null
},
// 返回参数
pageVO
:
{
list
:
[],
// 返回的列表
total
:
0
,
// 一共多少条数据
pages
:
0
// 一共多少页
},
// loading
pageLoading
:
true
,
// 查询参数
searchParam
:
{
},
addOrUpdateVisible
:
false
}
},
mounted
()
{
this
.
getPage
()
},
methods
:
{
getPage
()
{
this
.
pageLoading
=
true
api
.
page
({
...
this
.
pageQuery
,
...
this
.
searchParam
}).
then
(
pageVO
=>
{
this
.
pageVO
=
pageVO
this
.
pageLoading
=
false
})
},
addOrUpdateHandle
(
hotSearchId
)
{
this
.
addOrUpdateVisible
=
true
this
.
$nextTick
(()
=>
{
this
.
$refs
.
addOrUpdate
.
init
(
hotSearchId
)
})
},
deleteHandle
(
hotSearchId
)
{
this
.
$confirm
(
this
.
$t
(
'
table.sureToDelete
'
),
this
.
$t
(
'
table.tips
'
),
{
confirmButtonText
:
this
.
$t
(
'
table.confirm
'
),
cancelButtonText
:
this
.
$t
(
'
table.cancel
'
),
type
:
'
warning
'
}).
then
(()
=>
this
.
deleteById
(
hotSearchId
))
},
deleteById
(
hotSearchId
)
{
api
.
deleteById
(
hotSearchId
).
then
(()
=>
{
this
.
$message
({
message
:
this
.
$t
(
'
table.actionSuccess
'
),
type
:
'
success
'
,
duration
:
1500
,
onClose
:
()
=>
this
.
getPage
()
})
})
},
getSearchList
()
{
this
.
pageQuery
.
pageNum
=
1
// 若请求参数某项没值,则不传此参数
this
.
pageQuery
.
title
=
this
.
pageQuery
.
title
||
null
this
.
pageQuery
.
content
=
this
.
pageQuery
.
content
||
null
this
.
pageQuery
.
status
=
this
.
pageQuery
.
status
||
null
this
.
getPage
()
},
clearSearchInfo
()
{
// 若请求参数某项没值,则不传此参数
this
.
pageQuery
.
title
=
null
this
.
pageQuery
.
content
=
null
this
.
pageQuery
.
status
=
null
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.mod-hot-search
{
.el-form--inline
{
.el-form-item
{
margin-right
:
20px
;
}
}
}
</
style
>
front-end/mall4cloud-multishop-master/src/views/multishop/index-img/add-or-update.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<div
class=
"index-img"
>
<el-dialog
:title=
"dataForm.attrId? $t('table.edit'): $t('table.create')"
:close-on-click-modal=
"false"
:destroy-on-close=
"true"
:visible.sync=
"visible"
top=
"12vh"
width=
"750px"
@
close=
"closeDialog"
>
<el-form
ref=
"dataForm"
:rules=
"rules"
:model=
"dataForm"
label-position=
"left"
label-width=
"90px"
style=
"min-width: 600px; width: 600px; margin-left:35px;"
>
<!-- 图片 -->
<el-form-item
label=
"轮播图片"
prop=
"imgUrl"
>
<img-upload
v-model=
"dataForm.imgUrl"
/>
<div
class=
""
>
建议图片尺寸为710*780
</div>
</el-form-item>
<!-- 平台 -->
<el-form-item
label=
"展示平台"
prop=
"imgType"
>
<el-radio
v-model=
"dataForm.imgType"
:label=
"0"
>
移动端
</el-radio>
</el-form-item>
<!-- 状态 -->
<el-form-item
label=
"轮播图状态"
prop=
"status"
>
<el-radio
v-model=
"dataForm.status"
:label=
"0"
>
禁用
</el-radio>
<el-radio
v-model=
"dataForm.status"
:label=
"1"
>
正常
</el-radio>
</el-form-item>
<!-- 排序 -->
<el-form-item
label=
"轮播图排序"
prop=
"seq"
>
<el-input-number
v-model=
"dataForm.seq"
:min=
"0"
controls-position=
"right"
:precision=
"0"
/>
</el-form-item>
<!-- 类型 -->
<el-form-item
label=
"轮播图类型"
prop=
""
>
<el-radio
v-model=
"relatedSpu"
:label=
"0"
>
无
</el-radio>
<el-radio
v-model=
"relatedSpu"
:label=
"1"
>
商品
</el-radio>
<div
v-if=
"relatedSpu === 1 && dataForm.spu && dataForm.spu.spuId"
>
<el-card
:body-style=
"
{ padding: '0px' }" style="height: 160px;width: 120px">
<img
:src=
"(dataForm.spu.mainImgUrl).indexOf('http')===-1 ? resourcesUrl + dataForm.spu.mainImgUrl : dataForm.spu.mainImgUrl"
style=
"height:104px;width:100%"
>
<div
class=
"card-prod-bottom"
>
<span
class=
"card-prod-name"
>
{{
dataForm
.
spu
.
spuName
}}
</span>
<el-button
type=
"text"
class=
"card-prod-name-button"
@
click=
"deleteCurrentProd"
>
删除
</el-button>
</div>
</el-card>
</div>
<div
v-if=
"relatedSpu === 1 && !dataForm.spuId"
class=
"select-pro"
>
<el-button
@
click=
"selectProds"
>
选择商品
</el-button>
</div>
<prods-select
v-if=
"prodSelectVisible"
ref=
"prodSelect"
:is-single=
"true"
@
refreshSelectProds=
"getSelectedProd"
/>
</el-form-item>
</el-form>
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"visible = false"
>
{{
$t
(
'
table.cancel
'
)
}}
</el-button>
<el-button
type=
"primary"
@
click=
"dataFormSubmit()"
>
{{
$t
(
'
table.confirm
'
)
}}
</el-button>
</div>
</el-dialog>
</div>
</
template
>
<
script
>
import
*
as
api
from
'
@/api/multishop/index-img
'
import
ImgUpload
from
'
@/components/ImgUpload
'
import
ProdsSelect
from
'
@/components/ProdsSelect
'
export
default
{
components
:
{
ImgUpload
,
ProdsSelect
},
data
()
{
return
{
visible
:
false
,
dataForm
:
{
imgId
:
0
,
imgUrl
:
null
,
seq
:
0
,
imgType
:
0
,
status
:
1
,
spuId
:
null
,
spu
:
{}
// 商品列表
},
relatedSpu
:
0
,
resourcesUrl
:
process
.
env
.
VUE_APP_RESOURCES_URL
,
// 关联数据
card
:
{
id
:
0
,
pic
:
''
,
name
:
''
,
realData
:
{
prod
:
[],
shop
:
[],
activity
:
[]
}
},
prodSelectVisible
:
false
,
prods
:
{},
rules
:
{
imgUrl
:
[
{
required
:
true
,
message
:
'
请选择轮播图图片
'
,
trigger
:
'
blur
'
}
]
}
}
},
methods
:
{
init
(
imgId
)
{
this
.
visible
=
true
this
.
dataForm
.
imgId
=
imgId
||
0
this
.
$nextTick
(()
=>
{
this
.
$refs
[
'
dataForm
'
].
resetFields
()
if
(
!
this
.
dataForm
.
imgId
)
{
return
}
api
.
get
(
imgId
).
then
(
data
=>
{
this
.
dataForm
=
data
this
.
dataForm
.
spu
.
spuName
=
this
.
dataForm
.
spu
.
name
this
.
spus
=
data
.
spus
||
[]
this
.
relatedSpu
=
data
.
spuId
?
1
:
0
})
})
},
selectProds
()
{
this
.
prodSelectVisible
=
true
this
.
$nextTick
(()
=>
{
this
.
$refs
.
prodSelect
.
init
()
})
},
getSelectedProd
(
prods
)
{
console
.
log
(
prods
)
this
.
dataForm
.
spu
=
prods
[
0
]
this
.
dataForm
.
spuId
=
prods
[
0
].
spuId
this
.
dataForm
.
spuName
=
prods
[
0
].
spuName
},
deleteCurrentProd
()
{
this
.
dataForm
.
spu
=
{}
this
.
dataForm
.
spuId
=
''
},
closeDialog
()
{
this
.
dataForm
=
{
imgId
:
0
,
imgUrl
:
null
,
seq
:
0
,
imgType
:
0
,
status
:
1
,
spuId
:
null
,
spu
:
{}
}
},
/**
* 表单提交
*/
dataFormSubmit
()
{
this
.
$refs
.
dataForm
.
validate
(
valid
=>
{
if
(
!
valid
)
{
return
}
if
(
!
this
.
dataForm
.
imgUrl
)
{
this
.
$message
({
message
:
'
请选择轮播图片
'
,
type
:
'
warning
'
,
duration
:
1500
})
return
}
if
(
this
.
relatedSpu
===
1
&&
!
this
.
dataForm
.
spuId
)
{
this
.
$message
({
message
:
'
请选择商品
'
,
type
:
'
warning
'
,
duration
:
1500
})
return
}
if
(
this
.
relatedSpu
===
0
)
{
this
.
dataForm
.
spuId
=
''
}
const
dataForm
=
JSON
.
parse
(
JSON
.
stringify
(
this
.
dataForm
))
dataForm
.
spu
=
undefined
const
request
=
this
.
dataForm
.
imgId
?
api
.
update
(
dataForm
)
:
api
.
save
(
dataForm
)
request
.
then
(
data
=>
{
this
.
$message
({
message
:
this
.
$t
(
'
table.actionSuccess
'
),
type
:
'
success
'
,
duration
:
1500
,
onClose
:
()
=>
{
this
.
visible
=
false
this
.
$emit
(
'
refreshDataList
'
)
this
.
$refs
[
'
dataForm
'
].
resetFields
()
}
})
})
})
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.index-img
{
.el-form--label-left
{
.el-form-item__label
{
text-align
:
right
!
important
;
}
}
.select-pro
{
margin-top
:
10px
;
}
.card-prod-bottom
{
position
:
relative
;
text-align
:
left
;
top
:
-15px
;
.card-prod-name
{
margin
:
auto
;
padding
:
0
4px
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
width
:
118px
;
display
:
inline-block
;
}
.card-prod-name-button
{
position
:
absolute
;
top
:
30px
;
right
:
0
;
}
.el-button--medium
{
padding
:
2px
6px
!
important
;
}
}
}
</
style
>
front-end/mall4cloud-multishop-master/src/views/multishop/index-img/index.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<div
class=
"app-container"
>
<!-- 搜索相关区域 -->
<div
class=
"filter-container"
>
<el-button
v-permission=
"['multishop:indexImg:save']"
size=
"mini"
icon=
"el-icon-plus"
type=
"primary"
class=
"filter-item"
@
click=
"addOrUpdateHandle()"
>
{{
$t
(
'
table.create
'
)
}}
</el-button>
</div>
<!-- 列表相关区域 -->
<el-table
v-loading=
"pageLoading"
:data=
"pageVO.list"
border
stripe
fit
row-key=
"imgId"
highlight-current-row
style=
"width: 100%;"
>
<!-- 图片 -->
<el-table-column
label=
"图片"
prop=
"imgUrl"
align=
"center"
width=
"300px"
>
<template
slot-scope=
"
{row}">
<img
:src=
"(row.imgUrl).indexOf('http')===-1 ? resourcesUrl + row.imgUrl : row.imgUrl"
class=
"img"
>
</
template
>
</el-table-column>
<!-- 顺序 -->
<el-table-column
label=
"顺序"
prop=
""
align=
"center"
>
<
template
slot-scope=
"{row}"
>
<span>
{{
row
.
seq
}}
</span>
</
template
>
</el-table-column>
<!-- 状态 -->
<el-table-column
label=
"状态"
prop=
"status"
align=
"center"
>
<
template
slot-scope=
"{row}"
>
<el-tag
v-if=
"row.status === 0"
size=
"small"
type=
"danger"
>
{{
$t
(
"
product.category.offline
"
)
}}
</el-tag>
<el-tag
v-else
size=
"small"
>
{{
$t
(
"
product.category.normal
"
)
}}
</el-tag>
</
template
>
</el-table-column>
<!-- 平台 -->
<el-table-column
label=
"平台"
prop=
"icon"
align=
"center"
>
<
template
slot-scope=
"{row}"
>
<span>
{{
[
'
移动端
'
,
'
PC端
'
][
row
.
imgType
]
}}
</span>
</
template
>
</el-table-column>
<!-- 操作 -->
<el-table-column
:label=
"$t('table.actions')"
align=
"center"
class-name=
"small-padding fixed-width"
>
<
template
slot-scope=
"{row}"
>
<el-button
v-permission=
"['multishop:indexImg:update']"
type=
"text"
@
click=
"addOrUpdateHandle(row.imgId)"
>
{{
$t
(
'
table.edit
'
)
}}
</el-button>
<el-button
v-permission=
"['multishop:indexImg:delete']"
type=
"text"
@
click=
"deleteHandle(row.imgId)"
>
{{
$t
(
'
table.delete
'
)
}}
</el-button>
</
template
>
</el-table-column>
</el-table>
<!-- 分页条 -->
<pagination
v-show=
"pageVO.total>0"
:total=
"pageVO.total"
:page.sync=
"pageQuery.pageNum"
:limit.sync=
"pageQuery.pageSize"
@
pagination=
"getPage()"
/>
<!-- 弹窗, 新增 / 修改 -->
<add-or-update
v-if=
"addOrUpdateVisible"
ref=
"addOrUpdate"
@
refreshDataList=
"getPage()"
/>
</div>
</template>
<
script
>
import
permission
from
'
@/directive/permission/index.js
'
import
Pagination
from
'
@/components/Pagination
'
import
AddOrUpdate
from
'
./add-or-update.vue
'
import
*
as
api
from
'
@/api/multishop/index-img
'
export
default
{
components
:
{
Pagination
,
AddOrUpdate
},
directives
:
{
permission
},
data
()
{
return
{
resourcesUrl
:
process
.
env
.
VUE_APP_RESOURCES_URL
,
// 查询的参数
pageQuery
:
{
pageSize
:
10
,
pageNum
:
1
,
name
:
null
,
attrType
:
null
},
// 返回参数
pageVO
:
{
list
:
[],
// 返回的列表
total
:
0
,
// 一共多少条数据
pages
:
0
// 一共多少页
},
// loading
pageLoading
:
true
,
addOrUpdateVisible
:
false
}
},
mounted
()
{
this
.
getPage
()
},
methods
:
{
getPage
()
{
this
.
pageLoading
=
true
api
.
page
({
...
this
.
pageQuery
,
...
this
.
searchParam
}).
then
(
pageVO
=>
{
this
.
pageVO
=
pageVO
this
.
pageLoading
=
false
})
},
addOrUpdateHandle
(
imgId
)
{
this
.
addOrUpdateVisible
=
true
this
.
$nextTick
(()
=>
{
this
.
$refs
.
addOrUpdate
.
init
(
imgId
)
})
},
deleteHandle
(
imgId
)
{
this
.
$confirm
(
this
.
$t
(
'
table.sureToDelete
'
),
this
.
$t
(
'
table.tips
'
),
{
confirmButtonText
:
this
.
$t
(
'
table.confirm
'
),
cancelButtonText
:
this
.
$t
(
'
table.cancel
'
),
type
:
'
warning
'
}).
then
(()
=>
this
.
deleteById
(
imgId
))
},
deleteById
(
imgId
)
{
api
.
deleteById
(
imgId
).
then
(()
=>
{
this
.
$message
({
message
:
this
.
$t
(
'
table.actionSuccess
'
),
type
:
'
success
'
,
duration
:
1500
,
onClose
:
()
=>
this
.
getPage
()
})
})
},
/**
* 搜索
*/
search
()
{
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.app-container
{
.img
{
width
:
auto
;
height
:
auto
;
max-width
:
100%
;
max-height
:
300px
;
}
}
</
style
>
front-end/mall4cloud-multishop-master/src/views/multishop/notice/add-or-update.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<el-dialog
:title=
"dataForm.id? $t('table.edit'): $t('table.create')"
:close-on-click-modal=
"false"
:visible.sync=
"visible"
top=
"5vh"
class=
"natice-dialog"
>
<el-form
ref=
"dataForm"
:rules=
"rules"
:model=
"dataForm"
label-position=
"left"
label-width=
"70px"
style=
"margin: 0 20px;"
>
<!-- 公告标题 -->
<el-form-item
:label=
"$t('multishop.notice.title')"
prop=
"title"
>
<el-input
v-model=
"dataForm.title"
placeholder=
"请输入公告标题"
/>
</el-form-item>
<!-- 状态(1:公布 0:撤回) -->
<el-form-item
:label=
"$t('multishop.notice.status')"
prop=
"status"
>
<el-radio-group
v-model=
"dataForm.status"
>
<el-radio
:label=
"0"
>
撤销
</el-radio>
<el-radio
:label=
"1"
>
公布
</el-radio>
</el-radio-group>
</el-form-item>
<!-- 是否置顶 -->
<el-form-item
:label=
"$t('multishop.notice.isTop')"
prop=
"isTop"
>
<el-radio-group
v-model=
"dataForm.isTop"
>
<el-radio
:label=
"0"
>
否
</el-radio>
<el-radio
:label=
"1"
>
是
</el-radio>
</el-radio-group>
</el-form-item>
<!-- 公告内容 -->
<el-form-item
:label=
"$t('multishop.notice.content')"
prop=
"content"
>
<tiny-mce
v-if=
"visible"
v-model=
"dataForm.content"
/>
</el-form-item>
</el-form>
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"visible = false"
>
{{
$t
(
'
table.cancel
'
)
}}
</el-button>
<el-button
type=
"primary"
@
click=
"dataFormSubmit()"
>
{{
$t
(
'
table.confirm
'
)
}}
</el-button>
</div>
</el-dialog>
</
template
>
<
script
>
import
*
as
api
from
'
@/api/multishop/notice
'
import
TinyMce
from
'
@/components/Tinymce
'
export
default
{
components
:
{
TinyMce
},
data
()
{
return
{
visible
:
false
,
dataForm
:
{
// id: 1, // 公告id
// shopId: 1, // 店铺id
title
:
''
,
// 公告标题
content
:
''
,
// 公告内容
status
:
1
,
// 状态(1:公布 0:撤回)
isTop
:
0
,
// 是否置顶
type
:
2
// 类型(1:平台公告 2:商城公告)
// publishTime: '' // 发布时间
},
rules
:
{
}
}
},
methods
:
{
init
(
id
)
{
this
.
dataForm
.
id
=
id
||
0
this
.
visible
=
true
this
.
$nextTick
(()
=>
{
this
.
$refs
[
'
dataForm
'
].
resetFields
()
if
(
!
this
.
dataForm
.
id
)
{
return
}
api
.
get
(
id
).
then
(
data
=>
{
this
.
dataForm
=
data
})
})
},
// 表单提交
dataFormSubmit
()
{
this
.
$refs
.
dataForm
.
validate
(
valid
=>
{
if
(
!
valid
)
{
return
}
const
request
=
this
.
dataForm
.
id
?
api
.
update
(
this
.
dataForm
)
:
api
.
save
(
this
.
dataForm
)
request
.
then
(
data
=>
{
this
.
$message
({
message
:
this
.
$t
(
'
table.actionSuccess
'
),
type
:
'
success
'
,
duration
:
1500
,
onClose
:
()
=>
{
this
.
visible
=
false
this
.
$emit
(
'
refreshDataList
'
)
this
.
$refs
[
'
dataForm
'
].
resetFields
()
}
})
})
})
}
}
}
</
script
>
<
style
lang=
"scss"
>
.natice-dialog
{
.el-dialog
{
min-width
:
740px
}
.el-dialog__body
{
padding
:
10px
20px
;
}
}
</
style
>
front-end/mall4cloud-multishop-master/src/views/multishop/notice/index.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<div
class=
"app-container"
>
<!-- 搜索相关区域 -->
<div
class=
"filter-container"
>
<el-button
size=
"mini"
icon=
"el-icon-search"
class=
"filter-item"
@
click=
"getPage()"
>
{{
$t
(
'
table.search
'
)
}}
</el-button>
<el-button
v-permission=
"['multishop:notice:save']"
size=
"mini"
icon=
"el-icon-plus"
type=
"primary"
class=
"filter-item"
@
click=
"addOrUpdateHandle()"
>
{{
$t
(
'
table.create
'
)
}}
</el-button>
</div>
<!-- 列表相关区域 -->
<el-table
v-loading=
"pageLoading"
:data=
"pageVO.list"
border
fit
highlight-current-row
style=
"width: 100%;"
>
<!-- 发布时间 -->
<el-table-column
:label=
"$t('multishop.notice.publishTime')"
prop=
"publishTime"
align=
"center"
>
<template
slot-scope=
"
{row}">
<span>
{{
row
.
publishTime
}}
</span>
</
template
>
</el-table-column>
<!-- 公告标题 -->
<el-table-column
:label=
"$t('multishop.notice.title')"
prop=
"title"
align=
"center"
>
<
template
slot-scope=
"{row}"
>
<span>
{{
row
.
title
}}
</span>
</
template
>
</el-table-column>
<!-- 状态(1:公布 0:撤回) -->
<el-table-column
:label=
"$t('multishop.notice.status')"
prop=
"status"
align=
"center"
>
<
template
slot-scope=
"{row}"
>
<el-tag
:type=
"row.status === 0 ? 'danger' : ''"
>
{{
[
'
撤销
'
,
'
公布
'
][
row
.
status
]
}}
</el-tag>
</
template
>
</el-table-column>
<!-- 是否置顶 -->
<el-table-column
:label=
"$t('multishop.notice.isTop')"
prop=
"isTop"
align=
"center"
>
<
template
slot-scope=
"{row}"
>
<el-tag
:type=
"row.isTop === 0 ? 'warning' : ''"
>
{{
[
'
否
'
,
'
是
'
][
row
.
isTop
]
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
:label=
"$t('table.actions')"
align=
"center"
width=
"230"
class-name=
"small-padding fixed-width"
>
<
template
slot-scope=
"{row}"
>
<el-button
v-permission=
"['multishop:notice:update']"
type=
"text"
@
click=
"addOrUpdateHandle(row.id)"
>
{{
$t
(
'
table.edit
'
)
}}
</el-button>
<el-button
v-permission=
"['multishop:notice:delete']"
type=
"text"
@
click=
"deleteHandle(row.id)"
>
{{
$t
(
'
table.delete
'
)
}}
</el-button>
</
template
>
</el-table-column>
</el-table>
<!-- 分页条 -->
<pagination
v-show=
"pageVO.total>0"
:total=
"pageVO.total"
:page.sync=
"pageQuery.pageNum"
:limit.sync=
"pageQuery.pageSize"
@
pagination=
"getPage()"
/>
<!-- 弹窗, 新增 / 修改 -->
<add-or-update
v-if=
"addOrUpdateVisible"
ref=
"addOrUpdate"
@
refreshDataList=
"getPage()"
/>
</div>
</template>
<
script
>
import
permission
from
'
@/directive/permission/index.js
'
import
Pagination
from
'
@/components/Pagination
'
import
AddOrUpdate
from
'
./add-or-update.vue
'
import
*
as
api
from
'
@/api/multishop/notice
'
export
default
{
name
:
''
,
components
:
{
Pagination
,
AddOrUpdate
},
directives
:
{
permission
},
data
()
{
return
{
// 查询的参数
pageQuery
:
{
pageSize
:
10
,
pageNum
:
1
},
// 返回参数
pageVO
:
{
list
:
[],
// 返回的列表
total
:
0
,
// 一共多少条数据
pages
:
0
// 一共多少页
},
// loading
pageLoading
:
true
,
// 查询参数
searchParam
:
{
},
addOrUpdateVisible
:
false
}
},
mounted
()
{
this
.
getPage
()
},
methods
:
{
getPage
()
{
this
.
pageLoading
=
true
api
.
page
({
...
this
.
pageQuery
,
...
this
.
searchParam
}).
then
(
pageVO
=>
{
this
.
pageVO
=
pageVO
this
.
pageLoading
=
false
})
},
addOrUpdateHandle
(
id
)
{
this
.
addOrUpdateVisible
=
true
this
.
$nextTick
(()
=>
{
this
.
$refs
.
addOrUpdate
.
init
(
id
)
})
},
deleteHandle
(
id
)
{
this
.
$confirm
(
this
.
$t
(
'
table.sureToDelete
'
),
this
.
$t
(
'
table.tips
'
),
{
confirmButtonText
:
this
.
$t
(
'
table.confirm
'
),
cancelButtonText
:
this
.
$t
(
'
table.cancel
'
),
type
:
'
warning
'
}).
then
(()
=>
this
.
deleteById
(
id
))
},
deleteById
(
id
)
{
api
.
deleteById
(
id
).
then
(()
=>
{
this
.
$message
({
message
:
this
.
$t
(
'
table.actionSuccess
'
),
type
:
'
success
'
,
duration
:
1500
,
onClose
:
()
=>
this
.
getPage
()
})
})
}
}
}
</
script
>
front-end/mall4cloud-multishop-master/src/views/multishop/shop-user/account-add-or-update.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<el-dialog
:title=
"dataForm.hasAccount? $t('table.edit'): $t('table.create')"
:visible.sync=
"visible"
>
<el-form
ref=
"dataForm"
:rules=
"rules"
:model=
"dataForm"
label-position=
"left"
label-width=
"70px"
style=
"width: 400px; margin-left:50px;"
>
<!-- 用户名 -->
<el-form-item
:label=
"$t('multishop.shopUserAccount.username')"
prop=
"username"
>
<el-input
v-model=
"dataForm.username"
/>
</el-form-item>
<!-- 密码 -->
<el-form-item
:label=
"$t('multishop.shopUserAccount.password')"
prop=
"password"
>
<el-input
v-model=
"dataForm.password"
show-password
/>
</el-form-item>
<!-- 状态 -->
<el-form-item
:label=
"$t('multishop.shopUserAccount.status')"
prop=
"status"
>
<el-radio-group
v-model=
"dataForm.status"
>
<el-radio
:label=
"1"
>
启用
</el-radio>
<el-radio
:label=
"0"
>
禁用
</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"visible = false"
>
{{
$t
(
'
table.cancel
'
)
}}
</el-button>
<el-button
type=
"primary"
@
click=
"dataFormSubmit()"
>
{{
$t
(
'
table.confirm
'
)
}}
</el-button>
</div>
</el-dialog>
</
template
>
<
script
>
import
*
as
api
from
'
@/api/multishop/shop-user-account
'
import
{
USER_NAME_REGEXP
}
from
'
@/utils/validate
'
export
default
{
data
()
{
return
{
visible
:
false
,
dataForm
:
{
hasAccount
:
0
,
userId
:
0
,
email
:
null
,
phone
:
null
,
username
:
null
,
password
:
null
,
status
:
1
},
rules
:
{
username
:
[
{
required
:
true
,
message
:
'
请输入用户名
'
,
trigger
:
'
blur
'
},
{
pattern
:
USER_NAME_REGEXP
,
message
:
'
用户名不能为纯数字且由数字字母下划线 4-16位组成
'
}
],
password
:
[
{
pattern
:
/^
(?!\d
+$
)([
a-zA-Z0-9_
]{4,16})
$/
,
message
:
'
密码不能为纯数字且由数字字母下划线 4-16位组成
'
}
]
}
}
},
methods
:
{
init
(
userId
,
hasAccount
)
{
this
.
dataForm
.
userId
=
userId
this
.
dataForm
.
hasAccount
=
hasAccount
this
.
visible
=
true
this
.
$nextTick
(()
=>
{
this
.
$refs
[
'
dataForm
'
].
resetFields
()
if
(
!
this
.
dataForm
.
hasAccount
)
{
return
}
api
.
get
(
userId
).
then
(
data
=>
{
this
.
dataForm
=
data
this
.
dataForm
.
hasAccount
=
hasAccount
})
})
},
// 表单提交
dataFormSubmit
()
{
this
.
$refs
.
dataForm
.
validate
(
valid
=>
{
if
(
!
valid
)
{
return
}
console
.
log
(
this
.
dataForm
)
const
request
=
this
.
dataForm
.
hasAccount
?
api
.
update
(
this
.
dataForm
)
:
api
.
save
(
this
.
dataForm
)
request
.
then
(
data
=>
{
this
.
$message
({
message
:
this
.
$t
(
'
table.actionSuccess
'
),
type
:
'
success
'
,
duration
:
1500
,
onClose
:
()
=>
{
this
.
visible
=
false
this
.
$emit
(
'
refreshDataList
'
)
this
.
$refs
[
'
dataForm
'
].
resetFields
()
}
})
})
})
}
}
}
</
script
>
front-end/mall4cloud-multishop-master/src/views/multishop/shop-user/add-or-update.vue
0 → 100644
View file @
a21f5a9a
<
template
>
<el-dialog
:title=
"dataForm.shopUserId? $t('table.edit'): $t('table.create')"
:visible.sync=
"visible"
>
<el-form
ref=
"dataForm"
:rules=
"dataRule"
:model=
"dataForm"
label-position=
"right"
label-width=
"80px"
>
<!-- 昵称 -->
<el-form-item
:label=
"$t('multishop.shopUser.nickName')"
prop=
"nickName"
>
<el-input
v-model=
"dataForm.nickName"
/>
</el-form-item>
<!-- 头像 -->
<el-form-item
:label=
"$t('multishop.shopUser.avatar')"
prop=
"avatar"
label-width=
"80px"
>
<img-upload
v-model=
"dataForm.avatar"
/>
<!--
<pic-upload
v-model=
"dataForm.avatar"
/>
-->
</el-form-item>
<!-- 员工编号 -->
<el-form-item
:label=
"$t('multishop.shopUser.code')"
prop=
"code"
>
<el-input
v-model=
"dataForm.code"
/>
</el-form-item>
<!-- 联系方式 -->
<el-form-item
:label=
"$t('multishop.shopUser.phoneNum')"
prop=
"phoneNum"
>
<el-input
v-model=
"dataForm.phoneNum"
/>
</el-form-item>
<!-- 选择角色 -->
<el-form-item
label=
"选择角色"
prop=
"roleIds"
>
<el-select
v-model=
"dataForm.roleIds"
multiple
placeholder=
"请选择"
style=
"width: 60%"
>
<el-option
v-for=
"item in roleOpts"
:key=
"item.roleId"
:label=
"item.roleName"
:value=
"item.roleId"
/>
</el-select>
</el-form-item>
</el-form>
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"visible = false"
>
{{
$t
(
'
table.cancel
'
)
}}
</el-button>
<el-button
type=
"primary"
@
click=
"dataFormSubmit()"
>
{{
$t
(
'
table.confirm
'
)
}}
</el-button>
</div>
</el-dialog>
</
template
>
<
script
>
import
*
as
api
from
'
@/api/multishop/shop-user
'
// import PicUpload from '@/components/PicUpload'
import
*
as
roleApi
from
'
@/api/rbac/role
'
import
ImgUpload
from
'
@/components/ImgUpload
'
export
default
{
components
:
{
// PicUpload,
ImgUpload
},
data
()
{
return
{
visible
:
false
,
dataForm
:
{
shopUserId
:
0
,
shopId
:
null
,
nickName
:
null
,
avatar
:
null
,
code
:
null
,
phoneNum
:
null
,
hasAccount
:
null
,
roleIds
:
[]
},
roleOpts
:
[],
dataRule
:
{
nickName
:
[
{
required
:
true
,
message
:
'
昵称不能为空
'
,
trigger
:
'
blur
'
}
],
avatar
:
[
{
required
:
true
,
message
:
'
头像不能为空
'
,
trigger
:
'
blur
'
}
]
}
}
},
methods
:
{
init
(
shopUserId
)
{
this
.
dataForm
.
shopUserId
=
shopUserId
||
0
this
.
visible
=
true
this
.
$nextTick
(()
=>
{
this
.
$refs
[
'
dataForm
'
].
resetFields
()
roleApi
.
list
().
then
(
data
=>
{
this
.
roleOpts
=
data
})
if
(
this
.
dataForm
.
shopUserId
)
{
api
.
get
(
shopUserId
).
then
(
data
=>
{
this
.
dataForm
=
data
})
}
})
},
// 表单提交
dataFormSubmit
()
{
this
.
$refs
.
dataForm
.
validate
(
valid
=>
{
if
(
valid
)
{
const
request
=
this
.
dataForm
.
shopUserId
?
api
.
update
(
this
.
dataForm
)
:
api
.
save
(
this
.
dataForm
)
request
.
then
(
data
=>
{
this
.
$message
({
message
:
this
.
$t
(
'
table.actionSuccess
'
),
type
:
'
success
'
,
duration
:
1500
,
onClose
:
()
=>
{
this
.
visible
=
false
this
.
$emit
(
'
refreshDataList
'
)
this
.
$refs
[
'
dataForm
'
].
resetFields
()
}
})
})
}
})
}
}
}
</
script
>
Prev
1
…
14
15
16
17
18
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment