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
7e44b621
authored
Dec 01, 2023
by
owen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
营销:适配商城装修组件【秒杀】(待重写)
parent
b4ba1043
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
308 additions
and
1 deletions
+308
-1
src/components/DiyEditor/components/mobile/PromotionSeckill/config.ts
+64
-0
src/components/DiyEditor/components/mobile/PromotionSeckill/index.vue
+125
-0
src/components/DiyEditor/components/mobile/PromotionSeckill/property.vue
+112
-0
src/components/DiyEditor/util.ts
+7
-1
No files found.
src/components/DiyEditor/components/mobile/PromotionSeckill/config.ts
0 → 100644
View file @
7e44b621
import
{
ComponentStyle
,
DiyComponent
}
from
'@/components/DiyEditor/util'
/** 秒杀属性 */
export
interface
PromotionSeckillProperty
{
// 布局类型:单列 | 三列
layoutType
:
'oneCol'
|
'threeCol'
// 商品字段
fields
:
{
// 商品名称
name
:
PromotionSeckillFieldProperty
// 商品价格
price
:
PromotionSeckillFieldProperty
}
// 角标
badge
:
{
// 是否显示
show
:
boolean
// 角标图片
imgUrl
:
string
}
// 上圆角
borderRadiusTop
:
number
// 下圆角
borderRadiusBottom
:
number
// 间距
space
:
number
// 秒杀活动编号
activityId
:
number
// 组件样式
style
:
ComponentStyle
}
// 商品字段
export
interface
PromotionSeckillFieldProperty
{
// 是否显示
show
:
boolean
// 颜色
color
:
string
}
// 定义组件
export
const
component
=
{
id
:
'PromotionSeckill'
,
name
:
'秒杀'
,
icon
:
'mdi:calendar-time'
,
property
:
{
activityId
:
undefined
,
layoutType
:
'oneCol'
,
fields
:
{
name
:
{
show
:
true
,
color
:
'#000'
},
price
:
{
show
:
true
,
color
:
'#ff3000'
}
},
badge
:
{
show
:
false
,
imgUrl
:
''
},
borderRadiusTop
:
8
,
borderRadiusBottom
:
8
,
space
:
8
,
style
:
{
bgType
:
'color'
,
bgColor
:
''
,
marginLeft
:
8
,
marginRight
:
8
,
marginBottom
:
8
}
as
ComponentStyle
}
}
as
DiyComponent
<
PromotionSeckillProperty
>
src/components/DiyEditor/components/mobile/PromotionSeckill/index.vue
0 → 100644
View file @
7e44b621
<
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
}"
>
<!-- 商品 -->
<div
class=
"relative box-content flex flex-row flex-wrap overflow-hidden bg-white"
:style=
"
{
borderTopLeftRadius: `${property.borderRadiusTop}px`,
borderTopRightRadius: `${property.borderRadiusTop}px`,
borderBottomLeftRadius: `${property.borderRadiusBottom}px`,
borderBottomRightRadius: `${property.borderRadiusBottom}px`
}"
v-for="(spu, index) in spuList"
:key="index"
>
<!-- 角标 -->
<div
v-if=
"property.badge.show"
class=
"absolute left-0 top-0 z-1 items-center justify-center"
>
<el-image
fit=
"cover"
:src=
"property.badge.imgUrl"
class=
"h-26px w-38px"
/>
</div>
<!-- 商品封面图 -->
<el-image
fit=
"cover"
:src=
"spu.picUrl"
:style=
"
{ width: imageSize, height: imageSize }" />
<div
:class=
"[
'flex flex-col gap-8px p-8px box-border',
{
'w-[calc(100%-64px)]': columns === 2,
'w-full': columns === 3
}
]"
>
<!-- 商品名称 -->
<div
v-if=
"property.fields.name.show"
class=
"truncate text-12px"
:style=
"
{ color: property.fields.name.color }"
>
{{
spu
.
name
}}
</div>
<div>
<!-- 商品价格 -->
<span
v-if=
"property.fields.price.show"
class=
"text-12px"
:style=
"
{ color: property.fields.price.color }"
>
¥
{{
spu
.
price
}}
</span>
</div>
</div>
</div>
</div>
</el-scrollbar>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
PromotionSeckillProperty
}
from
'./config'
import
*
as
ProductSpuApi
from
'@/api/mall/product/spu'
import
*
as
SeckillActivityApi
from
'@/api/mall/promotion/seckill/seckillActivity'
/** 秒杀 */
defineOptions
({
name
:
'PromotionSeckill'
})
// 定义属性
const
props
=
defineProps
<
{
property
:
PromotionSeckillProperty
}
>
()
// 商品列表
const
spuList
=
ref
<
ProductSpuApi
.
Spu
[]
>
([])
watch
(
()
=>
props
.
property
.
activityId
,
async
()
=>
{
if
(
!
props
.
property
.
activityId
)
return
const
activity
=
await
SeckillActivityApi
.
getSeckillActivity
(
props
.
property
.
activityId
)
if
(
!
activity
?.
spuId
)
return
spuList
.
value
=
[
await
ProductSpuApi
.
getSpu
(
activity
.
spuId
)]
},
{
immediate
:
true
,
deep
:
true
}
)
// 手机宽度
const
phoneWidth
=
ref
(
375
)
// 容器
const
containerRef
=
ref
()
// 商品的列数
const
columns
=
ref
(
2
)
// 滚动条宽度
const
scrollbarWidth
=
ref
(
'100%'
)
// 商品图大小
const
imageSize
=
ref
(
'0'
)
// 商品网络列数
const
gridTemplateColumns
=
ref
(
''
)
// 计算布局参数
watch
(
()
=>
[
props
.
property
,
phoneWidth
,
spuList
.
value
.
length
],
()
=>
{
// 计算列数
columns
.
value
=
props
.
property
.
layoutType
===
'oneCol'
?
1
:
3
// 每列的宽度为:(总宽度 - 间距 * (列数 - 1))/ 列数
const
productWidth
=
(
phoneWidth
.
value
-
props
.
property
.
space
*
(
columns
.
value
-
1
))
/
columns
.
value
// 商品图布局:2列时,左右布局 3列时,上下布局
imageSize
.
value
=
columns
.
value
===
2
?
'64px'
:
`
${
productWidth
}
px`
// 指定列数
gridTemplateColumns
.
value
=
`repeat(
${
columns
.
value
}
, auto)`
// 不滚动
scrollbarWidth
.
value
=
'100%'
},
{
immediate
:
true
,
deep
:
true
}
)
onMounted
(()
=>
{
// 提取手机宽度
phoneWidth
.
value
=
containerRef
.
value
?.
wrapRef
?.
offsetWidth
||
375
})
</
script
>
<
style
scoped
lang=
"scss"
></
style
>
src/components/DiyEditor/components/mobile/PromotionSeckill/property.vue
0 → 100644
View file @
7e44b621
<
template
>
<ComponentContainerProperty
v-model=
"formData.style"
>
<el-form
label-width=
"80px"
:model=
"formData"
>
<el-card
header=
"秒杀活动"
class=
"property-group"
shadow=
"never"
>
<el-form-item
label=
"秒杀活动"
prop=
"activityId"
>
<el-select
v-model=
"formData.activityId"
>
<el-option
v-for=
"activity in activityList"
:key=
"activity.id"
:label=
"activity.name"
:value=
"activity.id"
/>
</el-select>
</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.layoutType"
>
<el-tooltip
class=
"item"
content=
"单列"
placement=
"bottom"
>
<el-radio-button
label=
"oneCol"
>
<Icon
icon=
"fluent:text-column-one-24-filled"
/>
</el-radio-button>
</el-tooltip>
<el-tooltip
class=
"item"
content=
"三列"
placement=
"bottom"
>
<el-radio-button
label=
"threeCol"
>
<Icon
icon=
"fluent:text-column-three-24-filled"
/>
</el-radio-button>
</el-tooltip>
</el-radio-group>
</el-form-item>
<el-form-item
label=
"商品名称"
prop=
"fields.name.show"
>
<div
class=
"flex gap-8px"
>
<ColorInput
v-model=
"formData.fields.name.color"
/>
<el-checkbox
v-model=
"formData.fields.name.show"
/>
</div>
</el-form-item>
<el-form-item
label=
"商品价格"
prop=
"fields.price.show"
>
<div
class=
"flex gap-8px"
>
<ColorInput
v-model=
"formData.fields.price.color"
/>
<el-checkbox
v-model=
"formData.fields.price.show"
/>
</div>
</el-form-item>
</el-card>
<el-card
header=
"角标"
class=
"property-group"
shadow=
"never"
>
<el-form-item
label=
"角标"
prop=
"badge.show"
>
<el-switch
v-model=
"formData.badge.show"
/>
</el-form-item>
<el-form-item
label=
"角标"
prop=
"badge.imgUrl"
v-if=
"formData.badge.show"
>
<UploadImg
v-model=
"formData.badge.imgUrl"
height=
"44px"
width=
"72px"
>
<template
#
tip
>
建议尺寸:36 * 22
</
template
>
</UploadImg>
</el-form-item>
</el-card>
<el-card
header=
"商品样式"
class=
"property-group"
shadow=
"never"
>
<el-form-item
label=
"上圆角"
prop=
"borderRadiusTop"
>
<el-slider
v-model=
"formData.borderRadiusTop"
:max=
"100"
:min=
"0"
show-input
input-size=
"small"
:show-input-controls=
"false"
/>
</el-form-item>
<el-form-item
label=
"下圆角"
prop=
"borderRadiusBottom"
>
<el-slider
v-model=
"formData.borderRadiusBottom"
:max=
"100"
:min=
"0"
show-input
input-size=
"small"
:show-input-controls=
"false"
/>
</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>
</template>
<
script
setup
lang=
"ts"
>
import
{
PromotionSeckillProperty
}
from
'./config'
import
{
usePropertyForm
}
from
'@/components/DiyEditor/util'
import
*
as
SeckillActivityApi
from
'@/api/mall/promotion/seckill/seckillActivity'
import
{
CommonStatusEnum
}
from
'@/utils/constants'
// 秒杀属性面板
defineOptions
({
name
:
'PromotionSeckillProperty'
})
const
props
=
defineProps
<
{
modelValue
:
PromotionSeckillProperty
}
>
()
const
emit
=
defineEmits
([
'update:modelValue'
])
const
{
formData
}
=
usePropertyForm
(
props
.
modelValue
,
emit
)
// 活动列表
const
activityList
=
ref
<
SeckillActivityApi
.
SeckillActivityVO
>
([])
onMounted
(
async
()
=>
{
const
{
list
}
=
await
SeckillActivityApi
.
getSeckillActivityPage
({
status
:
CommonStatusEnum
.
ENABLE
})
activityList
.
value
=
list
})
</
script
>
<
style
scoped
lang=
"scss"
></
style
>
src/components/DiyEditor/util.ts
View file @
7e44b621
...
@@ -116,6 +116,12 @@ export const PAGE_LIBS = [
...
@@ -116,6 +116,12 @@ export const PAGE_LIBS = [
{
{
name
:
'营销组件'
,
name
:
'营销组件'
,
extended
:
true
,
extended
:
true
,
components
:
[
'CombinationCard'
,
'SeckillCard'
,
'PointCard'
,
'CouponCard'
,
'PromotionArticle'
]
components
:
[
'PromotionCombination'
,
'PromotionSeckill'
,
'PromotionPoint'
,
'CouponCard'
,
'PromotionArticle'
]
}
}
]
as
DiyComponentLibrary
[]
]
as
DiyComponentLibrary
[]
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