Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
3500a206
authored
Oct 10, 2023
by
puhui999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
营销活动:完善 review 提到的问题,添加拼团列表查看弹窗
parent
86323f97
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
213 additions
and
93 deletions
+213
-93
src/api/mall/promotion/bargain/bargainActivity.ts
+1
-1
src/api/mall/promotion/combination/combinationRecord.ts
+5
-0
src/utils/formatTime.ts
+51
-0
src/utils/formatter.ts
+4
-9
src/utils/index.ts
+2
-3
src/views/mall/promotion/bargain/activity/BargainActivityForm.vue
+2
-2
src/views/mall/promotion/combination/activity/CombinationActivityForm.vue
+1
-2
src/views/mall/promotion/combination/record/CombinationRecordListDialog.vue
+119
-0
src/views/mall/promotion/combination/record/index.vue
+20
-66
src/views/mall/trade/order/index.vue
+8
-10
No files found.
src/api/mall/promotion/bargain/bargainActivity.ts
View file @
3500a206
...
@@ -24,7 +24,7 @@ export interface BargainProductVO {
...
@@ -24,7 +24,7 @@ export interface BargainProductVO {
spuId
:
number
spuId
:
number
skuId
:
number
skuId
:
number
bargainFirstPrice
:
number
// 砍价起始价格,单位分
bargainFirstPrice
:
number
// 砍价起始价格,单位分
bargainPrice
:
number
// 砍价底价
bargain
Min
Price
:
number
// 砍价底价
stock
:
number
// 活动库存
stock
:
number
// 活动库存
}
}
...
...
src/api/mall/promotion/combination/combinationRecord.ts
View file @
3500a206
...
@@ -22,6 +22,11 @@ export const getCombinationRecordPage = async (params) => {
...
@@ -22,6 +22,11 @@ export const getCombinationRecordPage = async (params) => {
return
await
request
.
get
({
url
:
'/promotion/combination-record/page'
,
params
})
return
await
request
.
get
({
url
:
'/promotion/combination-record/page'
,
params
})
}
}
// 查询一个拼团的完整拼团记录
export
const
getCombinationRecordPageByHeadId
=
async
(
params
)
=>
{
return
await
request
.
get
({
url
:
'/promotion/combination-record/page-by-headId'
,
params
})
}
// 获得拼团记录的概要信息
// 获得拼团记录的概要信息
export
const
getCombinationRecordSummary
=
async
()
=>
{
export
const
getCombinationRecordSummary
=
async
()
=>
{
return
await
request
.
get
({
url
:
'/promotion/combination-record/get-summary'
})
return
await
request
.
get
({
url
:
'/promotion/combination-record/get-summary'
})
...
...
src/utils/formatTime.ts
View file @
3500a206
import
dayjs
from
'dayjs'
import
dayjs
from
'dayjs'
/**
/**
* 日期快捷选项适用于 el-date-picker
*/
export
const
defaultShortcuts
=
[
{
text
:
'今天'
,
value
:
()
=>
{
return
new
Date
()
}
},
{
text
:
'昨天'
,
value
:
()
=>
{
const
date
=
new
Date
()
date
.
setTime
(
date
.
getTime
()
-
3600
*
1000
*
24
)
return
[
date
,
date
]
}
},
{
text
:
'最近七天'
,
value
:
()
=>
{
const
date
=
new
Date
()
date
.
setTime
(
date
.
getTime
()
-
3600
*
1000
*
24
*
7
)
return
[
date
,
new
Date
()]
}
},
{
text
:
'最近 30 天'
,
value
:
()
=>
{
const
date
=
new
Date
()
date
.
setTime
(
date
.
getTime
()
-
3600
*
1000
*
24
*
30
)
return
[
date
,
new
Date
()]
}
},
{
text
:
'本月'
,
value
:
()
=>
{
const
date
=
new
Date
()
date
.
setDate
(
1
)
// 设置为当前月的第一天
return
[
date
,
new
Date
()]
}
},
{
text
:
'今年'
,
value
:
()
=>
{
const
date
=
new
Date
()
return
[
new
Date
(
`
${
date
.
getFullYear
()}
-01-01`
),
date
]
}
}
]
/**
* 时间日期转换
* 时间日期转换
* @param date 当前时间,new Date() 格式
* @param date 当前时间,new Date() 格式
* @param format 需要转换的时间格式字符串
* @param format 需要转换的时间格式字符串
...
...
src/utils/formatter.ts
View file @
3500a206
import
{
fenToYuan
}
from
'@/utils'
import
{
floatToFixed2
}
from
'@/utils'
import
{
TableColumnCtx
}
from
'element-plus'
// 格式化金额【分转元】
// 格式化金额【分转元】
export
const
fenToYuanFormat
=
(
// @ts-ignore
row
:
any
,
export
const
fenToYuanFormat
=
(
_
,
_
,
cellValue
:
any
,
_
)
=>
{
column
:
TableColumnCtx
<
any
>
,
return
`¥
${
floatToFixed2
(
cellValue
)}
`
cellValue
:
any
,
index
:
number
)
=>
{
return
`¥
${
fenToYuan
(
cellValue
)}
`
}
}
src/utils/index.ts
View file @
3500a206
...
@@ -224,13 +224,12 @@ export const convertToInteger = (num: number | string | undefined): number => {
...
@@ -224,13 +224,12 @@ export const convertToInteger = (num: number | string | undefined): number => {
* 元转分
* 元转分
*/
*/
export
const
yuanToFen
=
(
amount
:
string
|
number
):
number
=>
{
export
const
yuanToFen
=
(
amount
:
string
|
number
):
number
=>
{
return
Math
.
round
(
Number
(
amount
)
*
100
)
return
convertToInteger
(
amount
)
}
}
/**
/**
* 分转元
* 分转元
*/
*/
export
const
fenToYuan
=
(
price
:
string
|
number
):
number
=>
{
export
const
fenToYuan
=
(
price
:
string
|
number
):
number
=>
{
price
=
Number
(
price
)
return
formatToFraction
(
price
)
return
(
price
/
100.0
).
toFixed
(
2
)
}
}
src/views/mall/promotion/bargain/activity/BargainActivityForm.vue
View file @
3500a206
...
@@ -61,6 +61,7 @@ import { SpuAndSkuList, SpuProperty, SpuSelect } from '@/views/mall/promotion/co
...
@@ -61,6 +61,7 @@ import { SpuAndSkuList, SpuProperty, SpuSelect } from '@/views/mall/promotion/co
import
{
getPropertyList
,
RuleConfig
}
from
'@/views/mall/product/spu/components'
import
{
getPropertyList
,
RuleConfig
}
from
'@/views/mall/product/spu/components'
import
*
as
ProductSpuApi
from
'@/api/mall/product/spu'
import
*
as
ProductSpuApi
from
'@/api/mall/product/spu'
import
{
convertToInteger
,
formatToFraction
}
from
'@/utils'
import
{
convertToInteger
,
formatToFraction
}
from
'@/utils'
import
{
cloneDeep
}
from
'lodash-es'
defineOptions
({
name
:
'PromotionBargainActivityForm'
})
defineOptions
({
name
:
'PromotionBargainActivityForm'
})
...
@@ -204,8 +205,7 @@ const submitForm = async () => {
...
@@ -204,8 +205,7 @@ const submitForm = async () => {
// 提交请求
// 提交请求
formLoading
.
value
=
true
formLoading
.
value
=
true
try
{
try
{
// TODO @puhui999: 这样要深克隆
const
data
=
cloneDeep
(
formRef
.
value
.
formModel
)
as
BargainActivityApi
.
BargainActivityVO
const
data
=
formRef
.
value
.
formModel
as
BargainActivityApi
.
BargainActivityVO
const
products
=
spuAndSkuListRef
.
value
.
getSkuConfigs
(
'productConfig'
)
const
products
=
spuAndSkuListRef
.
value
.
getSkuConfigs
(
'productConfig'
)
products
.
forEach
((
item
:
BargainProductVO
)
=>
{
products
.
forEach
((
item
:
BargainProductVO
)
=>
{
// 砍价价格元转分
// 砍价价格元转分
...
...
src/views/mall/promotion/combination/activity/CombinationActivityForm.vue
View file @
3500a206
...
@@ -167,8 +167,7 @@ const submitForm = async () => {
...
@@ -167,8 +167,7 @@ const submitForm = async () => {
products
.
forEach
((
item
:
CombinationActivityApi
.
CombinationProductVO
)
=>
{
products
.
forEach
((
item
:
CombinationActivityApi
.
CombinationProductVO
)
=>
{
item
.
combinationPrice
=
convertToInteger
(
item
.
combinationPrice
)
item
.
combinationPrice
=
convertToInteger
(
item
.
combinationPrice
)
})
})
// TODO @puhui999: 这样要深克隆
const
data
=
cloneDeep
(
formRef
.
value
.
formModel
)
as
CombinationActivityApi
.
CombinationActivityVO
const
data
=
formRef
.
value
.
formModel
as
CombinationActivityApi
.
CombinationActivityVO
data
.
products
=
products
data
.
products
=
products
// 真正提交
// 真正提交
if
(
formType
.
value
===
'create'
)
{
if
(
formType
.
value
===
'create'
)
{
...
...
src/views/mall/promotion/combination/record/CombinationRecordListDialog.vue
0 → 100644
View file @
3500a206
<
template
>
<Dialog
v-model=
"dialogVisible"
title=
"拼团列表"
>
<!-- 列表 -->
<ContentWrap>
<el-table
v-loading=
"loading"
:data=
"list"
>
<el-table-column
align=
"center"
label=
"编号"
prop=
"id"
/>
<el-table-column
align=
"center"
label=
"头像"
prop=
"avatar"
/>
<el-table-column
align=
"center"
label=
"昵称"
prop=
"nickname"
/>
<el-table-column
align=
"center"
label=
"开团团长"
prop=
"headId"
>
<template
#
default=
"
{ row }: { row: CombinationRecordApi.CombinationRecordVO }">
{{
row
.
headId
?
list
.
find
((
item
)
=>
item
.
id
===
row
.
headId
)?.
nickname
:
row
.
nickname
}}
</
template
>
</el-table-column>
<el-table-column
:formatter=
"dateFormatter"
align=
"center"
label=
"开团时间"
prop=
"startTime"
width=
"180"
/>
<el-table-column
align=
"center"
label=
"拼团商品"
prop=
"type"
show-overflow-tooltip
width=
"300"
>
<
template
#
defaul=
"{ row }"
>
<el-image
:src=
"row.picUrl"
class=
"mr-5px h-30px w-30px align-middle"
@
click=
"imagePreview(row.picUrl)"
/>
<span
class=
"align-middle"
>
{{
row
.
spuName
}}
</span>
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"几人团"
prop=
"userSize"
/>
<el-table-column
align=
"center"
label=
"参与人数"
prop=
"userCount"
/>
<el-table-column
:formatter=
"dateFormatter"
align=
"center"
label=
"参团时间"
prop=
"createTime"
width=
"180"
/>
<el-table-column
:formatter=
"dateFormatter"
align=
"center"
label=
"结束时间"
prop=
"endTime"
width=
"180"
/>
<el-table-column
align=
"center"
label=
"拼团状态"
prop=
"status"
>
<
template
#
default=
"scope"
>
<dict-tag
:type=
"DICT_TYPE.PROMOTION_COMBINATION_RECORD_STATUS"
:value=
"scope.row.status"
/>
</
template
>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
v-model:limit=
"queryParams.pageSize"
v-model:page=
"queryParams.pageNo"
:total=
"total"
@
pagination=
"getList"
/>
</ContentWrap>
</Dialog>
</template>
<
script
lang=
"ts"
setup
>
import
{
dateFormatter
}
from
'@/utils/formatTime'
import
*
as
CombinationRecordApi
from
'@/api/mall/promotion/combination/combinationRecord'
import
{
DICT_TYPE
}
from
'@/utils/dict'
import
{
createImageViewer
}
from
'@/components/ImageViewer'
/** 助力列表 */
defineOptions
({
name
:
'CombinationRecordListDialog'
})
const
message
=
useMessage
()
// 消息弹窗
const
loading
=
ref
(
true
)
// 列表的加载中
const
total
=
ref
(
0
)
// 列表的总页数
const
list
=
ref
([])
// 列表的数据
const
queryParams
=
reactive
({
pageNo
:
1
,
pageSize
:
10
,
headId
:
undefined
})
/** 打开弹窗 */
const
dialogVisible
=
ref
(
false
)
// 弹窗的是否展示
const
open
=
async
(
headId
:
any
)
=>
{
dialogVisible
.
value
=
true
queryParams
.
headId
=
headId
await
getList
()
}
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
/** 查询列表 */
const
getList
=
async
()
=>
{
loading
.
value
=
true
try
{
const
data
=
await
CombinationRecordApi
.
getCombinationRecordPageByHeadId
(
queryParams
)
list
.
value
=
data
.
list
total
.
value
=
data
.
total
}
finally
{
loading
.
value
=
false
}
}
/** 商品图预览 */
const
imagePreview
=
(
imgUrl
:
string
)
=>
{
createImageViewer
({
urlList
:
[
imgUrl
]
})
}
</
script
>
src/views/mall/promotion/combination/record/index.vue
View file @
3500a206
...
@@ -78,7 +78,7 @@
...
@@ -78,7 +78,7 @@
<el-form-item
label=
"创建时间"
prop=
"createTime"
>
<el-form-item
label=
"创建时间"
prop=
"createTime"
>
<el-date-picker
<el-date-picker
v-model=
"queryParams.createTime"
v-model=
"queryParams.createTime"
:shortcuts=
"
s
hortcuts"
:shortcuts=
"
defaultS
hortcuts"
class=
"!w-240px"
class=
"!w-240px"
end-placeholder=
"结束日期"
end-placeholder=
"结束日期"
start-placeholder=
"开始日期"
start-placeholder=
"开始日期"
...
@@ -171,9 +171,17 @@
...
@@ -171,9 +171,17 @@
/>
/>
</
template
>
</
template
>
</el-table-column>
</el-table-column>
<!-- TODO puhui999:这里加个查看拼团?点击后,查看完整的拼团列表? -->
<el-table-column
align=
"center"
fixed=
"right"
label=
"操作"
>
<el-table-column
align=
"center"
fixed=
"right"
label=
"操作"
>
<
template
#
default
></
template
>
<
template
#
default=
"scope"
>
<el-button
v-hasPermi=
"['promotion:combination-record:query']"
link
type=
"primary"
@
click=
"openRecordListDialog(scope.row)"
>
查看拼团
</el-button>
</
template
>
</el-table-column>
</el-table-column>
</el-table>
</el-table>
<!-- 分页 -->
<!-- 分页 -->
...
@@ -184,23 +192,27 @@
...
@@ -184,23 +192,27 @@
@
pagination=
"getList"
@
pagination=
"getList"
/>
/>
</ContentWrap>
</ContentWrap>
<!-- 表单弹窗 -->
<CombinationRecordListDialog
ref=
"combinationRecordListRef"
/>
</template>
</template>
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts"
setup
>
import
CombinationRecordListDialog
from
'./CombinationRecordListDialog.vue'
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'@/utils/dict'
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'@/utils/dict'
import
{
dateFormatter
}
from
'@/utils/formatTime'
import
{
dateFormatter
,
defaultShortcuts
}
from
'@/utils/formatTime'
import
{
createImageViewer
}
from
'@/components/ImageViewer'
import
{
createImageViewer
}
from
'@/components/ImageViewer'
import
*
as
CombinationRecordApi
from
'@/api/mall/promotion/combination/combinationRecord'
import
*
as
CombinationRecordApi
from
'@/api/mall/promotion/combination/combinationRecord'
defineOptions
({
name
:
'CombinationRecord'
})
defineOptions
({
name
:
'CombinationRecord'
})
const
queryParams
=
ref
({
const
queryParams
=
ref
({
dateType
:
0
,
// 日期类型
status
:
undefined
,
// 拼团状态
status
:
undefined
,
// 拼团状态
createTime
:
undefined
,
// 创建时间
createTime
:
undefined
,
// 创建时间
pageSize
:
10
,
pageSize
:
10
,
pageNo
:
1
pageNo
:
1
})
})
const
queryFormRef
=
ref
()
// 搜索的表单
const
queryFormRef
=
ref
()
// 搜索的表单
const
combinationRecordListRef
=
ref
()
// 查询表单 Ref
const
loading
=
ref
(
true
)
// 列表的加载中
const
loading
=
ref
(
true
)
// 列表的加载中
const
total
=
ref
(
0
)
// 总记录数
const
total
=
ref
(
0
)
// 总记录数
const
pageList
=
ref
<
CombinationRecordApi
.
CombinationRecordVO
[]
>
([])
// 分页数据
const
pageList
=
ref
<
CombinationRecordApi
.
CombinationRecordVO
[]
>
([])
// 分页数据
...
@@ -225,68 +237,10 @@ const recordSummary = ref({
...
@@ -225,68 +237,10 @@ const recordSummary = ref({
const
getSummary
=
async
()
=>
{
const
getSummary
=
async
()
=>
{
recordSummary
.
value
=
await
CombinationRecordApi
.
getCombinationRecordSummary
()
recordSummary
.
value
=
await
CombinationRecordApi
.
getCombinationRecordSummary
()
}
}
// 日期快捷选项
// TODO @puhui999:不用 dateType,而是 shortcuts 选择后,设置到对应的 date 就 ok 啦。直接通过它查询。然后,看看怎么把 shortcuts 变成一个公共变量,类似 defaultProps 一样
const
shortcuts
=
ref
([
{
text
:
'今天'
,
type
:
'toDay'
,
value
:
()
=>
{
queryParams
.
value
.
dateType
=
1
return
new
Date
()
}
},
{
text
:
'昨天'
,
type
:
'yesterday'
,
value
:
()
=>
{
const
date
=
new
Date
()
date
.
setTime
(
date
.
getTime
()
-
3600
*
1000
*
24
)
queryParams
.
value
.
dateType
=
2
return
[
date
,
date
]
}
},
{
text
:
'最近七天'
,
type
:
'lastSevenDays'
,
value
:
()
=>
{
const
date
=
new
Date
()
date
.
setTime
(
date
.
getTime
()
-
3600
*
1000
*
24
*
7
)
queryParams
.
value
.
dateType
=
3
return
[
date
,
new
Date
()]
}
},
{
text
:
'最近 30 天'
,
type
:
'last30Days'
,
value
:
()
=>
{
const
date
=
new
Date
()
date
.
setTime
(
date
.
getTime
()
-
3600
*
1000
*
24
*
30
)
queryParams
.
value
.
dateType
=
4
return
[
date
,
new
Date
()]
}
},
{
text
:
'本月'
,
type
:
'thisMonth'
,
value
:
()
=>
{
const
date
=
new
Date
()
date
.
setDate
(
1
)
// 设置为当前月的第一天
queryParams
.
value
.
dateType
=
5
return
[
date
,
new
Date
()]
}
},
{
text
:
'今年'
,
type
:
'thisYear'
,
value
:
()
=>
{
const
date
=
new
Date
()
queryParams
.
value
.
dateType
=
6
return
[
new
Date
(
`
${
date
.
getFullYear
()}
-01-01`
),
date
]
}
}
])
const
openRecordListDialog
=
(
row
:
CombinationRecordApi
.
CombinationRecordVO
)
=>
{
combinationRecordListRef
.
value
?.
open
(
row
.
headId
)
}
/** 搜索按钮操作 */
/** 搜索按钮操作 */
const
handleQuery
=
()
=>
{
const
handleQuery
=
()
=>
{
queryParams
.
value
.
pageNo
=
1
queryParams
.
value
.
pageNo
=
1
...
...
src/views/mall/trade/order/index.vue
View file @
3500a206
...
@@ -121,26 +121,24 @@
...
@@ -121,26 +121,24 @@
@
keyup
.
enter=
"handleQuery"
@
keyup
.
enter=
"handleQuery"
/>
/>
</el-form-item>
</el-form-item>
<!-- TODO puhui 聚合搜索等售后结束后实现-->
<!-- TODO puhui999:尽量不要用 .k 这样的参数,完整拼写,有完整的业务含义 -->
<el-form-item
label=
"聚合搜索"
>
<el-form-item
label=
"聚合搜索"
>
<el-input
<el-input
v-show=
"true"
v-show=
"true"
v-model=
"queryParams[queryType.
k
]"
v-model=
"queryParams[queryType.
queryParam
]"
class=
"!w-280px"
class=
"!w-280px"
clearable
clearable
placeholder=
"请输入"
placeholder=
"请输入"
>
>
<template
#
prepend
>
<template
#
prepend
>
<el-select
<el-select
v-model=
"queryType.
k
"
v-model=
"queryType.
queryParam
"
class=
"!w-110px"
class=
"!w-110px"
clearable
clearable
placeholder=
"全部"
placeholder=
"全部"
@
change=
"inputChangeSelect"
@
change=
"inputChangeSelect"
>
>
<el-option
<el-option
v-for=
"dict in
s
earchList"
v-for=
"dict in
dynamicS
earchList"
:key=
"dict.value"
:key=
"dict.value"
:label=
"dict.label"
:label=
"dict.label"
:value=
"dict.value"
:value=
"dict.value"
...
@@ -386,11 +384,10 @@ const queryParams = ref({
...
@@ -386,11 +384,10 @@ const queryParams = ref({
pickUpStoreId
:
null
,
// 自提门店
pickUpStoreId
:
null
,
// 自提门店
pickUpVerifyCode
:
null
// 自提核销码
pickUpVerifyCode
:
null
// 自提核销码
})
})
const
queryType
=
reactive
({
k
:
''
})
// 订单搜索类型 k
const
queryType
=
reactive
({
queryParam
:
''
})
// 订单搜索类型 queryParam
// 订单聚合搜索 select 类型配置
// 订单聚合搜索 select 类型配置(动态搜索)
// TODO @puhui999:dynamicSearchList,动态搜索;其它相关的变量和方法,都可以朝着这个变量靠哈;这样更容易理解;
const
dynamicSearchList
=
ref
([
const
searchList
=
ref
([
{
value
:
'no'
,
label
:
'订单号'
},
{
value
:
'no'
,
label
:
'订单号'
},
{
value
:
'userId'
,
label
:
'用户UID'
},
{
value
:
'userId'
,
label
:
'用户UID'
},
{
value
:
'userNickname'
,
label
:
'用户昵称'
},
{
value
:
'userNickname'
,
label
:
'用户昵称'
},
...
@@ -401,7 +398,7 @@ const searchList = ref([
...
@@ -401,7 +398,7 @@ const searchList = ref([
* @param val
* @param val
*/
*/
const
inputChangeSelect
=
(
val
:
string
)
=>
{
const
inputChangeSelect
=
(
val
:
string
)
=>
{
s
earchList
.
value
dynamicS
earchList
.
value
.
filter
((
item
)
=>
item
.
value
!==
val
)
.
filter
((
item
)
=>
item
.
value
!==
val
)
?.
forEach
((
item1
)
=>
{
?.
forEach
((
item1
)
=>
{
// 清除集合搜索无用属性
// 清除集合搜索无用属性
...
@@ -475,6 +472,7 @@ const handleQuery = async () => {
...
@@ -475,6 +472,7 @@ const handleQuery = async () => {
const
resetQuery
=
()
=>
{
const
resetQuery
=
()
=>
{
queryFormRef
.
value
?.
resetFields
()
queryFormRef
.
value
?.
resetFields
()
queryParams
.
value
=
{
queryParams
.
value
=
{
pickUpVerifyCode
:
null
,
// 自提核销码
pageNo
:
1
,
// 页数
pageNo
:
1
,
// 页数
pageSize
:
10
,
// 每页显示数量
pageSize
:
10
,
// 每页显示数量
status
:
null
,
// 订单状态
status
:
null
,
// 订单状态
...
...
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