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
f07c74d8
authored
Sep 09, 2024
by
YunaiV
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/dev' into dev
parents
e5ec8201
1bd853bb
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
85 additions
and
47 deletions
+85
-47
src/views/mall/product/spu/components/SkuList.vue
+5
-5
src/views/mall/promotion/components/SpuAndSkuList.vue
+9
-9
src/views/mall/promotion/discountActivity/DiscountActivityForm.vue
+71
-33
No files found.
src/views/mall/product/spu/components/SkuList.vue
View file @
f07c74d8
...
@@ -180,17 +180,17 @@
...
@@ -180,17 +180,17 @@
</el-table-column>
</el-table-column>
<el-table-column
align=
"center"
label=
"销售价(元)"
min-width=
"80"
>
<el-table-column
align=
"center"
label=
"销售价(元)"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
<
template
#
default=
"{ row }"
>
{{
formatToFraction
(
row
.
price
)
}}
{{
row
.
price
}}
</
template
>
</
template
>
</el-table-column>
</el-table-column>
<el-table-column
align=
"center"
label=
"市场价(元)"
min-width=
"80"
>
<el-table-column
align=
"center"
label=
"市场价(元)"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
<
template
#
default=
"{ row }"
>
{{
formatToFraction
(
row
.
marketPrice
)
}}
{{
row
.
marketPrice
}}
</
template
>
</
template
>
</el-table-column>
</el-table-column>
<el-table-column
align=
"center"
label=
"成本价(元)"
min-width=
"80"
>
<el-table-column
align=
"center"
label=
"成本价(元)"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
<
template
#
default=
"{ row }"
>
{{
formatToFraction
(
row
.
costPrice
)
}}
{{
row
.
costPrice
}}
</
template
>
</
template
>
</el-table-column>
</el-table-column>
<el-table-column
align=
"center"
label=
"库存"
min-width=
"80"
>
<el-table-column
align=
"center"
label=
"库存"
min-width=
"80"
>
...
@@ -211,12 +211,12 @@
...
@@ -211,12 +211,12 @@
<
template
v-if=
"formData!.subCommissionType"
>
<
template
v-if=
"formData!.subCommissionType"
>
<el-table-column
align=
"center"
label=
"一级返佣(元)"
min-width=
"80"
>
<el-table-column
align=
"center"
label=
"一级返佣(元)"
min-width=
"80"
>
<template
#
default=
"
{ row }">
<template
#
default=
"
{ row }">
{{
formatToFraction
(
row
.
firstBrokeragePrice
)
}}
{{
row
.
firstBrokeragePrice
}}
</
template
>
</
template
>
</el-table-column>
</el-table-column>
<el-table-column
align=
"center"
label=
"二级返佣(元)"
min-width=
"80"
>
<el-table-column
align=
"center"
label=
"二级返佣(元)"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
<
template
#
default=
"{ row }"
>
{{
formatToFraction
(
row
.
secondBrokeragePrice
)
}}
{{
row
.
secondBrokeragePrice
}}
</
template
>
</
template
>
</el-table-column>
</el-table-column>
</template>
</template>
...
...
src/views/mall/promotion/components/SpuAndSkuList.vue
View file @
f07c74d8
...
@@ -30,13 +30,13 @@
...
@@ -30,13 +30,13 @@
<el-table-column
align=
"center"
label=
"销量"
min-width=
"90"
prop=
"salesCount"
/>
<el-table-column
align=
"center"
label=
"销量"
min-width=
"90"
prop=
"salesCount"
/>
<el-table-column
align=
"center"
label=
"库存"
min-width=
"90"
prop=
"stock"
/>
<el-table-column
align=
"center"
label=
"库存"
min-width=
"90"
prop=
"stock"
/>
<el-table-column
<el-table-column
v-if=
"spuData.length > 1 &&
isDelet
e"
v-if=
"spuData.length > 1 &&
deletabl
e"
align=
"center"
align=
"center"
label=
"操作"
label=
"操作"
min-width=
"90"
min-width=
"90"
>
>
<
template
#
default=
"scope"
>
<
template
#
default=
"scope"
>
<el-button
type=
"primary"
link
@
click=
"deleteSpu(scope.row.id)"
>
删除
</el-button>
<el-button
link
type=
"primary"
@
click=
"deleteSpu(scope.row.id)"
>
删除
</el-button>
</
template
>
</
template
>
</el-table-column>
</el-table-column>
</el-table>
</el-table>
...
@@ -56,13 +56,13 @@ const props = defineProps<{
...
@@ -56,13 +56,13 @@ const props = defineProps<{
spuList
:
T
[]
spuList
:
T
[]
ruleConfig
:
RuleConfig
[]
ruleConfig
:
RuleConfig
[]
spuPropertyListP
:
SpuProperty
<
T
>
[]
spuPropertyListP
:
SpuProperty
<
T
>
[]
isDelete
?:
boolean
// SPU 是否可删除;TODO deletable 换成这个名字好点。
deletable
?:
boolean
// SPU 是否可删除;
}
>
()
}
>
()
const
spuData
=
ref
<
Spu
[]
>
([])
// spu 详情数据列表
const
spuData
=
ref
<
Spu
[]
>
([])
// spu 详情数据列表
const
skuListRef
=
ref
()
// 商品属性列表Ref
const
skuListRef
=
ref
()
// 商品属性列表Ref
const
spuPropertyList
=
ref
<
SpuProperty
<
T
>
[]
>
([])
// spuId 对应的 sku 的属性列表
const
spuPropertyList
=
ref
<
SpuProperty
<
T
>
[]
>
([])
// spuId 对应的 sku 的属性列表
const
expandRowKeys
=
ref
<
number
[]
>
(
)
// 控制展开行需要设置 row-key 属性才能使用,该属性为展开行的 keys 数组。
const
expandRowKeys
=
ref
<
string
[]
>
([]
)
// 控制展开行需要设置 row-key 属性才能使用,该属性为展开行的 keys 数组。
/**
/**
* 获取所有 sku 活动配置
* 获取所有 sku 活动配置
...
@@ -71,10 +71,10 @@ const expandRowKeys = ref<number[]>() // 控制展开行需要设置 row-key 属
...
@@ -71,10 +71,10 @@ const expandRowKeys = ref<number[]>() // 控制展开行需要设置 row-key 属
*/
*/
const
getSkuConfigs
=
(
extendedAttribute
:
string
)
=>
{
const
getSkuConfigs
=
(
extendedAttribute
:
string
)
=>
{
skuListRef
.
value
.
validateSku
()
skuListRef
.
value
.
validateSku
()
const
seckillProducts
=
[]
const
seckillProducts
:
any
[]
=
[]
spuPropertyList
.
value
.
forEach
((
item
)
=>
{
spuPropertyList
.
value
.
forEach
((
item
)
=>
{
item
.
spuDetail
.
skus
.
forEach
((
sku
)
=>
{
item
.
spuDetail
.
skus
?.
forEach
((
sku
:
any
)
=>
{
seckillProducts
.
push
(
sku
[
extendedAttribute
])
seckillProducts
.
push
(
sku
[
extendedAttribute
]
as
any
)
})
})
})
})
return
seckillProducts
return
seckillProducts
...
@@ -124,10 +124,10 @@ watch(
...
@@ -124,10 +124,10 @@ watch(
()
=>
props
.
spuPropertyListP
,
()
=>
props
.
spuPropertyListP
,
(
data
)
=>
{
(
data
)
=>
{
if
(
!
data
)
return
if
(
!
data
)
return
spuPropertyList
.
value
=
data
as
SpuProperty
<
T
>
[]
spuPropertyList
.
value
=
data
as
SpuProperty
<
T
>
[]
as
any
// 解决如果之前选择的是单规格 spu 的话后面选择多规格 sku 多规格属性信息不展示的问题。解决方法:让 SkuList 组件重新渲染(行折叠会干掉包含的组件展开时会重新加载)
// 解决如果之前选择的是单规格 spu 的话后面选择多规格 sku 多规格属性信息不展示的问题。解决方法:让 SkuList 组件重新渲染(行折叠会干掉包含的组件展开时会重新加载)
setTimeout
(()
=>
{
setTimeout
(()
=>
{
expandRowKeys
.
value
=
data
.
map
((
item
)
=>
item
.
spuId
)
expandRowKeys
.
value
=
data
.
map
((
item
)
=>
item
.
spuId
+
''
)
},
200
)
},
200
)
},
},
{
{
...
...
src/views/mall/promotion/discountActivity/DiscountActivityForm.vue
View file @
f07c74d8
...
@@ -8,28 +8,40 @@
...
@@ -8,28 +8,40 @@
:schema=
"allSchemas.formSchema"
:schema=
"allSchemas.formSchema"
>
>
<!-- 先选择 -->
<!-- 先选择 -->
<!-- TODO @zhangshuai:商品允许选择多个 -->
<!-- TODO @zhangshuai:选择后的 SKU,需要后面加个【删除】按钮 -->
<!-- TODO @zhangshuai:展示的金额,貌似不对,大了 100 倍,需要看下 -->
<!-- TODO @zhangshuai:“优惠类型”,是每个 SKU 可以自定义已设置哈。因为每个商品 SKU 的折扣和减少价格,可能不同。具体交互,可以注册一个 youzan.com 看看;它的交互方式是,如果设置了“优惠金额”,则算“减价”;如果再次设置了“折扣百分比”,就算“打折”;这样形成一个互斥的优惠类型 -->
<template
#
spuId
>
<template
#
spuId
>
<el-button
@
click=
"spuSelectRef.open()"
>
选择商品
</el-button>
<el-button
@
click=
"spuSelectRef.open()"
>
选择商品
</el-button>
<SpuAndSkuList
<SpuAndSkuList
ref=
"spuAndSkuListRef"
ref=
"spuAndSkuListRef"
:deletable=
"true"
:rule-config=
"ruleConfig"
:rule-config=
"ruleConfig"
:spu-list=
"spuList"
:spu-list=
"spuList"
:spu-property-list-p=
"spuPropertyList"
:spu-property-list-p=
"spuPropertyList"
:isDelete=
"true"
@
delete=
"deleteSpu"
@
delete=
"deleteSpu"
>
>
<el-table-column
align=
"center"
label=
"优惠金额"
min-width=
"168"
>
<el-table-column
align=
"center"
label=
"优惠金额"
min-width=
"168"
>
<template
#
default=
"
{ row: sku }">
<template
#
default=
"
{ row }">
<el-input-number
v-model=
"sku.productConfig.discountPrice"
:min=
"0"
class=
"w-100%"
/>
<el-input-number
v-model=
"row.productConfig.discountPrice"
:max=
"parseFloat(fenToYuan(row.price))"
:min=
"0"
:precision=
"2"
:step=
"0.1"
class=
"w-100%"
@
change=
"handleSkuDiscountPriceChange(row)"
/>
</
template
>
</
template
>
</el-table-column>
</el-table-column>
<el-table-column
align=
"center"
label=
"折扣百分比(%)"
min-width=
"168"
>
<el-table-column
align=
"center"
label=
"折扣百分比(%)"
min-width=
"168"
>
<
template
#
default=
"{ row: sku }"
>
<
template
#
default=
"{ row }"
>
<el-input-number
v-model=
"sku.productConfig.discountPercent"
class=
"w-100%"
/>
<el-input-number
v-model=
"row.productConfig.discountPercent"
:max=
"100"
:min=
"0"
:precision=
"2"
:step=
"0.1"
class=
"w-100%"
@
change=
"handleSkuDiscountPercentChange(row)"
/>
</
template
>
</
template
>
</el-table-column>
</el-table-column>
</SpuAndSkuList>
</SpuAndSkuList>
...
@@ -45,11 +57,12 @@
...
@@ -45,11 +57,12 @@
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts"
setup
>
import
{
SpuAndSkuList
,
SpuProperty
,
SpuSelect
}
from
'../components'
import
{
SpuAndSkuList
,
SpuProperty
,
SpuSelect
}
from
'../components'
import
{
allSchemas
,
rules
}
from
'./discountActivity.data'
import
{
allSchemas
,
rules
}
from
'./discountActivity.data'
import
{
cloneDeep
}
from
'lodash-es'
import
{
cloneDeep
,
debounce
}
from
'lodash-es'
import
*
as
DiscountActivityApi
from
'@/api/mall/promotion/discount/discountActivity'
import
*
as
DiscountActivityApi
from
'@/api/mall/promotion/discount/discountActivity'
import
*
as
ProductSpuApi
from
'@/api/mall/product/spu'
import
*
as
ProductSpuApi
from
'@/api/mall/product/spu'
import
{
getPropertyList
,
RuleConfig
}
from
'@/views/mall/product/spu/components'
import
{
getPropertyList
,
RuleConfig
}
from
'@/views/mall/product/spu/components'
import
{
formatToFraction
}
from
'@/utils'
import
{
convertToInteger
,
erpCalculatePercentage
,
fenToYuan
,
yuanToFen
}
from
'@/utils'
import
{
PromotionDiscountTypeEnum
}
from
'@/utils/constants'
defineOptions
({
name
:
'PromotionDiscountActivityForm'
})
defineOptions
({
name
:
'PromotionDiscountActivityForm'
})
...
@@ -65,11 +78,19 @@ const formRef = ref() // 表单 Ref
...
@@ -65,11 +78,19 @@ const formRef = ref() // 表单 Ref
const
spuSelectRef
=
ref
()
// 商品和属性选择 Ref
const
spuSelectRef
=
ref
()
// 商品和属性选择 Ref
const
spuAndSkuListRef
=
ref
()
// sku 限时折扣 配置组件Ref
const
spuAndSkuListRef
=
ref
()
// sku 限时折扣 配置组件Ref
const
ruleConfig
:
RuleConfig
[]
=
[]
const
ruleConfig
:
RuleConfig
[]
=
[
{
name
:
'productConfig.discountPrice'
,
rule
:
(
arg
)
=>
arg
>
0
,
message
:
'商品优惠金额不能为 0 !!!'
}
]
const
spuList
=
ref
<
DiscountActivityApi
.
SpuExtension
[]
>
([])
// 选择的 spu
const
spuList
=
ref
<
DiscountActivityApi
.
SpuExtension
[]
>
([])
// 选择的 spu
const
spuPropertyList
=
ref
<
SpuProperty
<
DiscountActivityApi
.
SpuExtension
>
[]
>
([])
const
spuPropertyList
=
ref
<
SpuProperty
<
DiscountActivityApi
.
SpuExtension
>
[]
>
([])
const
spuIds
=
ref
<
number
[]
>
([])
const
spuIds
=
ref
<
number
[]
>
([])
const
selectSpu
=
(
spuId
:
number
,
skuIds
:
number
[])
=>
{
const
selectSpu
=
(
spuId
:
number
,
skuIds
:
number
[])
=>
{
// TODO puhui999: 艿艿现在限时折扣活动可以选择多个 spu ,那么 spuId 是不是得改成 spuIds 来存放多个?🤣
formRef
.
value
.
setValues
({
spuId
})
getSpuDetails
(
spuId
,
skuIds
)
getSpuDetails
(
spuId
,
skuIds
)
}
}
/**
/**
...
@@ -101,21 +122,20 @@ const getSpuDetails = async (
...
@@ -101,21 +122,20 @@ const getSpuDetails = async (
selectSkus
?.
forEach
((
sku
)
=>
{
selectSkus
?.
forEach
((
sku
)
=>
{
let
config
:
DiscountActivityApi
.
DiscountProductVO
=
{
let
config
:
DiscountActivityApi
.
DiscountProductVO
=
{
skuId
:
sku
.
id
!
,
skuId
:
sku
.
id
!
,
spuId
:
spu
.
id
,
spuId
:
spu
.
id
!
,
discountType
:
1
,
discountType
:
1
,
discountPercent
:
0
,
discountPercent
:
0
,
discountPrice
:
0
discountPrice
:
0
}
}
if
(
typeof
products
!==
'undefined'
)
{
if
(
typeof
products
!==
'undefined'
)
{
const
product
=
products
.
find
((
item
)
=>
item
.
skuId
===
sku
.
id
)
const
product
=
products
.
find
((
item
)
=>
item
.
skuId
===
sku
.
id
)
if
(
product
)
{
product
.
discountPercent
=
fenToYuan
(
product
.
discountPercent
)
as
any
product
.
discountPrice
=
fenToYuan
(
product
.
discountPrice
)
as
any
}
config
=
product
||
config
config
=
product
||
config
}
}
sku
.
productConfig
=
config
sku
.
productConfig
=
config
sku
.
price
=
formatToFraction
(
sku
.
price
)
sku
.
marketPrice
=
formatToFraction
(
sku
.
marketPrice
)
sku
.
costPrice
=
formatToFraction
(
sku
.
costPrice
)
sku
.
firstBrokeragePrice
=
formatToFraction
(
sku
.
firstBrokeragePrice
)
sku
.
secondBrokeragePrice
=
formatToFraction
(
sku
.
secondBrokeragePrice
)
})
})
spu
.
skus
=
selectSkus
as
DiscountActivityApi
.
SkuExtension
[]
spu
.
skus
=
selectSkus
as
DiscountActivityApi
.
SkuExtension
[]
spuPropertyList
.
value
.
push
({
spuPropertyList
.
value
.
push
({
...
@@ -168,25 +188,13 @@ const submitForm = async () => {
...
@@ -168,25 +188,13 @@ const submitForm = async () => {
// 提交请求
// 提交请求
formLoading
.
value
=
true
formLoading
.
value
=
true
try
{
try
{
const
data
=
formRef
.
value
.
formModel
as
DiscountActivityApi
.
DiscountActivityVO
// 获取折扣商品配置
// 获取折扣商品配置
const
products
=
cloneDeep
(
spuAndSkuListRef
.
value
.
getSkuConfigs
(
'productConfig'
))
const
products
=
cloneDeep
(
spuAndSkuListRef
.
value
.
getSkuConfigs
(
'productConfig'
))
// 校验优惠金额、折扣百分比,是否正确
// TODO @puhui999:这个交互,可以参考下 youzan 的
let
discountInvalid
=
false
products
.
forEach
((
item
:
DiscountActivityApi
.
DiscountProductVO
)
=>
{
products
.
forEach
((
item
:
DiscountActivityApi
.
DiscountProductVO
)
=>
{
if
(
item
.
discountPrice
!=
null
&&
item
.
discountPrice
>
0
)
{
item
.
discountPercent
=
convertToInteger
(
item
.
discountPercent
)
item
.
discountType
=
1
item
.
discountPrice
=
convertToInteger
(
item
.
discountPrice
)
}
else
if
(
item
.
discountPercent
!=
null
&&
item
.
discountPercent
>
0
)
{
item
.
discountType
=
2
}
else
{
discountInvalid
=
true
}
})
})
if
(
discountInvalid
)
{
const
data
=
cloneDeep
(
formRef
.
value
.
formModel
)
as
DiscountActivityApi
.
DiscountActivityVO
message
.
error
(
'优惠金额和折扣百分比需要填写一个'
)
return
}
data
.
products
=
products
data
.
products
=
products
// 真正提交
// 真正提交
if
(
formType
.
value
===
'create'
)
{
if
(
formType
.
value
===
'create'
)
{
...
@@ -204,6 +212,36 @@ const submitForm = async () => {
...
@@ -204,6 +212,36 @@ const submitForm = async () => {
}
}
}
}
/** 处理 sku 优惠金额变动 */
const
handleSkuDiscountPriceChange
=
debounce
((
row
:
any
)
=>
{
// 校验边界
if
(
row
.
productConfig
.
discountPrice
<=
0
)
{
return
}
// 设置优惠类型:满减
row
.
productConfig
.
discountType
=
PromotionDiscountTypeEnum
.
PRICE
.
type
// 设置折扣
row
.
productConfig
.
discountPercent
=
erpCalculatePercentage
(
row
.
price
-
yuanToFen
(
row
.
productConfig
.
discountPrice
),
row
.
price
)
},
200
)
/** 处理 sku 优惠折扣变动 */
const
handleSkuDiscountPercentChange
=
debounce
((
row
:
any
)
=>
{
// 校验边界
if
(
row
.
productConfig
.
discountPercent
<=
0
||
row
.
productConfig
.
discountPercent
>=
100
)
{
return
}
// 设置优惠类型:折扣
row
.
productConfig
.
discountType
=
PromotionDiscountTypeEnum
.
PERCENT
.
type
// 设置满减金额
row
.
productConfig
.
discountPrice
=
fenToYuan
(
row
.
price
-
row
.
price
*
(
row
.
productConfig
.
discountPercent
/
100.0
||
0
)
)
},
200
)
/** 重置表单 */
/** 重置表单 */
const
resetForm
=
async
()
=>
{
const
resetForm
=
async
()
=>
{
spuList
.
value
=
[]
spuList
.
value
=
[]
...
...
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