Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mayi-mp-shop
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
程默
mayi-mp-shop
Commits
be7aa12c
Commit
be7aa12c
authored
Mar 10, 2021
by
李嘉林
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
拼团组件
parent
168e2e23
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
2461 additions
and
4 deletions
+2461
-4
src/components/activity/spellGroup/goodsItem.vue
+630
-0
src/components/activity/spellGroup/index.vue
+518
-0
src/components/activity/spellGroup/mixin/computed.js
+153
-0
src/components/content/information/articleItem.vue
+2
-2
src/pages/home/index.vue
+7
-1
src/pages/home/main.json
+2
-1
static/nativeComponents/spellGroup/GoodsItem/index.js
+140
-0
static/nativeComponents/spellGroup/GoodsItem/index.json
+6
-0
static/nativeComponents/spellGroup/GoodsItem/index.wxml
+164
-0
static/nativeComponents/spellGroup/GoodsItem/index.wxss
+364
-0
static/nativeComponents/spellGroup/heapItem/index.js
+107
-0
static/nativeComponents/spellGroup/heapItem/index.json
+6
-0
static/nativeComponents/spellGroup/heapItem/index.wxml
+22
-0
static/nativeComponents/spellGroup/heapItem/index.wxss
+79
-0
static/nativeComponents/spellGroup/heapItem/utils/touchEvent.js
+261
-0
No files found.
src/components/activity/spellGroup/goodsItem.vue
0 → 100644
View file @
be7aa12c
<
template
>
<div
class=
"goods-item-child"
:class=
"datas.componentData['borderColorShow']? 'itemBorder': ''"
:style=
"
{
'border-radius': getBorderRadius + 'em',
'border':'1px solid'+datas.componentData['borderColor'],
'--border_color': datas.componentData['borderColor'],
'box-shadow': datas.componentData['cardShadow']
? '0px 0px 5px ' +
datas.componentData['cardShadowSize'] +
'px #ccc'
: '',
}"
>
<div
class=
"imgBox slidebox1"
:style=
"
{'background-color':datas.componentData['backgroundColorShow']?datas.componentData['backgroundColor']:''}"
>
<div
class=
"have-group"
v-if=
"datas.componentData['haveGroupShow'] &&items &&items['groupBuyFlag'] =='1'"
>
{{
items
&&
items
[
"haveGroupNum"
]?
items
[
"haveGroupNum"
]:
"0"
}}
人已团
</div>
<div
class=
"goodsPicture"
v-if=
"items != null"
:style=
"
{ padding: datas.componentData.imgSize }"
>
<div
class=
"angleSign"
v-if=
"angleSign && angleSignImg"
:style=
"
{
width: angleSignSize + '%',
height: angleSignSize + '%',
}"
>
<image
:src=
"angleSignImg"
mode=
"widthFix"
></image>
</div>
<image
mode=
"widthFix"
:src=
"items['coverImage'] ==''? items['productImgUrl']: items['coverImage']"
lazy-load
></image>
<!-- items.oversoldFlag==0&&items.totalQty-0
<
=
0
--
>
<div
class=
"whiteBg"
v-if=
"items &&items.oversoldFlag ==0 &&items.totalQty - 0
<
=
0
"
>
<div
class=
"cover"
>
<!--
<p>
商品
</p>
<p>
售罄
</p>
-->
<image
mode=
"heightFix"
v-if=
"items&&items.oversoldFlag==0&&items.totalQty-0
<
=
0
"
src=
"http://mayi-newshop.oss-cn-shanghai.aliyuncs.com/public/png/f254fe62-6dda-46f6-a2f4-a7b2aa0474df.png"
alt
></image>
</div>
</div>
</div>
<!--
<img
v-if=
"items!=null"
:src=
"items['coverImage'] | DFSImg(400,400)"
alt
:style=
"
{'padding':datas.componentData.imgSize}"
/>-->
</div>
<div
:style=
"
{
'text-align': datas.componentData['initcharAlign'],
}"
class="info"
>
<div
class=
"info-top"
style=
"overflow: hidden;display: flex;justify-content: space-between;"
>
<p
class=
"name"
:style=
"
{color: datas.componentData['nameColor'],fontWeight: datas.componentData['nameFontWeight'],'font-size':datas.componentData['nameFontSize'] + 'em',height: '2.8em',}"
v-if="datas.componentData['nameShow']"
>
{{
items
!=
null
?
items
[
"productName"
]:
"名称"
}}
</p>
<div
v-if=
"datas.componentData['followerShow']"
class=
"follower-wrap my-hairline--left"
:style=
"
{
width:
datas.componentData.columnNum == 3 ? '3em' : '4em',
'padding-left':
datas.componentData.columnNum == 3 ? '0' : '0.8em',
}"
>
<div
class=
"follower-num"
:style=
"
{ color: followerColor }"
>
{{
items
!=
null
?
items
[
"totalCollectionCount"
]?
items
[
"totalCollectionCount"
]:
0
:
0
}}
</div>
<div
class=
"follower-text"
>
关注人数
</div>
</div>
</div>
<!--
<p
:style=
"
{'color':datas.componentData['describeColor'],'font-size':datas.componentData['describeFontSize']+'em'}"
v-if="datas.componentData['describeShow']
&&
items!=null
&&
items.specificationsName!=''"
>
{{
items
.
specificationsName
}}
</p>
-->
<p
style=
"overflow: hidden; color: #999"
>
<span
:style=
"
{ 'font-size': '0.7em' }"
v-if="datas.componentData['alSaleShow']"
>已售
{{
items
!=
null
?
items
[
"totalSalesCount"
]:
0
}}
件
</span
>
<span
:style=
"
{ 'font-size': '0.7em' }"
v-if="datas.componentData['alSaleShow']
&&
datas.componentData['collectShow']"
>/
</span
>
<span
:style=
"
{ 'font-size': '0.7em' }"
v-if="datas.componentData['collectShow']"
>
剩余
{{
items
!=
null
&&
items
[
"qty"
]
!=
undefined
?
items
[
"qty"
]
>
0
?
items
[
"qty"
]:
items
.
oversoldFlag
==
1
?
"数量充足"
:
"数量不足"
:
""
}}
<span
v-if=
"items != null &&(items['qty']? items['qty'] >= 0: items['saleQty'] >= 0)"
>
件
</span
>
</span>
</p>
<template
v-if=
"items != null"
>
<div
class=
"marketing flex"
v-if=
"marketingTag &&marketingStyle == 0 &&items.marketingTag"
>
<div
class=
"item"
v-for=
"(item1, index1) in datas.componentData.items.marketingTag"
:key=
"index1"
>
{{
item1
.
label
}}
</div>
</div>
</
template
>
<div
class=
"bottom"
>
<
template
v-if=
"goodsType != 1"
>
<!--
<div
v-if=
"vipPrice&&true"
class=
"vipPrice1 flex"
>
<div
class=
"vipIcon"
>
VIP
</div>
<div
class=
"right"
><span>
8.8
</span><span>
折
</span></div>
</div>
-->
<div
class=
"priceItem flex"
>
<p
class=
"price"
:style=
"
{color: datas.componentData['priceColor'],'font-size': datas.componentData['priceFontSize'] + 'em',}"
v-if="datas.componentData['priceShow']"
>
<template
v-if=
"items != null &&(items['groupBuyFlag'] == '0' ||items['groupBuyFlag'] == '1')"
>
<span>
¥
</span>
<span>
{{
items
!=
null
?
items
[
"goodsMinPrice"
]:
0
}}
</span>
</
template
>
<
template
v-if=
"items != null &&items['groupBuyFlag'] != '0' &&items['groupBuyFlag'] != '1'"
>
<span>
<span>
¥
</span>
{{
items
!=
null
?
items
[
"minPrice"
]:
0
}}
</span>
<del
style=
"font-size: 12px; color: #999"
v-if=
"items !=null &&datas.componentData['priceMarking'] &&items['minGoodsSuggestedRetailPrice'] &&items['minPrice'] -0
<items
['
minGoodsSuggestedRetailPrice
']
-0
&&
datas
.
componentData
['
columnNum
']
<
3
"
>
<span>
¥
</span>
<span>
{{
items
!=
null
?
items
[
"minGoodsSuggestedRetailPrice"
]:
0
}}
</span>
</del>
</
template
>
</p>
<div
v-if=
"vipPrice &&items != null"
class=
"vipPrice2 flex"
>
<p
class=
"left"
:style=
"{'font-size':datas.componentData['priceFontSize'] -0.1 +'em',}"
v-if=
"showVipPrice(index) == true"
>
<span>
¥
</span>
<span>
{{items["minPriceAfterRecommendedCardPriceTable"]}}
</span>
</p>
<div
class=
"vipIcon line-clamp1"
v-if=
"showVipTag(index) == true"
>
{{items["recommendedCardMinPricePriceTableName"]}}
</div>
</div>
</div>
</template>
<
template
v-else
>
<p
class=
"price"
:style=
"
{color: datas.componentData['priceColor'],'font-size':datas.componentData['priceFontSize'] + 'em',}"
v-if="datas.componentData['priceShow']"
>
<template
v-if=
"items != null"
>
<template
v-if=
"items['groupBuyFlag'] == '0' ||items['groupBuyFlag'] == '1'"
>
<span>
¥
</span>
<span>
{{
items
!=
null
?
items
[
"goodsMinPrice"
]:
0
}}
</span>
</
template
>
<
template
v-else
>
<span
v-if=
"items['exchangeIntegral'] &&items['exchangeIntegral'] > 0"
>
{{
items
!=
null
?
items
[
"exchangeIntegral"
]:
0
}}
积分
</span
>
<span
v-if=
"items['minPrice'] &&items['minPrice'] > 0 &&items['exchangeIntegral'] &&items['exchangeIntegral'] > 0"
>
+
</span
>
<template
v-if=
"items['minPrice'] &&items['minPrice'] > 0"
>
<span>
¥
</span>
<span>
{{
items
!=
null
?
items
[
"minPrice"
]:
0
}}
</span>
</
template
>
</template>
</template>
</p>
</template>
<
template
v-if=
"items != null &&items['minProductGoodsCommission'] &&items['minProductGoodsCommission'] -0 >0.01"
>
<div
class=
"showCommission"
:style=
"
{
color: commissionColor,
'border-color': commissionColor,
}"
v-if="datas.componentData.commissionStyle == 0"
>
<div
class=
"commission-box"
:style=
"
{ 'background-color': commissionBgColor }"
>
<span>
收益
</span>
<span>
¥
</span>
<span>
{{
items
[
"minProductGoodsCommission"
]
}}
</span>
</div>
</div>
</
template
>
<div
class=
"buy-now"
style=
"background-color: #aaa"
:style=
"{ 'font-size': getPayFontSize }"
v-if=
"items &&items.oversoldFlag ==0 &&items.totalQty - 0 <=0 &&datas.componentData['paynow']"
>
<span>
已售罄
</span>
</div>
<div
v-if=
"((items &&items.totalQty - 0 >0) ||(items &&items.oversoldFlag == 1)) &&datas.componentData['paynow']"
@
click
.
stop=
"
onclickBuynow(items)
"
>
<i
class=
"buy-now-icon"
:class=
"'iconfont-common' + btnIcon"
:style=
"{ color: btnColor }"
v-if=
"btnType < 6"
></i>
<div
class=
"buy-now"
v-else
:style=
"{
'background-color': btnColor,
'font-size': getPayFontSize,
}"
>
<span>
{{ btnTest }}
</span>
</div>
</div>
</div>
<
template
v-if=
"items != null"
>
<div
class=
"marketing flex"
v-if=
"marketingTag &&marketingStyle == 1 &&items.marketingTag"
>
<div
class=
"item"
v-for=
"(item1, index1) in datas.componentData.items.marketingTag"
:key=
"index1"
>
{{
item1
.
label
}}
</div>
</div>
</
template
>
<
template
v-if=
"items != null &&items['minProductGoodsCommission'] &&items['minProductGoodsCommission'] -0 >0.01"
>
<div
class=
"showCommissionTwo flex"
:style=
"
{
color: commissionColor,
'border-color': commissionColor,
}"
v-if="datas.componentData.commissionStyle == 1"
>
<div
class=
"commission-box"
:style=
"
{ 'background-color': commissionBgColor }"
>
<i
class=
"iconfont-common common-iconfenxiang"
></i>
<span>
赚
</span>
<span>
¥
</span>
<span
style=
"font-size: 16px"
>
{{
items
[
"minProductGoodsCommission"
]
}}
</span>
</div>
</div>
</
template
>
</div>
</div>
</template>
<
script
type=
"text/ecmascript-6"
>
import
mixin_computed
from
"./mixin/computed"
export
default
{
name
:
""
,
props
:[
'datas'
,
'items'
],
mixins
:
[
mixin_computed
],
data
()
{
return
{}
},
components
:
{},
computed
:
{},
created
()
{},
mounted
()
{},
methods
:
{}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.goods-item-child
{
position
:
relative
;
overflow
:
hidden
;
background
:
#ffffff
;
}
.itemBorder
{
border
:
1px
solid
var
(
--border_color
);
}
.imgBox
{
position
:
relative
;
overflow
:
hidden
;
width
:
100%
;
//
height
:
0
;
//
padding-bottom
:
100%
;
margin
:
0
auto
0.3em
;
img
{
display
:
block
;
width
:
100%
;
//
height
:
100%
;
//
position
:
absolute
;
//
margin
:
auto
;
//
top
:
-9999px
;
//
right
:
-9999px
;
//
bottom
:
-9999px
;
//
left
:
-9999px
;
}
.have-group
{
position
:
absolute
;
bottom
:
10px
;
left
:
6px
;
padding
:
4px
8px
;
background-color
:
rgba
(
0
,
0
,
0
,
0.6
);
color
:
white
;
font-size
:
12px
;
border-radius
:
4px
;
z-index
:
99
;
}
.goodsPicture
{
//
position
:
absolute
;
width
:
100%
;
height
:
100%
;
position
:
relative
;
box-sizing
:
border-box
;
.angleSign
{
position
:
absolute
;
top
:
0
;
left
:
0
;
image
{
height
:
100%
;
//
object-fit
:
contain
;
}
}
image
{
width
:
100%
;
}
img
{
width
:
100%
;
}
.whiteBg
{
position
:
absolute
;
top
:
0
;
left
:
0
;
right
:
0
;
bottom
:
0
;
background
:
rgba
(
#fff
,
0.7
);
.cover
{
position
:
absolute
;
top
:
20px
;
left
:
20px
;
right
:
20px
;
bottom
:
20px
;
display
:
flex
;
//
background
:
rgba
(
#333
,
0.6
);
//
justify-content
:
space-around
;
flex-direction
:
column
;
justify-content
:
center
;
align-items
:
center
;
border-radius
:
50%
;
//
background-image
:
url('../../../../../static/images/shouqing.png')
;
background-size
:
cover
;
image
{
width
:
100%
;
height
:
100%
;
}
p
{
//
font-size
:
16px
;
color
:
#fff
;
font-weight
:
bold
;
//
line-height
:
30px
;
letter-spacing
:
3px
;
text-align
:
center
;
}
}
}
}
}
.info
{
padding
:
5px
10px
12px
;
position
:
relative
;
background-color
:
white
;
.name
{
flex
:
1
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
display
:
-webkit-box
;
-webkit-line-clamp
:
2
;
-webkit-box-orient
:
vertical
;
line-height
:
1.4em
;
position
:
relative
;
}
.follower-wrap
{
position
:
relative
;
font-size
:
0.8em
;
//
padding-left
:
10px
;
//
border-left
:
1px
solid
;
color
:
#999
;
text-align
:
center
;
height
:
35px
;
.follower-num
{
text-align
:
center
;
//
color
:
#ff9933
;
font-size
:
1em
;
width
:
100%
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
.follower-text
{
color
:
#999
;
font-size
:
0.7em
;
text-align
:
center
;
width
:
100%
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
}
.vipPrice1
{
align-items
:
flex-end
;
margin-top
:
6px
;
font-size
:
12px
;
.vipIcon
{
min-width
:
32px
;
padding
:
1px
2px
;
height
:
14px
;
background
:
#333
;
font-size
:
10px
;
line-height
:
14px
;
text-align
:
center
;
color
:
#d7c7a1
;
border-top-left-radius
:
2px
;
border-bottom-left-radius
:
6px
;
}
.right
{
height
:
14px
;
color
:
#333
;
font-weight
:
bold
;
background
:
linear-gradient
(
227deg
,
rgba
(
212
,
195
,
142
,
1
),
rgba
(
252
,
232
,
162
,
1
)
);
border-radius
:
0px
6px
6px
0px
;
font-size
:
10px
;
text-align
:
center
;
padding
:
0
4px
0
2px
;
}
}
.priceItem
{
align-items
:
flex-end
;
}
.vipPrice2
{
align-items
:
flex-end
;
margin-top
:
6px
;
font-size
:
12px
;
.left
{
color
:
#333
;
font-weight
:
bold
;
margin-left
:
4px
;
}
.vipIcon
{
margin-left
:
4px
;
min-width
:
32px
;
padding
:
1px
4px
;
height
:
14px
;
background
:
#333
;
font-size
:
10px
;
line-height
:
14px
;
text-align
:
center
;
color
:
#d7c7a1
;
border-radius
:
6px
;
border-top-left-radius
:
2px
;
}
}
.marketing
{
align-items
:
center
;
flex-wrap
:
wrap
;
.item
{
margin-top
:
4px
;
margin-right
:
4px
;
font-size
:
10px
;
padding
:
0
6px
;
border
:
1px
solid
#ff5500
;
color
:
#ff5500
;
border-radius
:
20px
;
}
}
.bottom
{
position
:
relative
;
}
.price
{
font-weight
:
600
;
margin-top
:
6px
;
}
.showCommission
{
width
:
auto
;
display
:
inline-block
;
margin-top
:
4px
;
border
:
1px
solid
transparent
;
border-radius
:
6px
;
//
color
:
#ff9933
;
font-size
:
10px
;
//
padding
:
1px
6px
;
overflow
:
hidden
;
.commission-box
{
padding-left
:
6px
;
width
:
100%
;
height
:
100%
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
}
}
.buy-now
{
color
:
#ffffff
;
position
:
absolute
;
right
:
0
;
bottom
:
0
;
border-radius
:
15px
;
background-color
:
var
(
--main-color
);
width
:
70px
;
white-space
:
nowrap
;
padding
:
4px
15px
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
}
.buy-now-icon
{
position
:
absolute
;
right
:
0
;
bottom
:
0
;
font-size
:
18px
;
}
.showCommissionTwo
{
align-items
:
center
;
justify-content
:
center
;
margin-top
:
8px
;
width
:
100%
;
//
padding
:
0
10px
;
height
:
26px
;
font-size
:
12px
;
//
color
:
#FF5500
;
border
:
1px
solid
transparent
;
border-radius
:
26px
;
overflow
:
hidden
;
//
background
:
#FFEDE2
;
.commission-box
{
width
:
100%
;
height
:
100%
;
padding-left
:
10px
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
}
i
{
font-size
:
14px
;
margin-right
:
4px
;
}
}
}
</
style
>
src/components/activity/spellGroup/index.vue
0 → 100644
View file @
be7aa12c
<!-- 商品列表 -> 基于微商城 -->
<
template
>
<div
class=
"spell-group"
:style=
"
{
'padding-top': getPaddingList[0]['value'] + 'px',
'padding-bottom': getPaddingList[1]['value'] + 'px',
'padding-left': getPaddingList[2]['value'] + 'px',
'padding-right': getPaddingList[3]['value'] + 'px',
}"
v-if="this.render ? targetShow : true"
>
<div
class=
"list-wrap heap-wrap"
:style=
"
{'background-color': datas.componentData['heapBgColorShow']? datas.componentData['heapBgColor']: '','border-radius': datas.componentData['cardBorderRadius'] + 'em'}"
>
<div
class=
"tops"
:style=
"
{'padding':datas.componentData['titleIcon'] ||(datas.componentData['moreShow']
&&
datas.componentData.moreButtonSite == 'top')? '0px 0px 0px 0px': '','margin-bottom': datas.componentData['titleCardGap'] + 'px',}"
>
<div
class=
"left flex"
>
<div
class=
"img"
v-if=
"datas.componentData['titleIcon']"
>
<img
:src=
"titleIcon"
alt
/>
</div>
<h1
class=
"title"
>
{{
datas
.
componentData
[
"titles"
]
}}
</h1>
</div>
</div>
<!-- 堆叠卡片 -->
<div
v-if=
"datas.componentData.style==='heap'"
>
<spell-group-heap-item
:goodsList=
"goodsList"
:datas=
"datas"
></spell-group-heap-item>
</div>
<!-- 网格模式 -->
<div
class=
"goods"
v-if=
"datas.componentData.style === 'list'"
>
<ul
:style=
"
{'margin-left': -datas.componentData.proGap + 'px' }"
class="clearfix"
>
<li
v-for=
"(item, index) in getItemNum"
:key=
"index"
class=
"goods-item"
:class=
"datas.componentData.columnNum == 2 ? 'style2' : 'style3'"
:style=
"
{'padding-left': datas.componentData.proGap + 'px','width': getColumnWidth,}"
@click="onclickProduct(goodsList[index])"
>
<goodsItem
:datas=
"datas"
:items=
"item"
></goodsItem>
</li>
</ul>
</div>
<!-- 横向滑动 -->
<div
class=
"goods1"
:class=
"
{ 'goods1-wibkit': render }"
v-else-if="datas.componentData.style === 'across'"
>
<div
class=
"prev-btn"
>
<i
class=
"ant-fanhui-line"
style=
"font-size: 30px"
></i>
</div>
<div
class=
"next-btn"
>
<i
class=
"ant-fanhui-line"
style=
"font-size: 30px"
></i>
</div>
<div
v-for=
"(item, index) in getItemNum"
:key=
"index"
:style=
"
{ width: getColumnWidth,'margin-right': datas.componentData.proGap + 'px' }"
class="goods-item"
:class="{ lastchild: swiperNum == index + 1 }"
@click="onclickProduct(goodsList[index])"
>
<goodsItem
:datas=
"datas"
:items=
"item"
:style=
"
{'margin-left':datas.componentData.proGap*2+'px'}">
</goodsItem>
</div>
</div>
<!-- 瀑布流 -->
<div
class=
"waterfallFlow"
v-if=
"datas.componentData.style === 'waterfall'"
>
<div
class=
"left"
>
<div
v-for=
"(item,index) in goodsList"
:key=
"index"
@
click=
"onclickProduct(goodsList[index])"
:style=
"
{'margin-bottom':datas.componentData.proGap + 'px','margin-right':datas.componentData.proGap/2 + 'px'}">
<goodsItem
v-if=
"index%2==0"
:datas=
"datas"
:items=
"item"
></goodsItem>
</div>
</div>
<div
class=
"right"
>
<div
v-for=
"(item,index) in goodsList"
:key=
"index"
@
click=
"onclickProduct(goodsList[index])"
:style=
"
{'margin-bottom':datas.componentData.proGap + 'px','margin-left':datas.componentData.proGap/2 + 'px'}">
<goodsItem
v-if=
"index%2==1"
:datas=
"datas"
:items=
"item"
></goodsItem>
</div>
</div>
</div>
</div>
</div>
</
template
>
<
script
>
const
app
=
getApp
();
import
goodsItem
from
"./goodsItem"
import
mixin_computed
from
"./mixin/computed"
export
default
{
name
:
"spell-group"
,
mixins
:
[
mixin_computed
],
props
:
{
render
:
{
type
:
Boolean
,
default
:
true
,
},
datas
:
{
type
:
Object
,
default
:
function
()
{
return
{
fontSize
:
16
,
id
:
""
,
pageCode
:
0
,
pageType
:
0
,
code
:
0
,
//判断是否运维人员
componentData
:
{
goodsList
:
[],
initProductArr
:
[],
titles
:
"这是标题"
,
link
:
"https://www.baidu.com/"
,
fontColor
:
"#000000"
,
goodsSource
:
"classify"
,
//
style
:
"across"
,
//across
imgPadding
:
20
,
moreShow
:
true
,
moreButtonSite
:
"bottom"
,
rowNum
:
3
,
columnNum
:
2
,
proGap
:
10
,
backgroundColorShow
:
true
,
backgroundColor
:
"#CCCCCC"
,
borderColorShow
:
true
,
borderColor
:
"#999999"
,
get_shop_page_by_id
:
true
,
nameFontSize
:
0.8125
,
imgSize
:
"0%"
,
nameColor
:
"#000000"
,
describeShow
:
true
,
describeFontSize
:
1
,
priceShow
:
true
,
priceFontSize
:
0.9
,
priceColor
:
"#000000"
,
angleShow
:
false
,
colorLayoutShow
:
false
,
colorLayoutSite
:
"top"
,
initcharAlign
:
"left"
,
followerShow
:
true
,
// 划线价
priceMarking
:
true
,
// 商品排序 0 默认 1销量 2新品 3价格(由低到高)
goodsSort
:
0
,
paddingList
:
[
{
name
:
"上"
,
value
:
10
,
},
{
name
:
"下"
,
value
:
10
,
},
{
name
:
"左"
,
value
:
15
,
},
{
name
:
"右"
,
value
:
15
,
},
],
},
};
},
},
},
data
()
{
return
{
api
:
null
,
api2
:
null
,
targetShow
:
true
,
loading
:
false
,
swiperNum
:
5
,
toInit
:
true
,
DFSImg
:
""
,
sellOutShow
:
false
,
goodsList
:[],
};
},
created
()
{
this
.
DFSImg
=
app
.
DFSImg
;
},
mounted
()
{
this
.
init
();
},
methods
:
{
init
()
{
this
.
getProductList
(
2
);
},
async
getProductList
(
code
)
{
// 商品产品详情
let
productIdList
=
[];
this
.
goodsList
=
this
.
datas
.
componentData
.
goodsList
;
this
.
goodsList
.
forEach
((
element
)
=>
{
element
.
productImgUrl
=
""
;
element
.
productName
=
""
;
element
.
minPrice
=
""
;
productIdList
.
push
(
element
.
productId
);
});
if
(
productIdList
.
length
==
0
)
{
this
.
toInit
=
true
;
this
.
targetShow
=
false
;
return
;
}
let
query
=
{
sortColumn
:
this
.
goodsSort
,
sortType
:
this
.
goodsSort
!=
2
?
1
:
0
,
page
:
1
,
// 当前页
rows
:
productIdList
.
length
,
// 一页多少条
productIdList
:
productIdList
,
whetherShowSoldOutGoods
:
this
.
whetherShowSoldOutGoods
,
whetherQueryCollectCount
:
true
,
whetherUseVirtualSalesQty
:
true
,
//是否使用虚拟销售数量
whetherUseVirtualCollectCount
:
true
,
//是否使用虚拟收藏人数
whetherFindDistributionCommission
:
this
.
whetherFindDistributionCommission
,
//是否查询商品佣金(0:不查询,1:展示,为空不查佣金)
whetherFindRecommendedCardFlag
:
this
.
vipPrice
?
1
:
0
,
//是否查询会员价 1是 0否
whetherShowGoodsDefaultTagFlag
:
this
.
marketingTag
?
1
:
0
,
//是否展示营销标签 1是 0否
};
app
.
goodsApi
.
queryProductInfo
(
query
).
then
((
res
)
=>
{
this
.
sellOutShow
=
true
;
this
.
toInit
=
true
;
// 多主题(res.data.code)和商城端(res.code)不一样
if
(
res
.
data
.
code
==
200
)
{
this
.
datas
.
componentData
.
goodsList
=
res
.
data
.
data
.
list
;
this
.
datas
.
componentData
.
goodsList
.
forEach
((
item
)
=>
{
item
.
totalCollectionCount
=
Number
(
item
.
totalCollectionCount
)
||
0
;
item
.
qty
=
Number
(
item
.
qty
)
||
0
;
item
.
goodsMinPrice
=
Number
(
item
.
goodsMinPrice
).
toFixed
(
2
)
||
0
;
item
.
minPrice
=
Number
(
item
.
minPrice
).
toFixed
(
2
)
||
0
;
item
.
minGoodsSuggestedRetailPrice
=
Number
(
item
.
minGoodsSuggestedRetailPrice
).
toFixed
(
2
)
||
0
;
item
.
minPriceAfterRecommendedCardPriceTable
=
Number
(
item
.
minPriceAfterRecommendedCardPriceTable
).
toFixed
(
2
)
||
0
;
item
.
exchangeIntegral
=
Number
(
item
.
exchangeIntegral
).
toFixed
(
2
)
||
0
;
item
.
minProductGoodsCommission
=
Number
(
item
.
minProductGoodsCommission
).
toFixed
(
2
)
||
0
;
item
.
minGoodsSuggestedRetailPrice
=
Number
(
item
.
minGoodsSuggestedRetailPrice
).
toFixed
(
2
)
||
0
;
item
.
marketingTag
=
item
.
defaultTags
?
this
.
filtermark
(
item
.
defaultTags
,
this
.
marketingTagList
)
:
[];
item
.
coverImage
=
this
.
DFSImg
(
item
.
coverImage
,
700
,
null
,
1
);
item
.
productImgUrl
=
this
.
DFSImg
(
item
.
productImgUrl
,
700
,
null
,
1
);
});
this
.
goodsList
=
this
.
datas
.
componentData
.
goodsList
;
console
.
log
(
this
.
goodsList
,
'---------------------898'
)
if
(
this
.
goodsList
.
length
<=
0
)
{
this
.
targetShow
=
false
;
}
}
});
},
viewMore
()
{
if
(
!
this
.
render
)
return
;
if
(
this
.
goodsType
!=
1
)
{
if
(
this
.
datas
.
componentData
.
style
==
"list"
)
{
this
.
$router
.
push
({
name
:
"goods-commodityMenu"
,
query
:
{
categoryName
:
this
.
datas
.
componentData
.
categoryName
,
categoryId
:
this
.
datas
.
componentData
.
categoryId
,
},
});
}
else
{
this
.
$router
.
push
({
name
:
"goods-commodityMenu"
,
});
}
}
else
{
let
query
=
{
categoryName
:
this
.
datas
.
componentData
.
categoryName
,
categoryId
:
this
.
datas
.
componentData
.
categoryId
,
};
this
.
$router
.
push
({
name
:
"pointShop-productList"
,
query
,
});
}
},
//点击商城跳转---基于微商城
onclickProduct
(
item
)
{
let
productId
=
item
.
productId
;
let
terminalProductId
=
item
.
terminalProductId
;
let
linkVal
=
`/goods/
${
productId
}
?terminalProductId=
${
terminalProductId
}
`
;
app
.
$themeToLink
({
type
:
1
,
link
:
linkVal
});
},
showVipPrice
(
index
)
{
// 索引 0 显示价格 1显示名称
let
showFlag
=
false
;
let
vipPrice
=
this
.
goodsList
[
index
][
"minPriceAfterRecommendedCardPriceTable"
];
if
(
vipPrice
&&
Number
(
vipPrice
)
<
Number
(
this
.
goodsList
[
index
][
"minPrice"
])
)
{
showFlag
=
true
;
}
console
.
log
(
showFlag
,
"------------760"
);
return
showFlag
;
},
showVipTag
(
index
)
{
// 索引 0 显示价格 1显示名称
let
showFlag
=
false
;
let
vipPrice
=
this
.
goodsList
[
index
][
"minPriceAfterRecommendedCardPriceTable"
];
let
showTag
=
this
.
goodsList
[
index
][
"recommendedCardMinPricePriceTableName"
];
if
(
vipPrice
&&
showTag
&&
Number
(
vipPrice
)
<=
Number
(
this
.
goodsList
[
index
][
"minPrice"
])
)
{
showFlag
=
true
;
}
return
showFlag
;
},
filtermark
(
newlist
,
marketingTagList
)
{
let
list
=
[];
if
(
newlist
.
length
<=
0
)
return
;
if
(
marketingTagList
.
length
>
0
)
{
marketingTagList
.
forEach
((
item
,
index
)
=>
{
newlist
.
forEach
((
item1
,
index1
)
=>
{
if
(
item1
==
item
.
key
)
{
list
.
push
(
item
);
}
});
});
}
return
list
;
},
},
components
:
{
goodsItem
,
},
};
</
script
>
<
style
lang=
"scss"
scoped
>
.clearfix
:after
{
display
:
block
;
clear
:
both
;
content
:
""
;
visibility
:
hidden
;
height
:
0
;
}
.clearfix
{
zoom
:
1
;
}
.spell-group
{
position
:
relative
;
font-size
:
16px
;
.heap-wrap
{
padding
:
10px
;
}
.tops
{
position
:
relative
;
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
//
padding-bottom
:
0.54em
;
//
padding
:
0px
0px
10px
5px
;
.left
{
align-items
:
center
;
.img
{
width
:
30px
;
height
:
30px
;
overflow
:
hidden
;
margin-right
:
10px
;
img
{
width
:
100%
;
height
:
100%
;
object-fit
:
cover
;
}
}
}
}
h1
{
text-align
:
center
;
text-transform
:
uppercase
;
//
letter-spacing
:
0.1em
;
font-size
:
18px
;
color
:
#0a0a0a
;
}
.goods
{
width
:
100%
;
position
:
relative
;
ul
{
list-style
:
none
;
//
overflow
:
hidden
;
li
{
box-sizing
:
border-box
;
float
:
left
;
margin-bottom
:
1em
;
}
.style2
:nth-child
(
2n
+
1
)
{
clear
:
both
;
}
.style3
:nth-child
(
3n
+
1
)
{
clear
:
both
;
}
}
.marquee
{
position
:
absolute
;
z-index
:
999
;
top
:
10px
;
left
:
20px
;
}
}
.goods1
{
overflow-x
:
auto
;
overflow-y
:
hidden
;
white-space
:
nowrap
;
padding-bottom
:
5px
;
.prev-btn,
.next-btn
{
width
:
30px
;
height
:
30px
;
position
:
absolute
;
top
:
50%
;
z-index
:
99
;
opacity
:
0.5
;
font-size
:
30px
;
}
.next-btn
{
right
:
10px
;
transform
:
rotateY
(
180deg
);
}
.prev-btn
{
left
:
10px
;
}
.goods-item
{
display
:
inline-block
;
vertical-align
:
top
;
white-space
:
initial
;
.items
{
position
:
relative
;
border-radius
:
5px
;
overflow
:
hidden
;
//
box-shadow
:
1px
0px
26px
2px
#f5f5f5
;
background
:
#ffffff
;
.after
{
width
:
100%
;
height
:
100%
;
background-color
:
aliceblue
;
}
}
}
.slidebox2
{
box-sizing
:
border-box
;
-moz-box-sizing
:
border-box
;
/* Firefox */
-webkit-box-sizing
:
border-box
;
/* Safari */
}
}
.goods1-wibkit
::-webkit-scrollbar
{
display
:
none
;
}
.moreBottom
{
font-size
:
13px
;
text-align
:
center
;
padding-top
:
0.54em
;
color
:
#6b6b6b
;
.jt
{
display
:
inline-block
;
border-top
:
1px
solid
;
border-right
:
1px
solid
;
width
:
10px
;
height
:
10px
;
-webkit-transform
:
rotate
(
-135deg
);
transform
:
rotate
(
405deg
);
margin-left
:
0px
;
}
}
//
瀑布流
.waterfallFlow
{
display
:
flex
;
justify-content
:
space-between
;
.left,.right{
width
:
50%
;
box-sizing
:
border-box
;
}
}
}
</
style
>
src/components/activity/spellGroup/mixin/computed.js
0 → 100644
View file @
be7aa12c
const
app
=
getApp
();
export
default
{
computed
:
{
getBorderRadius
()
{
return
this
.
datas
.
componentData
.
borderRadius
==
undefined
?
0.625
:
this
.
datas
.
componentData
.
borderRadius
;
},
goodsSort
()
{
return
this
.
datas
.
componentData
.
goodsSort
||
0
;
},
// 会员价
vipPrice
()
{
return
this
.
datas
.
componentData
.
vipPrice
||
false
;
},
whetherFindDistributionCommission
()
{
return
this
.
datas
.
componentData
.
whetherFindDistributionCommission
?
1
:
0
;
},
categoryId
()
{
return
this
.
datas
.
componentData
.
categoryId
?
this
.
datas
.
componentData
.
categoryId
:
""
;
},
// 关注人数样式
followerColor
()
{
return
this
.
datas
.
componentData
.
followerColor
?
this
.
datas
.
componentData
.
followerColor
:
"#ff9933"
;
},
// 佣金文字颜色
commissionColor
()
{
return
this
.
datas
.
componentData
.
commissionColor
?
this
.
datas
.
componentData
.
commissionColor
:
"#ff9051"
;
},
//佣金背景颜色
commissionBgColor
()
{
return
this
.
datas
.
componentData
.
commissionBgColor
?
this
.
datas
.
componentData
.
commissionBgColor
:
""
;
},
// 按钮图标
btnIcon
()
{
return
this
.
datas
.
componentData
.
btnIcon
?
this
.
datas
.
componentData
.
btnIcon
:
""
;
},
// 按钮类型
btnType
()
{
return
this
.
datas
.
componentData
.
btnType
?
this
.
datas
.
componentData
.
btnType
:
6
;
},
// 按钮颜色
btnColor
()
{
return
this
.
datas
.
componentData
.
btnColor
?
this
.
datas
.
componentData
.
btnColor
:
"var(--main-color)"
;
},
// 按钮文案
btnTest
()
{
return
this
.
datas
.
componentData
.
btnTest
?
this
.
datas
.
componentData
.
btnTest
:
"立即购买"
;
},
getItemNum
()
{
return
this
.
datas
.
componentData
.
goodsList
;
},
getPaddingList
()
{
return
this
.
datas
.
componentData
.
paddingList
;
},
getColumnWidth
()
{
if
(
this
.
datas
.
componentData
.
columnNum
==
1
)
{
return
"100%"
;
}
else
if
(
this
.
datas
.
componentData
.
columnNum
==
2
)
{
return
"50%"
;
}
else
{
return
"33.3%"
;
}
},
getPayFontSize
()
{
if
(
this
.
datas
.
componentData
.
columnNum
==
1
)
{
return
"12px"
;
}
else
if
(
this
.
datas
.
componentData
.
columnNum
==
2
)
{
return
"10px"
;
}
else
{
return
"8px"
;
}
},
getListPadding
()
{
if
(
this
.
datas
.
componentData
.
columnNum
==
1
)
{
return
""
;
}
else
if
(
this
.
datas
.
componentData
.
columnNum
==
2
)
{
return
(
"0 "
+
this
.
datas
.
componentData
.
proGap
/
2
+
"px"
+
" 0 "
+
this
.
datas
.
componentData
.
proGap
/
2
+
"px"
);
}
else
{
return
"33.3%"
;
}
},
whetherShowSoldOutGoods
()
{
// 商城端接口的获取商城配置信息
// if (this.render) {
// return this.$store.state.setShopConfig.whetherShowSoldOutGoods || 1;
// } else {
// return 1;
// }
return
1
;
},
goodsType
()
{
return
this
.
datas
.
componentData
.
goodsType
||
0
;
},
// 展示标题图片
titleIcon
()
{
return
app
.
DFSImg
(
this
.
datas
.
componentData
.
titleIcon
,
400
,
400
)
||
""
;
},
// 展示角标
angleSign
()
{
return
this
.
datas
.
componentData
.
angleSign
||
false
;
},
// 角标尺寸
angleSignSize
()
{
return
this
.
datas
.
componentData
.
angleSignSize
||
25
;
},
// 展示角标图片
angleSignImg
()
{
return
this
.
datas
.
componentData
.
angleSignImg
||
""
;
},
// 展示营销标签
marketingTag
()
{
return
this
.
datas
.
componentData
.
marketingTag
||
false
;
},
// 展示营销标签类型
marketingStyle
()
{
return
this
.
datas
.
componentData
.
marketingStyle
||
0
;
},
// 营销标签列表
marketingTagList
()
{
return
this
.
datas
.
componentData
.
marketingTagList
||
[];
},
cardShadowSize
()
{
return
this
.
datas
.
componentData
.
cardShadowSize
?
this
.
datas
.
componentData
.
cardShadowSize
:
3
;
}
}
};
\ No newline at end of file
src/components/content/information/articleItem.vue
View file @
be7aa12c
...
...
@@ -30,7 +30,7 @@
<span
class=
"tagName"
>
{{
item
.
tagName
}}
</span>
</div>
</div>
<image
:src=
"info.coverUrl"
mode=
"widthFix"
></image>
<image
:src=
"info.coverUrl"
mode=
"widthFix"
lazy-load
></image>
</div>
<div
class=
"infoText"
>
<p
...
...
@@ -70,7 +70,7 @@
<span
class=
"tagName"
>
{{
item
.
tagName
}}
</span>
</div>
</div>
<image
:src=
"info.coverUrl"
mode=
"widthFix"
></image>
<image
:src=
"info.coverUrl"
lazy-load
mode=
"widthFix"
></image>
</div>
</div>
</
template
>
...
...
src/pages/home/index.vue
View file @
be7aa12c
...
...
@@ -84,6 +84,10 @@
<div
v-if=
"item.componentCode == 'merchants-list' && item.componentInfo.visible == 1"
>
<merchants-list
class=
"goodsListItem"
:datas=
"item"
></merchants-list>
</div>
<div
v-if=
"item.componentCode == 'spell-group' && item.componentInfo.visible == 1"
>
<spell-group
:datas=
"item"
></spell-group>
</div>
</div>
<bottomCont></bottomCont>
</div>
...
...
@@ -105,6 +109,7 @@ import text from '@/components/content/text'
import
imgText
from
'@/components/content/imgText'
import
coupon
from
'@/components/activity/coupon'
import
integralTurntable
from
'@/components/activity/integralTurntable'
import
spellGroup
from
'@/components/activity/spellGroup'
import
{
setTabBarActive
,
checkTabbarPage
,
themeColor
}
from
"../../utils/mayi.js"
;
import
{
throttle
}
from
"../../utils/index.js"
const
app
=
getApp
();
...
...
@@ -134,7 +139,8 @@ export default {
coupon
,
integralTurntable
,
transverseLabel
,
information
information
,
spellGroup
},
onShareAppMessage
(
res
)
{
let
shareVal
=
{};
...
...
src/pages/home/main.json
View file @
be7aa12c
...
...
@@ -19,7 +19,8 @@
"photo-gallery"
:
"/static/nativeComponents/PhotoGallery/index"
,
"live-broadcast"
:
"/static/nativeComponents/LiveBroadcast/index"
,
"share-picture"
:
"/static/nativeComponents/SharePicture/index"
,
"merchants-list"
:
"/static/nativeComponents/MerchantsList/index"
"merchants-list"
:
"/static/nativeComponents/MerchantsList/index"
,
"spell-group-heap-item"
:
"/static/nativeComponents/spellGroup/heapItem/index"
},
"enablePullDownRefresh"
:
true
,
"backgroundColor"
:
"#f5f5f5"
...
...
static/nativeComponents/spellGroup/GoodsItem/index.js
0 → 100644
View file @
be7aa12c
const
app
=
getApp
();
const
{
goodsApi
,
DFSImg
,
$themeToLink
,
$themeAddToCard
}
=
app
;
const
componentOptions
=
{
// 组件选项
options
:
{
multipleSlots
:
true
},
behaviors
:
[],
properties
:
{
datas
:
{
type
:
Object
},
items
:
{
type
:
Object
},
indexs
:
{
type
:
Number
}
},
// 组件数据
data
:
{
isPageHidden
:
false
,
// 页面是否处于隐藏状态
timeData
:
{}
},
// 数据监听器
observers
:
{},
// 组件方法
methods
:
{
init
()
{},
getSaleTime
(
val
)
{
return
new
Date
(
val
.
replace
(
/-/g
,
"/"
)).
getTime
()
-
new
Date
().
getTime
();
},
showVipPrice
(
index
)
{
// 索引 0 显示价格 1显示名称
let
showFlag
=
false
;
let
vipPrice
=
this
.
items
[
"minPriceAfterRecommendedCardPriceTable"
];
if
(
vipPrice
&&
Number
(
vipPrice
)
<
Number
(
this
.
items
[
"minPrice"
]))
{
showFlag
=
true
;
}
console
.
log
(
showFlag
,
"------------760"
);
return
showFlag
;
},
showVipTag
(
index
)
{
// 索引 0 显示价格 1显示名称
let
showFlag
=
false
;
let
vipPrice
=
this
.
items
[
"minPriceAfterRecommendedCardPriceTable"
];
let
showTag
=
this
.
items
[
"recommendedCardMinPricePriceTableName"
];
if
(
vipPrice
&&
showTag
&&
Number
(
vipPrice
)
<=
Number
(
this
.
items
[
"minPrice"
])
)
{
showFlag
=
true
;
}
return
showFlag
;
},
onChange
(
e
)
{
this
.
setData
({
timeData
:
e
.
detail
});
},
onclickProduct
()
{
let
{
goodsType
}
=
this
.
data
.
datas
.
componentData
;
let
{
productId
,
terminalProductId
,
terminalGoodsMixId
}
=
this
.
data
.
items
;
let
linkVal
=
""
;
if
(
goodsType
==
0
)
{
linkVal
=
`/goods/
${
productId
}
?terminalProductId=
${
terminalProductId
}
`
;
}
else
if
(
goodsType
==
1
)
{
linkVal
=
`/pointShop/goodsDetail?productId
${
productId
}
&terminalProductId=
${
terminalProductId
}
&terminalGoodsMixId=
${
terminalGoodsMixId
}
`
;
}
$themeToLink
({
type
:
1
,
link
:
linkVal
});
},
onclickBuynow
()
{
let
{
btnType
}
=
this
.
data
.
datas
.
componentData
;
let
{
minProductGoodsMixid
,
minProductGoodsId
,
minGoodsId
}
=
this
.
data
.
items
;
let
linkVal
=
""
;
if
(
btnType
<
6
)
{
// 加入购物车
console
.
log
(
"加入购物车"
);
$themeAddToCard
(
this
.
data
.
items
);
}
else
{
// 进入确认订单
linkVal
=
`/order/orderConfirm?productGoodsMixId=
${
minProductGoodsMixid
}
&productGoodsId=
${
minProductGoodsId
}
&goodsId=
${
minGoodsId
}
&qty=1&goodsString=null&source=3`
;
}
console
.
log
(
linkVal
,
"-------90"
);
$themeToLink
({
type
:
1
,
link
:
linkVal
});
},
toMerchants
()
{
let
{
orgId
}
=
this
.
data
.
items
;
$themeToLink
({
type
:
1
,
link
:
`/merchantsDetail/
${
orgId
}
`
});
},
},
// 组件生命周期
lifetimes
:
{
created
()
{},
attached
()
{
this
.
init
();
},
ready
()
{},
moved
()
{},
detached
()
{}
},
definitionFilter
()
{},
// 页面生命周期
pageLifetimes
:
{
// 页面被展示
show
()
{
const
{
isPageHidden
}
=
this
.
data
;
// show事件发生前,页面不是处于隐藏状态时
if
(
!
isPageHidden
)
{
return
;
}
// 重新执行定时器等操作
},
// 页面被隐藏
hide
()
{
this
.
setData
({
isPageHidden
:
true
});
// 清除定时器等操作
},
// 页面尺寸变化时
resize
()
{}
}
};
Component
(
componentOptions
)
static/nativeComponents/spellGroup/GoodsItem/index.json
0 → 100644
View file @
be7aa12c
{
"component"
:
true
,
"usingComponents"
:
{
"van-count-down"
:
"/static/vant/count-down/index"
}
}
static/nativeComponents/spellGroup/GoodsItem/index.wxml
0 → 100644
View file @
be7aa12c
<!-- 商品列表item -->
<view
class="goodsItem {{datas.componentData.style==='rowList'?'goodsRowList':''}} {{datas.componentData.style==='heap'?'goodsRowList goodsHeapItem':''}}"
style="--proGap2:{{datas.componentData.proGap*2}}rpx;"
bindtap="onclickProduct"
>
<view class="goods-item-child {{datas.componentData['borderColorShow']?'goods-item-child-bd':''}}" style="border-radius:{{datas.componentData.borderRadius}}em;--border_color:{{datas.componentData['borderColor']}};box-shadow:{{datas.componentData['cardShadow']?'0rpx 0rpx 10rpx '+datas.componentData['cardShadowSize']*2+'rpx #ccc':''}};">
<!-- 商品图片 -->
<view class="imgBox" style="background-color:{{datas.componentData['backgroundColorShow']?datas.componentData['backgroundColor']:''}}">
<view
class="goodsPicture"
wx:if="{{items!=null}}"
style="padding:{{datas.componentData.imgSize}}"
>
<!-- 显示拼团数 -->
<view class="have-group" wx:if="{{datas.componentData['haveGroupShow']&& (items && items['groupBuyFlag'] == '1')}}">{{items.haveGroupNum?items.haveGroupNum:0}}人已团</view>
<!-- 商品角标 -->
<view
class="angleSign"
style="width:{{datas.componentData.angleSignSize}}%;height:{{datas.componentData.angleSignSize}}%;"
wx:if="{{datas.componentData['angleSign'] && datas.componentData['angleSignImg']}}"
>
<image mode="widthFix" src="{{datas.componentData['angleSignImg']}}" />
</view>
<!-- 商品主图 -->
<image
lazy-load
mode="{{datas.componentData.style==='rowList' || datas.componentData.style==='heap'?'aspectFit':'widthFix'}}"
class="productImgUrl"
wx:if="{{datas.componentData.goodsImgType == 1}}"
src="{{items.productImgUrl}}"
/>
<image
lazy-load
mode="{{datas.componentData.style==='rowList' || datas.componentData.style==='heap'?'aspectFit':'widthFix'}}"
class="productImgUrl"
wx:else
src="{{items.coverImage}}"
/>
<!-- 售罄遮罩 -->
<view class="whiteBg" wx:if="{{items&&items.oversoldFlag==0&&items.totalQty-0<=0}}">
<view class="cover">
<image mode="aspectFit" src="http://mayi-newshop.oss-cn-shanghai.aliyuncs.com/public/png/f254fe62-6dda-46f6-a2f4-a7b2aa0474df.png" />
</view>
</view>
</view>
</view>
<!-- 商品详情 -->
<view class="info" style="text-align:{{datas.componentData['initcharAlign']}};">
<view class="info-top flex">
<view
class="name"
wx:if="{{datas.componentData['nameShow']}}"
style="color:{{datas.componentData['nameColor']}};font-weight:{{datas.componentData['nameFontWeight']}};font-size:{{datas.componentData['nameFontSize']}}em;height:2.8em;"
>
{{items!=null?items['productName']:'名称'}}
</view>
<view
class="follower-wrap"
wx:if="{{datas.componentData['followerShow']}}"
style="padding-left:{{datas.componentData.columnNum == 3 ? '0' : '20rpx'}}"
>
<view class="follower-num" style="color:{{datas.componentData['followerColor']?datas.componentData['followerColor']:'#ff9933'}};">
{{items!=null? items['totalCollectionCount']:0}}
</view>
<view class="follower-text">关注人数</view>
</view>
</view>
<!-- 已售 -->
<view class="Sold">
<text wx:if="{{datas.componentData['alSaleShow']}}">已售{{items!=null ? items['totalSalesCount'] :0}}件</text>
<text wx:if="{{datas.componentData['alSaleShow'] && datas.componentData['collectShow']}}">/</text>
<text wx:if="{{datas.componentData['collectShow']}}">剩余{{items!=null && items['qty']!=undefined ? (items['qty'] > 0 ? items['qty']: items.oversoldFlag==1?'数量充足':'数量不足') : ''}}<text wx:if="{{items!=null && (items['qty'] ? items['qty'] >= 0 : items['saleQty'] >= 0) && items.oversoldFlag!=1}}">件</text>
</text>
</view>
<!-- 标签 -->
<view class="marketing flex" wx:if="{{datas.componentData['marketingTag']&&datas.componentData['marketingStyle']==0&&items.marketingTag}}">
<view
class="item"
wx:for="{{items.marketingTag}}"
wx:key="index"
>
{{item.label}}
</view>
</view>
<!-- 底部 -->
<view class="bottom" wx:if="{{datas.componentData['goodsType'] !=1}}">
<!-- 价格 -->
<view class="priceItem flex">
<view
class="price flex"
style="color:{{datas.componentData['priceColor']}};font-size:{{datas.componentData['priceFontSize']}}em;"
wx:if="{{datas.componentData['priceShow']}}"
>
<text wx:if="{{items!=null && (items['groupBuyFlag'] == '0' ||items['groupBuyFlag'] == '1')}}">
¥{{items!=null ? items['goodsMinPrice']:0}}
</text>
<text style="font-size:24rpx;color:#999;text-decoration:line-through;" wx:if="{{items!=null&&datas.componentData['priceMarking']&&items['minGoodsSuggestedRetailPrice']&&(items['goodsMinPrice']-0<items['minGoodsSuggestedRetailPrice']-0)&&datas.componentData['columnNum']<3}}">
¥{{items['minGoodsSuggestedRetailPrice']}}
</text>
</view>
<view class="vipPrice2 flex" wx:if="{{datas.componentData.vipPrice}}">
<view class="left" wx:if="{{items.showVipPrice==true}}">
¥{{items['minPriceAfterRecommendedCardPriceTable']}}
</view>
<view class="vipIcon line-clamp1" wx:if="{{items.showVipTag==true}}">
{{items["recommendedCardMinPricePriceTableName"]}}
</view>
</view>
</view>
<!-- 收益样式一 -->
<block wx:if="{{items!=null&&items['minProductGoodsCommission']&&items['minProductGoodsCommission']-0>0.01}}">
<view
class="showCommission"
style="color:{{datas.componentData.commissionColor}};border-color:{{datas.componentData.commissionColor}};"
wx:if="{{datas.componentData.commissionStyle==0}}"
>
<view class="commission-box" style="background-color:{{datas.componentData.commissionBgColor}}">
<text>收益</text>
<text>¥{{items['minProductGoodsCommission']}}</text>
</view>
</view>
</block>
<view wx:if="{{(items&&items.totalQty-0>0||items&&items.oversoldFlag==1)&& datas.componentData['paynow']}}" catchtap="onclickBuynow">
<text wx:if="{{datas.componentData.btnType<6}}" style="color:{{datas.componentData.btnColor}}" class="buy-now-icon iconfont-common {{datas.componentData.btnIcon}}"></text>
<view
wx:else
class="buy-now"
style="background-color:{{datas.componentData.btnColor}};font-size:24rpx;"
>
{{datas.componentData.btnTest}}
</view>
</view>
</view>
<!-- 底部展示标签列表 -->
<block wx:if="{{items!=null}}">
<view class="marketing flex" wx:if="{{datas.componentData.marketingTag&&datas.componentData.marketingStyle==1&&items.marketingTag}}">
<view
class="item"
wx:for="{{items.marketingTag}}"
wx:key="index"
>
{{item.label}}
</view>
</view>
</block>
<!-- 收益样式二 -->
<block wx:if="{{items!=null&&items['minProductGoodsCommission']&&items['minProductGoodsCommission']-0>0.01}}">
<view
class="showCommissionTwo flex"
wx:if="{{datas.componentData.commissionStyle==1}}"
style="color:{{datas.componentData.commissionColor}};border-color:{{datas.componentData.commissionColor}};"
>
<view class="commission-box" style="background-color:{{datas.componentData.commissionBgColor}}">
<text class="iconfont-common common-iconfenxiang"></text>
<text style="padding:0 8rpx;">赚¥</text>
<text style="font-size:32rpx;">{{items['minProductGoodsCommission']}}</text>
</view>
</view>
</block>
</view>
</view>
</view>
static/nativeComponents/spellGroup/GoodsItem/index.wxss
0 → 100644
View file @
be7aa12c
@import "/static/font/common_icon.wxss";
.flex{
display: flex;
}
.goods-item-child-bd{
border: 1px solid var(--border_color);
}
image{
width: 100%;
display: block;
}
.goodsItem{
margin-bottom: var(--proGap2);
white-space: initial;
}
.goods-item-child {
position: relative;
overflow: hidden;
background: #fff;
}
.goodsRowList .goods-item-child{
display: flex;
align-items: flex-start;
}
.goodsRowList .goods-item-child .imgBox{
width: auto;
width: 180rpx;
height: 180rpx;
margin: 20rpx;
overflow: hidden;
border-radius: 12rpx;
-webkit-border-radius: 12rpx;
-moz-border-radius: 12rpx;
-ms-border-radius: 12rpx;
-o-border-radius: 12rpx;
}
.goodsRowList .goods-item-child .info{
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-around;
}
.goodsHeapItem{
width: 100%;
}
.merchantsEntrance{
padding: 8rpx 20rpx;
}
.merchantsEntrance .left{
align-items: center;
}
.merchantsEntrance .left .logo{
width: 52rpx;
height: 52rpx;
border-radius: 8rpx;
-webkit-border-radius: 8rpx;
-moz-border-radius: 8rpx;
-ms-border-radius: 8rpx;
-o-border-radius: 8rpx;
overflow: hidden;
background: #f5f5f5;
margin-right: 20rpx;
}
.imgBox{
position: relative;
overflow: hidden;
width: 100%;
margin: 0 auto;
}
.goodsPicture{
width: 100%;
height: 100%;
position: relative;
box-sizing: border-box;
}
.goodsPicture .have-group{
position: absolute;
bottom: 20rpx;
left: 12rpx;
padding: 8rpx 16rpx;
background-color: rgba(0,0,0,.6);
color: white;
font-size: 24rpx;
border-radius: 8rpx;
-webkit-border-radius: 8rpx;
-moz-border-radius: 8rpx;
-ms-border-radius: 8rpx;
-o-border-radius: 8rpx;
}
.goodsPicture .productImgUrl{
width: 100%;
height: 100%;
}
.goodsPicture .saleWay{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
display: flex;
justify-content: center;
z-index: 2;
color: #fff;
}
.goodsPicture .saleWay .saleWayBg{
background: var(--main-color);
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 0.5;
}
.goodsPicture .saleWay .saleTime{
position: relative;
z-index: 2;
padding: 4rpx 0;
}
.goodsPicture .saleWay .saleTime text{
color: #fff;
}
.goodsPicture .angleSign{
position: absolute;
top: 0;
left: 0;
}
.whiteBg {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(#fff, 0.7);
}
.whiteBg .cover {
position: absolute;
top: 20px;
left: 20px;
right: 20px;
bottom: 20px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border-radius: 50%;
background-size: cover;
}
.whiteBg .cover img {
width: 100%;
height: 100%;
object-fit: contain;
}
.info{
padding: 10rpx 20rpx 24rpx;
position: relative;
background-color: white;
}
.info .info-top{
overflow: hidden;
justify-content: space-between;
}
.info .name{
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
line-height: 1.4em;
position: relative;
}
.info .follower-wrap{
position: relative;
font-size: 0.8em;
color: #999;
text-align: center;
height: 70rpx;
border-left: 1px solid #999;
}
.info .follower-wrap .follower-num{
text-align: center;
font-size: 1em;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.info .follower-wrap .follower-text{
color: #999;
font-size: 0.7em;
text-align: center;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.vipPrice1{
align-items: flex-end;
margin-top: 12rpx;
font-size: 24rpx;
}
.vipPrice1 .vipIcon{
min-width: 64rpx;
padding: 2rpx 4rpx;
height: 28rpx;
background: #333;
font-size: 20rpx;
line-height: 28rpx;
text-align: center;
color: #d7c7a1;
border-top-left-radius: 4rpx;
border-bottom-left-radius: 12rpx;
}
.vipPrice1 .right{
height: 28rpx;
color: #333;
font-weight: bold;
background: linear-gradient( 227deg, rgba(212, 195, 142, 1), rgba(252, 232, 162, 1) );
border-radius: 0rpx 12rpx 12rpx 0rpx;
font-size: 20rpx;
text-align: center;
padding: 0 8rpx 0 4rpx;
-webkit-border-radius: 0rpx 12rpx 12rpx 0rpx;
-moz-border-radius: 0rpx 12rpx 12rpx 0rpx;
-ms-border-radius: 0rpx 12rpx 12rpx 0rpx;
-o-border-radius: 0rpx 12rpx 12rpx 0rpx;
}
.priceItem {
align-items: flex-end;
}
.priceItem .price{
align-items: center;
}
.vipPrice2{
align-items: flex-end;
margin-top: 12rpx;
font-size: 24rpx;
}
.vipPrice2 .left{
color: #333;
font-weight: bold;
margin-left: 8rpx;
}
.vipPrice2 .vipIcon{
margin-left: 8rpx;
min-width: 64rpx;
padding: 2rpx 8rpx;
height: 28rpx;
background: #333;
font-size: 20rpx;
line-height: 28rpx;
text-align: center;
color: #d7c7a1;
border-radius: 12rpx;
border-top-left-radius: 2rpx;
-webkit-border-radius: 12rpx;
-moz-border-radius: 12rpx;
-ms-border-radius: 12rpx;
-o-border-radius: 12rpx;
}
.Sold{
overflow: hidden;
color: #999;
}
.Sold text{
font-size: 24rpx;
}
.buy-now-icon{
color: var(--main-color);
}
.buy-now {
color: #ffffff;
position: absolute;
right: 0;
bottom: 0;
border-radius: 30rpx;
background-color: var(--main-color);
width: 140rpx;
white-space: nowrap;
padding: 8rpx 20rpx;
display: flex;
justify-content: center;
align-items: center;
-webkit-border-radius: 30rpx;
-moz-border-radius: 30rpx;
-ms-border-radius: 30rpx;
-o-border-radius: 30rpx;
}
.buy-now-icon {
position: absolute;
right: 0;
bottom: 0;
font-size: 36rpx;
}
.showCommission {
width: auto;
display: inline-block;
margin-top: 8rpx;
border: 1px solid transparent;
border-radius: 12rpx;
font-size: 10px;
overflow: hidden;
-webkit-border-radius: 12rpx;
-moz-border-radius: 12rpx;
-ms-border-radius: 12rpx;
-o-border-radius: 12rpx;
}
.showCommission .commission-box {
box-sizing: border-box;
padding: 0 10rpx;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.showCommissionTwo {
align-items: center;
justify-content: center;
margin-top: 16rpx;
width: 100%;
height: 52rpx;
font-size: 24rpx;
border: 1px solid transparent;
border-radius: 26px;
overflow: hidden;
}
.showCommissionTwo .commission-box {
width: 100%;
height: 100%;
padding-left: 20rpx;
display: flex;
justify-content: center;
align-items: center;
}
.showCommissionTwo i {
font-size: 28rpx;
margin-right: 8rpx;
}
.marketing {
align-items: center;
flex-wrap: wrap;
}
.marketing .item {
margin-top: 8rpx;
margin-right: 8rpx;
font-size: 20rpx;
padding: 0 12rpx;
border: 2rpx solid #ff5500;
color: #ff5500;
border-radius: 40rpx;
-webkit-border-radius: 40rpx;
-moz-border-radius: 40rpx;
-ms-border-radius: 40rpx;
-o-border-radius: 40rpx;
}
.bottom {
position: relative;
}
.price {
font-weight: 600;
margin-top: 12rpx;
}
\ No newline at end of file
static/nativeComponents/spellGroup/heapItem/index.js
0 → 100644
View file @
be7aa12c
import
TouchEvent
from
"./utils/touchEvent"
;
const
componentOptions
=
{
// 组件选项
options
:
{
multipleSlots
:
true
},
behaviors
:
[],
properties
:
{
datas
:
{
type
:
Object
},
goodsList
:
{
type
:
Array
}
},
// 组件数据
data
:
{
isPageHidden
:
false
,
// 页面是否处于隐藏状态
isLoading
:
false
,
swiperCurIndex
:
0
,
slideClass
:
""
,
lockSwipe
:
false
},
// 数据监听器
observers
:
{},
// 组件生命周期
lifetimes
:
{
created
()
{
new
TouchEvent
(
this
,
"touchCard"
,
{
swipe
:
evt
=>
{
//在touch结束触发,evt.direction代表滑动的方向 ['Up','Right','Down','Left']
if
(
evt
.
direction
===
"Left"
)
this
.
next
(
evt
);
if
(
evt
.
direction
===
"Right"
)
this
.
prev
(
evt
);
}
});
},
attached
()
{}
},
// 组件方法
methods
:
{
next
(
e
)
{
if
(
this
.
data
.
lockSwipe
)
return
;
this
.
data
.
lockSwipe
=
true
;
if
(
-
this
.
data
.
swiperCurIndex
>=
this
.
data
.
goodsList
.
length
-
1
)
{
return
(
this
.
data
.
lockSwipe
=
false
);
}
const
index
=
e
.
currentTarget
.
dataset
[
"index"
];
this
.
setData
(
{
[
"goodsList["
+
index
+
"].slideClass"
]:
" ani-slide-up"
},
()
=>
{
this
.
setData
({
swiperCurIndex
:
--
this
.
data
.
swiperCurIndex
});
}
);
setTimeout
(()
=>
{
this
.
data
.
lockSwipe
=
false
;
this
.
setData
({
[
"goodsList["
+
index
+
"].slideClass"
]:
""
});
},
590
);
},
prev
(
e
)
{
const
index
=
e
.
currentTarget
.
dataset
[
"index"
]
-
1
;
if
(
this
.
data
.
lockSwipe
||
index
<
0
)
return
;
this
.
data
.
lockSwipe
=
true
;
this
.
setData
({
[
"goodsList["
+
index
+
"].slideClass"
]:
" ani-slide-down"
,
swiperCurIndex
:
++
this
.
data
.
swiperCurIndex
});
setTimeout
(()
=>
{
this
.
data
.
lockSwipe
=
false
;
this
.
setData
({
[
"goodsList["
+
index
+
"].slideClass"
]:
""
});
},
590
);
}
},
definitionFilter
()
{},
// 页面生命周期
pageLifetimes
:
{
// 页面被展示
show
()
{
const
{
isPageHidden
}
=
this
.
data
;
// show事件发生前,页面不是处于隐藏状态时
if
(
!
isPageHidden
)
{
return
;
}
// 重新执行定时器等操作
},
// 页面被隐藏
hide
()
{
this
.
setData
({
isPageHidden
:
true
});
// 清除定时器等操作
},
// 页面尺寸变化时
resize
()
{}
}
};
Component
(
componentOptions
);
static/nativeComponents/spellGroup/heapItem/index.json
0 → 100644
View file @
be7aa12c
{
"component"
:
true
,
"usingComponents"
:
{
"goods-item"
:
"../GoodsItem/index"
}
}
static/nativeComponents/spellGroup/heapItem/index.wxml
0 → 100644
View file @
be7aa12c
<view class="container center">
<view class="card-swiper">
<view
wx:for="{{goodsList}}"
wx:key="index"
data-index="{{index}}"
class="{{'card-swiper-item curdistance' + (swiperCurIndex + index) + (!!item.slideClass? item.slideClass: '')}}"
bindtouchstart="touchCard.start"
bindtouchmove="touchCard.move"
bindtouchend="touchCard.end"
bindtouchcancel="touchCard.cancel"
>
<goods-item
style="width:100%"
datas="{{datas}}"
items="{{goodsList[index]}}"
indexs="{{index}}"
></goods-item>
</view>
</view>
</view>
static/nativeComponents/spellGroup/heapItem/index.wxss
0 → 100644
View file @
be7aa12c
.container{
width: 100%;
height: 200rpx;
padding: 0 0 20rpx;
}
/**index.wxss**/
.card-swiper{
position: relative;
width: 100%;
height: 100%;
color: #666;
font-size: 28rpx;
}
.card-swiper-item{
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
left: 0;
width: 92%;
transition: all .3s ease-out;
z-index: 0;
display: none;
overflow: hidden;
}
.card-swiper .card-swiper-item.curdistance0{
z-index: 10;
display: flex;
}
.card-swiper .card-swiper-item.curdistance1{
display: flex;
z-index: 9;
transform: scale(.95);
opacity: .7;
left: 40rpx;
}
.card-swiper .card-swiper-item.curdistance2{
display: flex;
z-index: 8;
transform: scale(.9);
opacity: .4;
left: 80rpx;
}
.ani-slide-up{
display: flex;
animation: slideUp .6s ease-out;
z-index: 11;
/* transform: rotate(25deg); */
}
.ani-slide-down{
display: flex;
animation: slideUp .6s ease-in;
animation-direction: reverse;
}
@keyframes slideUp{
0% {
}
70% {
opacity: 1;
}
100% {
transform: translateX(-1000rpx);
opacity: 0;
-webkit-transform: translateX(-1000rpx);
-moz-transform: translateX(-1000rpx);
-ms-transform: translateX(-1000rpx);
-o-transform: translateX(-1000rpx);
}
}
\ No newline at end of file
static/nativeComponents/spellGroup/heapItem/utils/touchEvent.js
0 → 100644
View file @
be7aa12c
var
defaultOption
=
{
touchStart
:
function
()
{
},
touchMove
:
function
()
{
},
touchEnd
:
function
()
{
},
touchCancel
:
function
()
{
},
multipointStart
:
function
()
{
},
multipointEnd
:
function
()
{
},
tap
:
function
()
{
},
doubleTap
:
function
()
{
},
longTap
:
function
()
{
},
singleTap
:
function
()
{
},
rotate
:
function
()
{
},
pinch
:
function
()
{
},
pressMove
:
function
()
{
},
swipe
:
function
()
{
}
}
export
default
class
YrobotTouch
{
constructor
(
pageOBJ
,
name
,
option
=
{})
{
this
.
preV
=
{
x
:
null
,
y
:
null
};
this
.
pinchStartLen
=
null
;
this
.
scale
=
1
;
this
.
isDoubleTap
=
false
;
this
.
delta
=
null
;
this
.
last
=
null
;
this
.
now
=
null
;
this
.
tapTimeout
=
null
;
this
.
singleTapTimeout
=
null
;
this
.
longTapTimeout
=
null
;
this
.
swipeTimeout
=
null
;
this
.
x1
=
this
.
x2
=
this
.
y1
=
this
.
y2
=
null
;
this
.
preTapPosition
=
{
x
:
null
,
y
:
null
};
this
.
lastZoom
=
1
;
this
.
tempZoom
=
1
;
try
{
if
(
this
.
_checkBeforeCreate
(
pageOBJ
,
name
))
{
this
.
_name
=
name
this
.
_option
=
{
...
defaultOption
,
...
option
}
pageOBJ
[
name
]
=
this
this
.
_bindFunc
(
pageOBJ
)
}
}
catch
(
error
)
{
console
.
error
(
error
)
}
}
_checkBeforeCreate
(
pageOBJ
,
name
)
{
if
(
!
pageOBJ
||
!
name
)
{
throw
new
Error
(
'YrobotTouch实例化时,必须传入page对象和引用名'
)
return
false
}
if
(
pageOBJ
[
name
])
{
throw
new
Error
(
'YrobotTouch实例化error: '
+
name
+
' 已经存在page中'
)
return
false
}
return
true
}
_bindFunc
(
pageOBJ
)
{
let
funcNames
=
[
'start'
,
'move'
,
'end'
,
'cancel'
]
for
(
let
funcName
of
funcNames
)
pageOBJ
[
this
.
_name
+
'.'
+
funcName
]
=
this
[
funcName
].
bind
(
this
)
}
start
(
evt
)
{
if
(
!
evt
.
touches
)
return
;
this
.
now
=
Date
.
now
();
this
.
x1
=
evt
.
touches
[
0
].
pageX
==
null
?
evt
.
touches
[
0
].
x
:
evt
.
touches
[
0
].
pageX
;
this
.
y1
=
evt
.
touches
[
0
].
pageY
==
null
?
evt
.
touches
[
0
].
y
:
evt
.
touches
[
0
].
pageY
;
this
.
delta
=
this
.
now
-
(
this
.
last
||
this
.
now
);
this
.
_option
.
touchStart
(
evt
);
if
(
this
.
preTapPosition
.
x
!==
null
)
{
this
.
isDoubleTap
=
(
this
.
delta
>
0
&&
this
.
delta
<=
250
&&
Math
.
abs
(
this
.
preTapPosition
.
x
-
this
.
x1
)
<
30
&&
Math
.
abs
(
this
.
preTapPosition
.
y
-
this
.
y1
)
<
30
);
}
this
.
preTapPosition
.
x
=
this
.
x1
;
this
.
preTapPosition
.
y
=
this
.
y1
;
this
.
last
=
this
.
now
;
let
preV
=
this
.
preV
,
len
=
evt
.
touches
.
length
;
if
(
len
>
1
)
{
this
.
_cancelLongTap
();
this
.
_cancelSingleTap
();
let
otx
=
evt
.
touches
[
1
].
pageX
==
null
?
evt
.
touches
[
1
].
x
:
evt
.
touches
[
1
].
pageX
;
let
oty
=
evt
.
touches
[
1
].
pageY
==
null
?
evt
.
touches
[
1
].
y
:
evt
.
touches
[
1
].
pageY
;
let
v
=
{
x
:
otx
-
this
.
x1
,
y
:
oty
-
this
.
y1
};
preV
.
x
=
v
.
x
;
preV
.
y
=
v
.
y
;
this
.
pinchStartLen
=
getLen
(
preV
);
this
.
_option
.
multipointStart
(
evt
);
}
this
.
longTapTimeout
=
setTimeout
(
function
()
{
evt
.
type
=
"longTap"
;
this
.
_option
.
longTap
(
evt
);
}.
bind
(
this
),
750
);
}
move
(
evt
)
{
if
(
!
evt
.
touches
)
return
;
let
preV
=
this
.
preV
,
len
=
evt
.
touches
.
length
,
currentX
=
evt
.
touches
[
0
].
pageX
==
null
?
evt
.
touches
[
0
].
x
:
evt
.
touches
[
0
].
pageX
,
currentY
=
evt
.
touches
[
0
].
pageY
==
null
?
evt
.
touches
[
0
].
y
:
evt
.
touches
[
0
].
pageY
;
this
.
isDoubleTap
=
false
;
if
(
len
>
1
)
{
let
otx
=
evt
.
touches
[
1
].
pageX
==
null
?
evt
.
touches
[
1
].
x
:
evt
.
touches
[
1
].
pageX
;
let
oty
=
evt
.
touches
[
1
].
pageY
==
null
?
evt
.
touches
[
1
].
y
:
evt
.
touches
[
1
].
pageY
;
let
v
=
{
x
:
otx
-
currentX
,
y
:
oty
-
currentY
};
if
(
preV
.
x
!==
null
)
{
if
(
this
.
pinchStartLen
>
0
)
{
evt
.
singleZoom
=
getLen
(
v
)
/
this
.
pinchStartLen
;
evt
.
zoom
=
evt
.
singleZoom
*
this
.
lastZoom
;
this
.
tempZoom
=
evt
.
zoom
;
evt
.
type
=
"pinch"
;
this
.
_option
.
pinch
(
evt
);
}
evt
.
angle
=
getRotateAngle
(
v
,
preV
);
evt
.
type
=
"rotate"
;
this
.
_option
.
rotate
(
evt
);
}
preV
.
x
=
v
.
x
;
preV
.
y
=
v
.
y
;
}
else
{
if
(
this
.
x2
!==
null
)
{
evt
.
deltaX
=
currentX
-
this
.
x2
;
evt
.
deltaY
=
currentY
-
this
.
y2
;
}
else
{
evt
.
deltaX
=
0
;
evt
.
deltaY
=
0
;
}
this
.
_option
.
pressMove
(
evt
);
}
this
.
_option
.
touchMove
(
evt
);
this
.
_cancelLongTap
();
this
.
x2
=
currentX
;
this
.
y2
=
currentY
;
if
(
len
>
1
)
{
// evt.preventDefault();
}
}
end
(
evt
)
{
if
(
!
evt
.
changedTouches
)
return
;
this
.
_cancelLongTap
();
let
self
=
this
;
evt
.
direction
=
this
.
_swipeDirection
(
this
.
x1
,
this
.
x2
,
this
.
y1
,
this
.
y2
);
//在结束钩子都加入方向判断,但触发swipe瞬时必须位移大于30
if
(
evt
.
touches
.
length
<
2
)
{
this
.
lastZoom
=
this
.
tempZoom
;
this
.
_option
.
multipointEnd
(
evt
);
}
this
.
_option
.
touchEnd
(
evt
);
//swipe
if
((
this
.
x2
&&
Math
.
abs
(
this
.
x1
-
this
.
x2
)
>
30
)
||
(
this
.
y2
&&
Math
.
abs
(
this
.
y1
-
this
.
y2
)
>
30
))
{
// evt.direction = this._swipeDirection(this.x1, this.x2, this.y1, this.y2);
this
.
swipeTimeout
=
setTimeout
(
function
()
{
evt
.
type
=
"swipe"
;
self
.
_option
.
swipe
(
evt
);
},
0
)
}
else
{
this
.
tapTimeout
=
setTimeout
(
function
()
{
evt
.
type
=
"tap"
;
self
.
_option
.
tap
(
evt
);
// trigger double tap immediately
if
(
self
.
isDoubleTap
)
{
evt
.
type
=
"doubleTap"
;
self
.
_option
.
doubleTap
(
evt
);
clearTimeout
(
self
.
singleTapTimeout
);
self
.
isDoubleTap
=
false
;
}
},
0
)
if
(
!
self
.
isDoubleTap
)
{
self
.
singleTapTimeout
=
setTimeout
(
function
()
{
self
.
_option
.
singleTap
(
evt
);
},
250
);
}
}
this
.
preV
.
x
=
0
;
this
.
preV
.
y
=
0
;
this
.
scale
=
1
;
this
.
pinchStartLen
=
null
;
this
.
x1
=
this
.
x2
=
this
.
y1
=
this
.
y2
=
null
;
}
cancel
(
evt
)
{
clearTimeout
(
this
.
singleTapTimeout
);
clearTimeout
(
this
.
tapTimeout
);
clearTimeout
(
this
.
longTapTimeout
);
clearTimeout
(
this
.
swipeTimeout
);
this
.
_option
.
touchCancel
(
evt
);
}
_cancelLongTap
()
{
clearTimeout
(
this
.
longTapTimeout
);
}
_cancelSingleTap
()
{
clearTimeout
(
this
.
singleTapTimeout
);
}
_swipeDirection
(
x1
,
x2
,
y1
,
y2
)
{
return
Math
.
abs
(
x1
-
x2
)
>=
Math
.
abs
(
y1
-
y2
)
?
(
x1
-
x2
>
0
?
'Left'
:
'Right'
)
:
(
y1
-
y2
>
0
?
'Up'
:
'Down'
)
}
destroy
()
{
if
(
this
.
singleTapTimeout
)
clearTimeout
(
this
.
singleTapTimeout
);
if
(
this
.
tapTimeout
)
clearTimeout
(
this
.
tapTimeout
);
if
(
this
.
longTapTimeout
)
clearTimeout
(
this
.
longTapTimeout
);
if
(
this
.
swipeTimeout
)
clearTimeout
(
this
.
swipeTimeout
);
this
.
_option
.
rotate
=
null
;
this
.
_option
.
touchStart
=
null
;
this
.
_option
.
multipointStart
=
null
;
this
.
_option
.
multipointEnd
=
null
;
this
.
_option
.
pinch
=
null
;
this
.
_option
.
swipe
=
null
;
this
.
_option
.
tap
=
null
;
this
.
_option
.
doubleTap
=
null
;
this
.
_option
.
longTap
=
null
;
this
.
_option
.
singleTap
=
null
;
this
.
_option
.
pressMove
=
null
;
this
.
_option
.
touchMove
=
null
;
this
.
_option
.
touchEnd
=
null
;
this
.
_option
.
touchCancel
=
null
;
this
.
preV
=
this
.
pinchStartLen
=
this
.
scale
=
this
.
isDoubleTap
=
this
.
delta
=
this
.
last
=
this
.
now
=
this
.
tapTimeout
=
this
.
singleTapTimeout
=
this
.
longTapTimeout
=
this
.
swipeTimeout
=
this
.
x1
=
this
.
x2
=
this
.
y1
=
this
.
y2
=
this
.
preTapPosition
=
this
.
rotate
=
this
.
touchStart
=
this
.
multipointStart
=
this
.
multipointEnd
=
this
.
pinch
=
this
.
swipe
=
this
.
tap
=
this
.
doubleTap
=
this
.
longTap
=
this
.
singleTap
=
this
.
pressMove
=
this
.
touchMove
=
this
.
touchEnd
=
this
.
touchCancel
=
null
;
return
null
;
}
}
function
getLen
(
v
)
{
return
Math
.
sqrt
(
v
.
x
*
v
.
x
+
v
.
y
*
v
.
y
);
}
function
dot
(
v1
,
v2
)
{
return
v1
.
x
*
v2
.
x
+
v1
.
y
*
v2
.
y
;
}
function
getAngle
(
v1
,
v2
)
{
let
mr
=
getLen
(
v1
)
*
getLen
(
v2
);
if
(
mr
===
0
)
return
0
;
let
r
=
dot
(
v1
,
v2
)
/
mr
;
if
(
r
>
1
)
r
=
1
;
return
Math
.
acos
(
r
);
}
function
cross
(
v1
,
v2
)
{
return
v1
.
x
*
v2
.
y
-
v2
.
x
*
v1
.
y
;
}
function
getRotateAngle
(
v1
,
v2
)
{
let
angle
=
getAngle
(
v1
,
v2
);
if
(
cross
(
v1
,
v2
)
>
0
)
{
angle
*=
-
1
;
}
return
angle
*
180
/
Math
.
PI
;
}
\ No newline at end of file
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