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
253401ac
authored
Nov 22, 2023
by
owen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
营销:适配商城装修组件【优惠券】
parent
1bb9df7b
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
436 additions
and
56 deletions
+436
-56
src/api/mall/promotion/coupon/couponTemplate.ts
+7
-0
src/components/DiyEditor/components/mobile/CouponCard/component.tsx
+78
-0
src/components/DiyEditor/components/mobile/CouponCard/config.ts
+47
-0
src/components/DiyEditor/components/mobile/CouponCard/index.vue
+142
-0
src/components/DiyEditor/components/mobile/CouponCard/property.vue
+104
-0
src/components/DiyEditor/components/mobile/ProductCard/config.ts
+1
-1
src/components/DiyEditor/components/mobile/ProductList/config.ts
+1
-1
src/components/DiyEditor/components/mobile/ProductList/index.vue
+20
-17
src/components/DiyEditor/util.ts
+6
-2
src/views/mall/product/comment/CommentForm.vue
+1
-1
src/views/mall/product/spu/components/SpuShowcase.vue
+16
-14
src/views/mall/product/spu/components/SpuTableSelect.vue
+8
-10
src/views/mall/promotion/coupon/components/CouponSelect.vue
+3
-7
src/views/mall/promotion/coupon/template/CouponTemplateForm.vue
+2
-3
No files found.
src/api/mall/promotion/coupon/couponTemplate.ts
View file @
253401ac
...
...
@@ -73,6 +73,13 @@ export function getCouponTemplatePage(params: PageParam) {
})
}
// 获得优惠劵模板分页
export
function
getCouponTemplateList
(
ids
:
number
[])
{
return
request
.
get
({
url
:
`/promotion/coupon-template/list?ids=
${
ids
}
`
})
}
// 导出优惠劵模板 Excel
export
function
exportCouponTemplateExcel
(
params
:
PageParam
)
{
return
request
.
get
({
...
...
src/components/DiyEditor/components/mobile/CouponCard/component.tsx
0 → 100644
View file @
253401ac
import
*
as
CouponTemplateApi
from
'@/api/mall/promotion/coupon/couponTemplate'
import
{
CouponTemplateValidityTypeEnum
,
PromotionDiscountTypeEnum
}
from
'@/utils/constants'
import
{
floatToFixed2
}
from
'@/utils'
import
{
formatDate
}
from
'@/utils/formatTime'
// 优惠值
export
const
CouponDiscount
=
defineComponent
({
name
:
'CouponDiscount'
,
props
:
{
coupon
:
{
type
:
CouponTemplateApi
.
CouponTemplateVO
}
},
setup
(
props
)
{
const
coupon
=
props
.
coupon
as
CouponTemplateApi
.
CouponTemplateVO
// 折扣
let
value
=
coupon
.
discountPercent
+
''
let
suffix
=
' 折'
// 满减
if
(
coupon
.
discountType
===
PromotionDiscountTypeEnum
.
PRICE
.
type
)
{
value
=
floatToFixed2
(
coupon
.
discountPrice
)
suffix
=
' 元'
}
return
()
=>
(
<
div
>
<
span
class=
{
'text-20px font-bold'
}
>
{
value
}
</
span
>
<
span
>
{
suffix
}
</
span
>
</
div
>
)
}
})
// 优惠描述
export
const
CouponDiscountDesc
=
defineComponent
({
name
:
'CouponDiscountDesc'
,
props
:
{
coupon
:
{
type
:
CouponTemplateApi
.
CouponTemplateVO
}
},
setup
(
props
)
{
const
coupon
=
props
.
coupon
as
CouponTemplateApi
.
CouponTemplateVO
// 使用条件
const
useCondition
=
coupon
.
usePrice
>
0
?
`满
${
floatToFixed2
(
coupon
.
usePrice
)}
元,`
:
''
// 优惠描述
const
discountDesc
=
coupon
.
discountType
===
PromotionDiscountTypeEnum
.
PRICE
.
type
?
`减
${
floatToFixed2
(
coupon
.
discountPrice
)}
元`
:
`打
${
coupon
.
discountPercent
}
折`
return
()
=>
(
<
div
>
<
span
>
{
useCondition
}
</
span
>
<
span
>
{
discountDesc
}
</
span
>
</
div
>
)
}
})
// 有效期
export
const
CouponValidTerm
=
defineComponent
({
name
:
'CouponValidTerm'
,
props
:
{
coupon
:
{
type
:
CouponTemplateApi
.
CouponTemplateVO
}
},
setup
(
props
)
{
const
coupon
=
props
.
coupon
as
CouponTemplateApi
.
CouponTemplateVO
const
text
=
coupon
.
validityType
===
CouponTemplateValidityTypeEnum
.
DATE
.
type
?
`有效期:
${
formatDate
(
coupon
.
validStartTime
,
'YYYY-MM-DD'
)}
至
${
formatDate
(
coupon
.
validEndTime
,
'YYYY-MM-DD'
)}
`
:
`领取后第
${
coupon
.
fixedStartTerm
}
-
${
coupon
.
fixedEndTerm
}
天内可用`
return
()
=>
<
div
>
{
text
}
</
div
>
}
})
src/components/DiyEditor/components/mobile/CouponCard/config.ts
0 → 100644
View file @
253401ac
import
{
ComponentStyle
,
DiyComponent
}
from
'@/components/DiyEditor/util'
/** 商品卡片属性 */
export
interface
CouponCardProperty
{
// 列数
columns
:
number
// 背景图
bgImg
:
string
// 文字颜色
textColor
:
string
// 按钮样式
button
:
{
// 颜色
color
:
string
// 背景颜色
bgColor
:
string
}
// 间距
space
:
number
// 优惠券编号列表
couponIds
:
number
[]
// 组件样式
style
:
ComponentStyle
}
// 定义组件
export
const
component
=
{
id
:
'CouponCard'
,
name
:
'优惠券'
,
icon
:
'ep:ticket'
,
property
:
{
columns
:
1
,
bgImg
:
''
,
textColor
:
'#E9B461'
,
button
:
{
color
:
'#434343'
,
bgColor
:
''
},
space
:
0
,
couponIds
:
[],
style
:
{
bgType
:
'color'
,
bgColor
:
''
,
marginBottom
:
8
}
as
ComponentStyle
}
}
as
DiyComponent
<
CouponCardProperty
>
src/components/DiyEditor/components/mobile/CouponCard/index.vue
0 → 100644
View file @
253401ac
<
template
>
<el-scrollbar
class=
"z-1 min-h-30px"
wrap-class=
"w-full"
ref=
"containerRef"
>
<div
class=
"flex flex-row text-12px"
:style=
"
{
gap: `${property.space}px`,
width: scrollbarWidth
}"
>
<div
class=
"box-content"
:style=
"
{
background: property.bgImg
? `url(${property.bgImg}) 100% center / 100% 100% no-repeat`
: '#fff',
width: `${couponWidth}px`,
color: property.textColor
}"
v-for="(coupon, index) in couponList"
:key="index"
>
<!-- 布局1:1列-->
<div
v-if=
"property.columns === 1"
class=
"m-l-16px flex flex-row justify-between p-8px"
>
<div
class=
"flex flex-col justify-evenly gap-4px"
>
<!-- 优惠值 -->
<CouponDiscount
:coupon=
"coupon"
/>
<!-- 优惠描述 -->
<CouponDiscountDesc
:coupon=
"coupon"
/>
<!-- 有效期 -->
<CouponValidTerm
:coupon=
"coupon"
/>
</div>
<div
class=
"flex flex-col justify-evenly"
>
<div
class=
"rounded-20px p-x-8px p-y-2px"
:style=
"
{
color: property.button.color,
background: property.button.bgColor
}"
>
立即领取
</div>
</div>
</div>
<!-- 布局2:2列-->
<div
v-else-if=
"property.columns === 2"
class=
"m-l-16px flex flex-row justify-between p-8px"
>
<div
class=
"flex flex-col justify-evenly gap-4px"
>
<!-- 优惠值 -->
<CouponDiscount
:coupon=
"coupon"
/>
<div>
{{
coupon
.
name
}}
</div>
</div>
<div
class=
"flex flex-col"
>
<div
class=
"h-full w-20px rounded-20px p-x-2px p-y-8px text-center"
:style=
"
{
color: property.button.color,
background: property.button.bgColor
}"
>
立即领取
</div>
</div>
</div>
<!-- 布局3:3列-->
<div
v-else
class=
"flex flex-col items-center justify-around gap-4px p-4px"
>
<!-- 优惠值 -->
<CouponDiscount
:coupon=
"coupon"
/>
<div>
{{
coupon
.
name
}}
</div>
<div
class=
"rounded-20px p-x-8px p-y-2px"
:style=
"
{
color: property.button.color,
background: property.button.bgColor
}"
>
立即领取
</div>
</div>
</div>
</div>
</el-scrollbar>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
CouponCardProperty
}
from
'./config'
import
*
as
CouponTemplateApi
from
'@/api/mall/promotion/coupon/couponTemplate'
import
{
CouponDiscount
}
from
'./component'
import
{
CouponDiscountDesc
,
CouponValidTerm
}
from
'@/components/DiyEditor/components/mobile/CouponCard/component'
/** 商品卡片 */
defineOptions
({
name
:
'CouponCard'
})
// 定义属性
const
props
=
defineProps
<
{
property
:
CouponCardProperty
}
>
()
// 商品列表
const
couponList
=
ref
<
CouponTemplateApi
.
CouponTemplateVO
[]
>
([])
watch
(
()
=>
props
.
property
.
couponIds
,
async
()
=>
{
if
(
props
.
property
.
couponIds
?.
length
>
0
)
{
couponList
.
value
=
await
CouponTemplateApi
.
getCouponTemplateList
(
props
.
property
.
couponIds
)
}
},
{
immediate
:
true
,
deep
:
true
}
)
// 手机宽度
const
phoneWidth
=
ref
(
375
)
// 容器
const
containerRef
=
ref
()
// 滚动条宽度
const
scrollbarWidth
=
ref
(
'100%'
)
// 优惠券的宽度
const
couponWidth
=
ref
(
375
)
// 计算布局参数
watch
(
()
=>
[
props
.
property
,
phoneWidth
,
couponList
.
value
.
length
],
()
=>
{
// 每列的宽度为:(总宽度 - 间距 * (列数 - 1))/ 列数
couponWidth
.
value
=
(
phoneWidth
.
value
*
0.95
-
props
.
property
.
space
*
(
props
.
property
.
columns
-
1
))
/
props
.
property
.
columns
// 显示滚动条
scrollbarWidth
.
value
=
`
${
couponWidth
.
value
*
couponList
.
value
.
length
+
props
.
property
.
space
*
(
couponList
.
value
.
length
-
1
)
}
px`
},
{
immediate
:
true
,
deep
:
true
}
)
onMounted
(()
=>
{
// 提取手机宽度
phoneWidth
.
value
=
containerRef
.
value
?.
wrapRef
?.
offsetWidth
||
375
})
</
script
>
<
style
scoped
lang=
"scss"
></
style
>
src/components/DiyEditor/components/mobile/CouponCard/property.vue
0 → 100644
View file @
253401ac
<
template
>
<ComponentContainerProperty
v-model=
"formData.style"
>
<el-form
label-width=
"80px"
:model=
"formData"
>
<el-card
header=
"优惠券列表"
class=
"property-group"
shadow=
"never"
>
<div
v-for=
"(coupon, index) in couponList"
:key=
"index"
class=
"flex items-center justify-between"
>
<el-text
size=
"large"
truncated
>
{{
coupon
.
name
}}
</el-text>
<el-text
type=
"info"
truncated
>
<span
v-if=
"coupon.usePrice > 0"
>
满
{{
floatToFixed2
(
coupon
.
usePrice
)
}}
元,
</span>
<span
v-if=
"coupon.discountType === PromotionDiscountTypeEnum.PRICE.type"
>
减
{{
floatToFixed2
(
coupon
.
discountPrice
)
}}
元
</span>
<span
v-else
>
打
{{
coupon
.
discountPercent
}}
折
</span>
</el-text>
</div>
<el-form-item
label-width=
"0"
>
<el-button
@
click=
"handleAddCoupon"
type=
"primary"
plain
class=
"m-t-8px w-full"
>
<Icon
icon=
"ep:plus"
class=
"mr-5px"
/>
添加
</el-button>
</el-form-item>
</el-card>
<el-card
header=
"优惠券样式"
class=
"property-group"
shadow=
"never"
>
<el-form-item
label=
"列数"
prop=
"type"
>
<el-radio-group
v-model=
"formData.columns"
>
<el-tooltip
class=
"item"
content=
"一列"
placement=
"bottom"
>
<el-radio-button
:label=
"1"
>
<Icon
icon=
"fluent:text-column-one-24-filled"
/>
</el-radio-button>
</el-tooltip>
<el-tooltip
class=
"item"
content=
"二列"
placement=
"bottom"
>
<el-radio-button
:label=
"2"
>
<Icon
icon=
"fluent:text-column-two-24-filled"
/>
</el-radio-button>
</el-tooltip>
<el-tooltip
class=
"item"
content=
"三列"
placement=
"bottom"
>
<el-radio-button
:label=
"3"
>
<Icon
icon=
"fluent:text-column-three-24-filled"
/>
</el-radio-button>
</el-tooltip>
</el-radio-group>
</el-form-item>
<el-form-item
label=
"背景图片"
prop=
"bgImg"
>
<UploadImg
v-model=
"formData.bgImg"
height=
"80px"
width=
"100%"
class=
"min-w-160px"
/>
</el-form-item>
<el-form-item
label=
"文字颜色"
prop=
"textColor"
>
<ColorInput
v-model=
"formData.textColor"
/>
</el-form-item>
<el-form-item
label=
"按钮背景"
prop=
"button.bgColor"
>
<ColorInput
v-model=
"formData.button.bgColor"
/>
</el-form-item>
<el-form-item
label=
"按钮文字"
prop=
"button.color"
>
<ColorInput
v-model=
"formData.button.color"
/>
</el-form-item>
<el-form-item
label=
"间隔"
prop=
"space"
>
<el-slider
v-model=
"formData.space"
:max=
"100"
:min=
"0"
show-input
input-size=
"small"
:show-input-controls=
"false"
/>
</el-form-item>
</el-card>
</el-form>
</ComponentContainerProperty>
<!-- 优惠券选择 -->
<CouponSelect
ref=
"couponSelectDialog"
v-model:multiple-selection=
"couponList"
/>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
CouponCardProperty
}
from
'./config'
import
{
usePropertyForm
}
from
'@/components/DiyEditor/util'
import
*
as
CouponTemplateApi
from
'@/api/mall/promotion/coupon/couponTemplate'
import
{
floatToFixed2
}
from
'@/utils'
import
{
PromotionDiscountTypeEnum
}
from
'@/utils/constants'
import
CouponSelect
from
'@/views/mall/promotion/coupon/components/CouponSelect.vue'
// 优惠券卡片属性面板
defineOptions
({
name
:
'CouponCardProperty'
})
const
props
=
defineProps
<
{
modelValue
:
CouponCardProperty
}
>
()
const
emit
=
defineEmits
([
'update:modelValue'
])
const
{
formData
}
=
usePropertyForm
(
props
.
modelValue
,
emit
)
// 优惠券列表
const
couponList
=
ref
<
CouponTemplateApi
.
CouponTemplateVO
[]
>
([])
const
couponSelectDialog
=
ref
()
// 添加优惠券
const
handleAddCoupon
=
()
=>
{
couponSelectDialog
.
value
.
open
()
}
watch
(
()
=>
couponList
.
value
,
()
=>
{
formData
.
value
.
couponIds
=
couponList
.
value
.
map
((
coupon
)
=>
coupon
.
id
)
}
)
</
script
>
<
style
scoped
lang=
"scss"
></
style
>
src/components/DiyEditor/components/mobile/ProductCard/config.ts
View file @
253401ac
...
...
@@ -62,7 +62,7 @@ export interface ProductCardFieldProperty {
export
const
component
=
{
id
:
'ProductCard'
,
name
:
'商品卡片'
,
icon
:
'
system-uicons:carousel
'
,
icon
:
'
fluent:text-column-two-left-24-filled
'
,
property
:
{
layoutType
:
'oneColBigImg'
,
fields
:
{
...
...
src/components/DiyEditor/components/mobile/ProductList/config.ts
View file @
253401ac
...
...
@@ -41,7 +41,7 @@ export interface ProductListFieldProperty {
export
const
component
=
{
id
:
'ProductList'
,
name
:
'商品栏'
,
icon
:
'
system-uicons:carousel
'
,
icon
:
'
fluent:text-column-two-24-filled
'
,
property
:
{
layoutType
:
'twoCol'
,
fields
:
{
...
...
src/components/DiyEditor/components/mobile/ProductList/index.vue
View file @
253401ac
<
template
>
<el-scrollbar
class=
"z-1 min-h-30px"
wrap-class=
"w-full"
ref=
"containerRef"
>
<!-- 商品网格 -->
<!-- 商品网格 -->
<div
class=
"grid overflow-x-auto"
:style=
"
{
gridGap: `${property.space}px`,
gridTemplateColumns,
width: scrollbarWidth
,
}"
width: scrollbarWidth
}"
>
<!-- 商品 -->
<div
...
...
@@ -63,11 +63,11 @@
</el-scrollbar>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
ProductListProperty
}
from
"./config"
import
*
as
ProductSpuApi
from
"@/api/mall/product/spu"
import
{
ProductListProperty
}
from
'./config'
import
*
as
ProductSpuApi
from
'@/api/mall/product/spu'
/** 商品卡片 */
defineOptions
({
name
:
"ProductList"
})
defineOptions
({
name
:
'ProductList'
})
// 定义属性
const
props
=
defineProps
<
{
property
:
ProductListProperty
}
>
()
// 商品列表
...
...
@@ -89,39 +89,42 @@ const containerRef = ref()
// 商品的列数
const
columns
=
ref
(
2
)
// 滚动条宽度
const
scrollbarWidth
=
ref
(
"100%"
)
const
scrollbarWidth
=
ref
(
'100%'
)
// 商品图大小
const
imageSize
=
ref
(
"0"
)
const
imageSize
=
ref
(
'0'
)
// 商品网络列数
const
gridTemplateColumns
=
ref
(
""
)
const
gridTemplateColumns
=
ref
(
''
)
// 计算布局参数
watch
(
()
=>
[
props
.
property
,
phoneWidth
,
spuList
.
value
.
length
],
()
=>
{
// 计算列数
columns
.
value
=
props
.
property
.
layoutType
===
"twoCol"
?
2
:
3
// 提取手机宽度
columns
.
value
=
props
.
property
.
layoutType
===
'twoCol'
?
2
:
3
// 每列的宽度为:(总宽度 - 间距 * (列数 - 1))/ 列数
const
productWidth
=
(
phoneWidth
.
value
-
props
.
property
.
space
*
(
columns
.
value
-
1
))
/
columns
.
value
const
productWidth
=
(
phoneWidth
.
value
-
props
.
property
.
space
*
(
columns
.
value
-
1
))
/
columns
.
value
// 商品图布局:2列时,左右布局 3列时,上下布局
imageSize
.
value
=
columns
.
value
===
2
?
"64px"
:
`
${
productWidth
}
px`
imageSize
.
value
=
columns
.
value
===
2
?
'64px'
:
`
${
productWidth
}
px`
// 根据布局类型,计算行数、列数
if
(
props
.
property
.
layoutType
===
"horizSwiper"
)
{
if
(
props
.
property
.
layoutType
===
'horizSwiper'
)
{
// 单行显示
gridTemplateColumns
.
value
=
`repeat(auto-fill,
${
productWidth
}
px)`
// 显示滚动条
scrollbarWidth
.
value
=
`
${
productWidth
*
spuList
.
value
.
length
+
props
.
property
.
space
*
(
spuList
.
value
.
length
-
1
)}
px`
scrollbarWidth
.
value
=
`
${
productWidth
*
spuList
.
value
.
length
+
props
.
property
.
space
*
(
spuList
.
value
.
length
-
1
)
}
px`
}
else
{
// 指定列数
gridTemplateColumns
.
value
=
`repeat(
${
columns
.
value
}
, auto)`
// 不滚动
scrollbarWidth
.
value
=
"100%"
scrollbarWidth
.
value
=
'100%'
}
},
{
immediate
:
true
,
deep
:
true
}
)
onMounted
(()
=>
{
phoneWidth
.
value
=
containerRef
.
value
?.
wrapRef
?.
offsetWidth
||
375
;
// 提取手机宽度
phoneWidth
.
value
=
containerRef
.
value
?.
wrapRef
?.
offsetWidth
||
375
})
</
script
>
...
...
src/components/DiyEditor/util.ts
View file @
253401ac
...
...
@@ -111,7 +111,11 @@ export const PAGE_LIBS = [
{
name
:
'会员组件'
,
extended
:
true
,
components
:
[
'UserCard'
,
'
OrderCard'
,
'WalletCard'
,
'CouponCard
'
]
components
:
[
'UserCard'
,
'
UserOrder'
,
'UserWallet'
,
'UserCoupon
'
]
},
{
name
:
'营销组件'
,
extended
:
true
,
components
:
[
'Combination'
,
'Seckill'
,
'Point'
,
'Coupon'
]
}
{
name
:
'营销组件'
,
extended
:
true
,
components
:
[
'CombinationCard'
,
'SeckillCard'
,
'PointCard'
,
'CouponCard'
]
}
]
as
DiyComponentLibrary
[]
src/views/mall/product/comment/CommentForm.vue
View file @
253401ac
...
...
@@ -48,7 +48,7 @@
</template>
<
script
setup
lang=
"ts"
>
import
*
as
CommentApi
from
'@/api/mall/product/comment'
import
SpuShowcase
from
"@/views/mall/product/spu/components/SpuShowcase.vue"
;
import
SpuShowcase
from
'@/views/mall/product/spu/components/SpuShowcase.vue'
import
*
as
ProductSpuApi
from
'@/api/mall/product/spu'
import
SkuTableSelect
from
'@/views/mall/product/spu/components/SkuTableSelect.vue'
...
...
src/views/mall/product/spu/components/SpuShowcase.vue
View file @
253401ac
...
...
@@ -27,7 +27,7 @@ import * as ProductSpuApi from '@/api/mall/product/spu'
import
SpuTableSelect
from
'@/views/mall/product/spu/components/SpuTableSelect.vue'
import
{
propTypes
}
from
'@/utils/propTypes'
import
{
oneOfType
}
from
'vue-types'
import
{
isArray
}
from
"@/utils/is"
;
import
{
isArray
}
from
'@/utils/is'
// 商品橱窗,一般用于与商品建立关系时使用
// 提供功能:展示商品列表、添加商品、移除商品
...
...
@@ -43,9 +43,9 @@ const props = defineProps({
// 计算是否可以添加
const
canAdd
=
computed
(()
=>
{
// 情况一:禁用时不可以添加
if
(
props
.
disabled
)
return
false
if
(
props
.
disabled
)
return
false
// 情况二:未指定限制数量时,可以添加
if
(
!
props
.
limit
)
return
true
if
(
!
props
.
limit
)
return
true
// 情况三:检查已添加数量是否小于限制数量
return
productSpus
.
value
.
length
<
props
.
limit
})
...
...
@@ -57,20 +57,19 @@ watch(
()
=>
props
.
modelValue
,
async
()
=>
{
const
ids
=
isArray
(
props
.
modelValue
)
// 情况一:多选
?
props
.
modelValue
// 情况二:单选
:
props
.
modelValue
?
[
props
.
modelValue
]:
[]
?
// 情况一:多选
props
.
modelValue
:
// 情况二:单选
props
.
modelValue
?
[
props
.
modelValue
]
:
[]
// 不需要返显
if
(
ids
.
length
===
0
)
{
if
(
ids
.
length
===
0
)
{
productSpus
.
value
=
[]
return
}
// 只有商品发生变化之后,才去查询商品
if
(
productSpus
.
value
.
length
===
0
||
productSpus
.
value
.
some
((
spu
)
=>
!
ids
.
includes
(
spu
.
id
!
))
)
{
if
(
productSpus
.
value
.
length
===
0
||
productSpus
.
value
.
some
((
spu
)
=>
!
ids
.
includes
(
spu
.
id
!
)))
{
productSpus
.
value
=
await
ProductSpuApi
.
getSpuDetailList
(
ids
)
}
},
...
...
@@ -103,12 +102,15 @@ const handleRemoveSpu = (index: number) => {
}
const
emit
=
defineEmits
([
'update:modelValue'
,
'change'
])
const
emitSpuChange
=
()
=>
{
if
(
props
.
limit
===
1
)
{
if
(
props
.
limit
===
1
)
{
const
spu
=
productSpus
.
value
.
length
>
0
?
productSpus
.
value
[
0
]
:
null
emit
(
'update:modelValue'
,
spu
?.
id
||
0
)
emit
(
'change'
,
spu
)
}
else
{
emit
(
'update:modelValue'
,
productSpus
.
value
.
map
((
spu
)
=>
spu
.
id
))
emit
(
'update:modelValue'
,
productSpus
.
value
.
map
((
spu
)
=>
spu
.
id
)
)
emit
(
'change'
,
productSpus
.
value
)
}
}
...
...
src/views/mall/product/spu/components/SpuTableSelect.vue
View file @
253401ac
...
...
@@ -167,7 +167,7 @@ const open = (spuList?: Spu[]) => {
// 处理已选中
if
(
spuList
&&
spuList
.
length
>
0
)
{
checkedSpus
.
value
=
[...
spuList
]
checkedStatus
.
value
=
Object
.
fromEntries
(
spuList
.
map
(
spu
=>
[
spu
.
id
,
true
]))
checkedStatus
.
value
=
Object
.
fromEntries
(
spuList
.
map
(
(
spu
)
=>
[
spu
.
id
,
true
]))
}
dialogVisible
.
value
=
true
...
...
@@ -184,7 +184,9 @@ const getList = async () => {
list
.
value
=
data
.
list
total
.
value
=
data
.
total
// checkbox绑定undefined会有问题,需要给一个bool值
list
.
value
.
forEach
(
spu
=>
checkedStatus
.
value
[
spu
.
id
]
=
checkedStatus
.
value
[
spu
.
id
]
||
false
)
list
.
value
.
forEach
(
(
spu
)
=>
(
checkedStatus
.
value
[
spu
.
id
]
=
checkedStatus
.
value
[
spu
.
id
]
||
false
)
)
// 计算全选框状态
calculateIsCheckAll
()
}
finally
{
...
...
@@ -272,23 +274,19 @@ const handleCheckOne = (checked: boolean, spu: Spu, isCalcCheckAll: boolean) =>
}
// 计算全选框状态
if
(
isCalcCheckAll
)
{
if
(
isCalcCheckAll
)
{
calculateIsCheckAll
()
}
}
// 查找商品在已选中商品列表中的索引
const
findCheckedIndex
=
(
spu
:
Spu
)
=>
checkedSpus
.
value
.
findIndex
(
item
=>
item
.
id
===
spu
.
id
)
const
findCheckedIndex
=
(
spu
:
Spu
)
=>
checkedSpus
.
value
.
findIndex
(
(
item
)
=>
item
.
id
===
spu
.
id
)
// 计算全选框状态
const
calculateIsCheckAll
=
()
=>
{
isCheckAll
.
value
=
list
.
value
.
every
(
spu
=>
{
let
valueElement
=
checkedStatus
.
value
[
spu
.
id
];
debugger
return
valueElement
;
});
isCheckAll
.
value
=
list
.
value
.
every
((
spu
)
=>
checkedStatus
.
value
[
spu
.
id
])
// 计算中间状态:不是全部选中 && 任意一个选中
isIndeterminate
.
value
=
!
isCheckAll
.
value
&&
list
.
value
.
some
(
spu
=>
checkedStatus
.
value
[
spu
.
id
])
isIndeterminate
.
value
=
!
isCheckAll
.
value
&&
list
.
value
.
some
(
(
spu
)
=>
checkedStatus
.
value
[
spu
.
id
])
}
// 分类列表
...
...
src/views/mall/promotion/coupon/components/CouponSelect.vue
View file @
253401ac
...
...
@@ -150,15 +150,14 @@ import {
}
from
'@/views/mall/promotion/coupon/formatter'
import
{
dateFormatter
}
from
'@/utils/formatTime'
import
*
as
CouponTemplateApi
from
'@/api/mall/promotion/coupon/couponTemplate'
import
type
{
GiveCouponTemplate
}
from
'@/api/mall/product/spu'
defineOptions
({
name
:
'CouponSelect'
})
defineProps
<
{
multipleSelection
:
GiveCouponTemplate
[]
multipleSelection
:
CouponTemplateApi
.
CouponTemplateVO
[]
}
>
()
const
emit
=
defineEmits
<
{
(
e
:
'update:multipleSelection'
,
v
:
GiveCouponTemplate
[])
(
e
:
'update:multipleSelection'
,
v
:
CouponTemplateApi
.
CouponTemplateVO
[])
}
>
()
const
dialogVisible
=
ref
(
false
)
// 弹窗的是否展示
const
dialogTitle
=
ref
(
'选择优惠卷'
)
// 弹窗的标题
...
...
@@ -210,10 +209,7 @@ const open = async () => {
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
const
handleSelectionChange
=
(
val
:
CouponTemplateApi
.
CouponTemplateVO
[])
=>
{
emit
(
'update:multipleSelection'
,
val
.
map
((
item
)
=>
({
id
:
item
.
id
,
name
:
item
.
name
}))
)
emit
(
'update:multipleSelection'
,
val
)
}
const
submitForm
=
()
=>
{
...
...
src/views/mall/promotion/coupon/template/CouponTemplateForm.vue
View file @
253401ac
...
...
@@ -187,7 +187,7 @@ import {
PromotionDiscountTypeEnum
,
PromotionProductScopeEnum
}
from
'@/utils/constants'
import
SpuShowcase
from
"@/views/mall/product/spu/components/SpuShowcase.vue"
;
import
SpuShowcase
from
'@/views/mall/product/spu/components/SpuShowcase.vue'
import
ProductCategorySelect
from
'@/views/mall/product/category/components/ProductCategorySelect.vue'
import
{
convertToInteger
,
formatToFraction
}
from
'@/utils'
...
...
@@ -385,5 +385,4 @@ function setProductScopeValues(data: CouponTemplateApi.CouponTemplateVO) {
}
</
script
>
<
style
lang=
"scss"
scoped
>
</
style
>
<
style
lang=
"scss"
scoped
></
style
>
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