-
25.gitignore
-
768App.vue
-
2Dockerfile
-
269component/share.vue
-
388components/AliHbPay/index.vue
-
320components/CashierList/index.vue
-
72components/Empty/index.vue
-
24components/GlobalLoading/index.js
-
89components/GlobalLoading/index.vue
-
250components/Loading/index.vue
-
54components/NoMore/index.vue
-
200components/Skeleton/index.vue
-
633components/activities/combinedSales.vue
-
430components/adWindow.vue
-
84components/basics/categoryList.vue
-
280components/basics/categoryShow.vue
-
24components/canvasShow/basics/assistDiv.vue
-
107components/canvasShow/basics/banner.vue
-
131components/canvasShow/basics/brandList.vue
-
109components/canvasShow/basics/categoryList.vue
-
113components/canvasShow/basics/coupon/app/index.vue
-
109components/canvasShow/basics/coupon/mixin.js
-
375components/canvasShow/basics/coupon/pc/index.vue
-
238components/canvasShow/basics/custom.vue
-
300components/canvasShow/basics/discount/app/index.vue
-
110components/canvasShow/basics/discount/mixin.js
-
247components/canvasShow/basics/discount/pc/index.vue
-
213components/canvasShow/basics/group/app/index.vue
-
86components/canvasShow/basics/group/mixin.js
-
250components/canvasShow/basics/group/pc/index.vue
-
118components/canvasShow/basics/header/app/index.vue
-
45components/canvasShow/basics/header/mixin.js
-
119components/canvasShow/basics/imageText.vue
-
136components/canvasShow/basics/imageTextList.vue
-
101components/canvasShow/basics/imageTextNav.vue
-
71components/canvasShow/basics/live/app/index.vue
-
461components/canvasShow/basics/live/app/item.vue
-
60components/canvasShow/basics/live/mixin.js
-
196components/canvasShow/basics/newProduct/app/index.vue
-
89components/canvasShow/basics/newProduct/mixin.js
-
96components/canvasShow/basics/notice.vue
-
218components/canvasShow/basics/price/app/index.vue
-
73components/canvasShow/basics/price/mixin.js
-
253components/canvasShow/basics/price/pc/index.vue
-
564components/canvasShow/basics/product/app/index.vue
-
96components/canvasShow/basics/product/mixin.js
-
226components/canvasShow/basics/product/pc/index.vue
-
157components/canvasShow/basics/shop.vue
-
168components/canvasShow/basics/spike/app/index.vue
-
137components/canvasShow/basics/spike/mixin.js
-
211components/canvasShow/basics/spike/pc/index.vue
-
79components/canvasShow/basics/text.vue
-
120components/canvasShow/basics/video.vue
-
319components/canvasShow/basics/vip/app/index.vue
-
60components/canvasShow/basics/vip/mixin.js
-
241components/canvasShow/basics/vip/pc/index.vue
-
226components/canvasShow/canvasShowPage.vue
-
32components/canvasShow/config/api.js
-
12components/canvasShow/config/config.js
-
204components/canvasShow/config/mixin/funMixin.js
-
9components/canvasShow/config/mixin/index.js
-
37components/canvasShow/config/mixin/sendReqMixin.js
-
135components/canvasShow/config/mixin/server.js
-
BINcomponents/canvasShow/static/images/btn-next.png
-
BINcomponents/canvasShow/static/images/btn-next2.png
-
BINcomponents/canvasShow/static/images/btn-prev.png
-
BINcomponents/canvasShow/static/images/btn-prev2.png
-
BINcomponents/canvasShow/static/images/coupon/bg-coupon.png
-
BINcomponents/canvasShow/static/images/coupon/bg-coupon2.png
-
BINcomponents/canvasShow/static/images/coupon/border_L1.png
-
0components/canvasShow/static/images/coupon/border_L2.png
-
0components/canvasShow/static/images/coupon/border_L3.png
-
0components/canvasShow/static/images/coupon/border_L4.png
-
0components/canvasShow/static/images/coupon/border_R1.png
-
0components/canvasShow/static/images/coupon/border_R2.png
-
0components/canvasShow/static/images/coupon/border_R3.png
-
0components/canvasShow/static/images/coupon/border_R4.png
-
BINcomponents/canvasShow/static/images/coupon/flag-coupon-r.png
-
BINcomponents/canvasShow/static/images/coupon/flag-coupon.png
-
BINcomponents/canvasShow/static/images/coupon/flag-coupon2-r.png
-
BINcomponents/canvasShow/static/images/coupon/flag-coupon2.png
-
BINcomponents/canvasShow/static/images/discount/bg-discount-top-text.png
-
BINcomponents/canvasShow/static/images/discount/bg-discount-top.png
-
BINcomponents/canvasShow/static/images/discount/flag-discount.png
-
BINcomponents/canvasShow/static/images/discount/flag-discount2.png
-
BINcomponents/canvasShow/static/images/discount/img-title.png
-
BINcomponents/canvasShow/static/images/discountListIcon.png
-
BINcomponents/canvasShow/static/images/group/flag-group.png
-
BINcomponents/canvasShow/static/images/group/img-title.png
-
BINcomponents/canvasShow/static/images/groupBuyIcon.png
-
BINcomponents/canvasShow/static/images/icon-title.png
-
BINcomponents/canvasShow/static/images/live/huabei.png
-
BINcomponents/canvasShow/static/images/live/icon-live-num.png
-
BINcomponents/canvasShow/static/images/live/img-title.png
-
BINcomponents/canvasShow/static/images/memberCenterIcon.png
-
BINcomponents/canvasShow/static/images/newProduct/bg-product-card.png
-
BINcomponents/canvasShow/static/images/newProduct/flag-new.png
-
BINcomponents/canvasShow/static/images/notice/ico_notice.png
-
BINcomponents/canvasShow/static/images/notice/ico_notice2.png
-
BINcomponents/canvasShow/static/images/price/bg-discount.png
@ -0,0 +1,25 @@ |
|||
.DS_Storep |
|||
.DS_Store |
|||
# Editor directories and files |
|||
.idea |
|||
.vscode |
|||
.hbuilderx |
|||
*.suo |
|||
*.ntvs* |
|||
*.njsproj |
|||
*.sln |
|||
*.hbuilderx |
|||
/unpackage/dist/dev |
|||
/unpackage/dist/static |
|||
/unpackage/dist/build/mp-alipay/ |
|||
/unpackage/dist/build/mp-weixin/ |
|||
/unpackage/dist/build/app-plus/ |
|||
/unpackage/dist/build/.automator |
|||
/unpackage/cache/ |
|||
/unpackage/cache/apk |
|||
/unpackage/release |
|||
/unpackage/res |
|||
/unpackage/resources |
|||
/node_modules |
|||
package-lock.json |
|||
|
@ -0,0 +1,768 @@ |
|||
<script> |
|||
// // #ifdef MP-WEIXIN |
|||
// const miniShopPlugin = requirePlugin('mini-shop-plugin'); |
|||
// // #endif |
|||
import NET from "@/utils/request"; |
|||
import API from "@/config/api"; |
|||
|
|||
export default { |
|||
onLaunch: function (options) { |
|||
if (options && options.path === 'pages_category_page1/goodsModule/goodsDetails' && options.query) { |
|||
this.globalData.productShareItem = options.query |
|||
} |
|||
if (options && options.path === 'pages_category_page1/store/index' && options.query) { |
|||
this.globalData.shopShareItem = options.query |
|||
} |
|||
if (options && options.path === 'pages_category_page1/distributionModule/recruit' && options.query) { |
|||
this.globalData.distributeRecruitItem = options.query |
|||
} |
|||
if (options && options.path === 'pages_category_page1/goodsModule/inviteSpell' && options.query) { |
|||
this.globalData.inviteSpellShareItem = options.query |
|||
} |
|||
//判断设备是否为 iPhone |
|||
const self = this |
|||
uni.getSystemInfo({ |
|||
success: function (res) { |
|||
console.log(res, '检查机型') |
|||
// 根据 model 进行判断 |
|||
// const iphoneModels = [ |
|||
// 'iPhone X', |
|||
// 'iPhone XR', |
|||
// 'iPhone XS Max', |
|||
// 'iPhone 11', |
|||
// 'iPhone 11 Pro', |
|||
// 'iPhone 11 Pro Max', |
|||
// 'iPhone 12/13 (Pro)', |
|||
// 'iPhone 12/13 mini', |
|||
// 'iPhone 12/13 Pro Max' |
|||
// ] |
|||
if (res.safeArea.top > 20 && res.model.indexOf('iPhone') !== -1) { |
|||
self.globalData.isIphone = true |
|||
} |
|||
} |
|||
}) |
|||
// 购物车右上角数量 |
|||
if(uni.getStorageSync('storage_key')){ |
|||
NET.request(API.ShoppingCart, {}, 'GET').then(resCart => { |
|||
let cartNum = 0 |
|||
resCart.data.forEach(shopItem=>{ |
|||
shopItem.skus.forEach(goodsItem=>{ |
|||
cartNum += goodsItem.number |
|||
}) |
|||
}) |
|||
uni.setStorageSync('allCartNum', cartNum) |
|||
if (cartNum > 0) { |
|||
uni.setTabBarBadge({ |
|||
index: 2, |
|||
text: cartNum.toString() |
|||
}) |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
, |
|||
globalData: { |
|||
isIphone: false, |
|||
} |
|||
, |
|||
} |
|||
; |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
@keyframes loading { |
|||
0%{ |
|||
background: #e7e7e7; |
|||
} |
|||
50%{ |
|||
background: #f8f8f8; |
|||
} |
|||
100%{ |
|||
background: #e7e7e7; |
|||
} |
|||
} |
|||
// 自定义骨架屏 |
|||
.ske-loading{ |
|||
.child-loading{ |
|||
animation: loading 2s linear 0s infinite alternate; |
|||
} |
|||
} |
|||
/*每个页面公共css */ |
|||
@import "uview-ui/index.scss"; |
|||
|
|||
uni-rich-text img { |
|||
max-width: 100% !important; |
|||
} |
|||
// 图片占位图 |
|||
.pic-img{ |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
.default-img { |
|||
background: url(./static/images/default.png) no-repeat center; |
|||
background-size: 100% 100%; |
|||
} |
|||
|
|||
.line1 { |
|||
text-overflow: ellipsis; |
|||
white-space: nowrap; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
.wid { |
|||
width: 100%; |
|||
} |
|||
|
|||
.fs4 { |
|||
font-size: 4upx; |
|||
} |
|||
|
|||
.fs18 { |
|||
font-size: 18upx; |
|||
} |
|||
|
|||
.fs20 { |
|||
font-size: 20upx; |
|||
} |
|||
|
|||
.fs22 { |
|||
font-size: 22upx; |
|||
} |
|||
|
|||
.fs24 { |
|||
font-size: 24upx; |
|||
} |
|||
|
|||
.fs26 { |
|||
font-size: 26upx; |
|||
} |
|||
|
|||
.fs28 { |
|||
font-size: 28upx; |
|||
} |
|||
|
|||
.fs30 { |
|||
font-size: 30upx; |
|||
} |
|||
|
|||
.fs32 { |
|||
font-size: 32upx; |
|||
} |
|||
|
|||
.fs34 { |
|||
font-size: 34upx; |
|||
} |
|||
|
|||
.fs36 { |
|||
font-size: 36upx; |
|||
} |
|||
|
|||
.fs38 { |
|||
font-size: 38upx; |
|||
} |
|||
|
|||
.fs40 { |
|||
font-size: 40upx; |
|||
} |
|||
|
|||
.fs42 { |
|||
font-size: 42upx; |
|||
} |
|||
|
|||
.fs44 { |
|||
font-size: 44upx; |
|||
} |
|||
|
|||
.fs46 { |
|||
font-size: 46upx; |
|||
} |
|||
|
|||
.fs48 { |
|||
font-size: 46upx; |
|||
} |
|||
|
|||
.fs50 { |
|||
font-size: 50upx; |
|||
} |
|||
|
|||
.fs60 { |
|||
font-size: 60upx; |
|||
} |
|||
|
|||
.fs-bold { |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.fs-weight-300 { |
|||
font-weight: 300; |
|||
} |
|||
|
|||
.fs-weight-200 { |
|||
font-weight: 200; |
|||
} |
|||
|
|||
.fs-weight-400 { |
|||
font-weight: 400; |
|||
} |
|||
|
|||
|
|||
.flex-display { |
|||
display: flex; |
|||
} |
|||
|
|||
.flex-center { |
|||
display: flex; |
|||
justify-content: center; |
|||
} |
|||
|
|||
.flex-items { |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
|
|||
.flex-items-plus { |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
} |
|||
|
|||
.flex-start { |
|||
display: flex; |
|||
justify-content: flex-start; |
|||
} |
|||
|
|||
.flex-end { |
|||
display: flex; |
|||
justify-content: flex-end; |
|||
} |
|||
|
|||
.flex-end-plus { |
|||
display: flex; |
|||
justify-content: flex-end; |
|||
align-items: center; |
|||
} |
|||
|
|||
.flex-column { |
|||
flex-direction: column |
|||
} |
|||
|
|||
.flex-column-plus { |
|||
display: flex; |
|||
flex-direction: column |
|||
} |
|||
|
|||
.flex-row { |
|||
flex-direction: row |
|||
} |
|||
|
|||
.flex-row-plus { |
|||
display: flex; |
|||
flex-direction: row |
|||
} |
|||
|
|||
.flex-sp-around { |
|||
justify-content: space-around; |
|||
} |
|||
|
|||
.flex-sp-between { |
|||
justify-content: space-between; |
|||
} |
|||
|
|||
.text-align { |
|||
text-align: center; |
|||
} |
|||
|
|||
.flex-wrap-1 { |
|||
display: flex; |
|||
flex-wrap: wrap |
|||
} |
|||
|
|||
.flex-nowrap-1 { |
|||
display: flex; |
|||
flex-wrap: nowrap |
|||
} |
|||
|
|||
.align-end { |
|||
display: flex; |
|||
align-items: flex-end; |
|||
} |
|||
|
|||
.align-sp-between { |
|||
align-content: space-between; |
|||
} |
|||
|
|||
|
|||
.mar-top-5 { |
|||
margin-top: 5upx; |
|||
} |
|||
|
|||
.mar-top-10 { |
|||
margin-top: 10upx; |
|||
} |
|||
|
|||
.mar-top-20 { |
|||
margin-top: 20upx; |
|||
} |
|||
|
|||
.mar-top-30 { |
|||
margin-top: 30upx; |
|||
} |
|||
|
|||
.mar-top-32 { |
|||
margin-top: 32upx; |
|||
} |
|||
|
|||
.mar-top-36 { |
|||
margin-top: 36upx; |
|||
} |
|||
|
|||
.mar-top-40 { |
|||
margin-top: 40upx; |
|||
} |
|||
|
|||
.mar-top-50 { |
|||
margin-top: 50upx; |
|||
} |
|||
|
|||
.mar-top-60 { |
|||
margin-top: 60upx; |
|||
} |
|||
|
|||
.mar-top-70 { |
|||
margin-top: 70upx; |
|||
} |
|||
|
|||
.mar-top-100 { |
|||
margin-top: 100upx; |
|||
} |
|||
|
|||
.mar-top-percent40 { |
|||
margin-top: 40%; |
|||
} |
|||
|
|||
.mar-top-half { |
|||
margin-top: 50%; |
|||
} |
|||
|
|||
.mar-left-6 { |
|||
margin-left: 6upx; |
|||
} |
|||
|
|||
.mar-left-5 { |
|||
margin-left: 5upx; |
|||
} |
|||
|
|||
.mar-left-10 { |
|||
margin-left: 10upx; |
|||
} |
|||
|
|||
.mar-left-20 { |
|||
margin-left: 20upx; |
|||
} |
|||
|
|||
.mar-left-30 { |
|||
margin-left: 30upx; |
|||
} |
|||
|
|||
.mar-left-35 { |
|||
margin-left: 35upx; |
|||
} |
|||
|
|||
.mar-left-40 { |
|||
margin-left: 40upx; |
|||
} |
|||
|
|||
.mar-left-50 { |
|||
margin-left: 50upx; |
|||
} |
|||
|
|||
.mar-left-60 { |
|||
margin-left: 60upx; |
|||
} |
|||
|
|||
.mar-left-70 { |
|||
margin-left: 70upx; |
|||
} |
|||
|
|||
.mar-right-10 { |
|||
margin-right: 10upx; |
|||
} |
|||
|
|||
.mar-right-20 { |
|||
margin-right: 20upx; |
|||
} |
|||
|
|||
.mar-right-25 { |
|||
margin-right: 25upx; |
|||
} |
|||
|
|||
.mar-right-30 { |
|||
margin-right: 30upx; |
|||
} |
|||
|
|||
.mar-right-35 { |
|||
margin-right: 35upx; |
|||
} |
|||
|
|||
.mar-right-40 { |
|||
margin-right: 40upx; |
|||
} |
|||
|
|||
.mar-right-50 { |
|||
margin-right: 50upx; |
|||
} |
|||
|
|||
.pad-left-10 { |
|||
padding-left: 10upx; |
|||
} |
|||
|
|||
.pad-left-20 { |
|||
padding-left: 20upx; |
|||
} |
|||
|
|||
.pad-left-40 { |
|||
padding-left: 40upx; |
|||
} |
|||
|
|||
.pad-right-20 { |
|||
padding-right: 20upx; |
|||
} |
|||
|
|||
.pad-top-20 { |
|||
padding-top: 20upx; |
|||
} |
|||
|
|||
.pad-top-40 { |
|||
padding-top: 40upx; |
|||
} |
|||
|
|||
.pad-bot-20 { |
|||
padding-bottom: 20upx; |
|||
} |
|||
|
|||
.pad-topbot-20 { |
|||
padding: 20upx 0upx; |
|||
} |
|||
|
|||
.pad-topbot-5 { |
|||
padding: 0upx 5upx; |
|||
} |
|||
|
|||
.pad-topbot-10 { |
|||
padding: 0upx 10upx; |
|||
} |
|||
|
|||
.pad-topbot-50 { |
|||
padding: 50upx 0upx; |
|||
} |
|||
|
|||
.pad-bot-20 { |
|||
padding-bottom: 20upx; |
|||
} |
|||
|
|||
.pad-bot-30 { |
|||
padding-bottom: 30upx; |
|||
} |
|||
|
|||
.pad-bot-40 { |
|||
padding-bottom: 40upx; |
|||
} |
|||
|
|||
.pad-bot-100 { |
|||
padding-bottom: 100upx; |
|||
} |
|||
|
|||
.pad-bot-140 { |
|||
padding-bottom: 140upx; |
|||
} |
|||
|
|||
.bor-rad-30 { |
|||
border-radius: 30upx; |
|||
} |
|||
|
|||
.bor-rad-45 { |
|||
border-radius: 45upx; |
|||
} |
|||
|
|||
.bor-rad-half { |
|||
border-radius: 50%; |
|||
} |
|||
|
|||
.backColor { |
|||
background-color: #009688; |
|||
} |
|||
|
|||
.backColorFFF { |
|||
background-color: #FFFFFF; |
|||
} |
|||
|
|||
.pos-abs { |
|||
position: absolute; |
|||
} |
|||
|
|||
.bor-bot-line { |
|||
border-bottom: #C8C7CC 1upx solid; |
|||
} |
|||
|
|||
.bor-line-F7F7F7 { |
|||
border-bottom: #F7F7F7 1upx solid; |
|||
} |
|||
|
|||
.bor-line-E5E5E5 { |
|||
border-bottom: #E5E5E5 1upx solid; |
|||
} |
|||
|
|||
.borRig-line-E5E5E5 { |
|||
border-right: #DDDDDD 2upx solid; |
|||
} |
|||
|
|||
.borRig-line-20 { |
|||
border-bottom: #F7F7F7 20upx solid; |
|||
} |
|||
|
|||
.font-color-red { |
|||
color: red; |
|||
} |
|||
|
|||
.font-color-FFF { |
|||
color: #FFFFFF; |
|||
} |
|||
|
|||
.font-color-8A734A { |
|||
color: #8A734A; |
|||
} |
|||
|
|||
.font-color-71521B { |
|||
color: #71521B; |
|||
} |
|||
|
|||
.font-color-222 { |
|||
color: #222222; |
|||
} |
|||
|
|||
.font-color-333 { |
|||
color: #333333; |
|||
} |
|||
|
|||
.font-color-666 { |
|||
color: #666666; |
|||
} |
|||
|
|||
.font-color-999 { |
|||
color: #999999; |
|||
} |
|||
|
|||
.font-color-656 { |
|||
color: #656565; |
|||
} |
|||
|
|||
.font-color-DDD { |
|||
color: #DDDDDD; |
|||
} |
|||
|
|||
.font-color-CCC { |
|||
color: #CCCCCC; |
|||
} |
|||
|
|||
.font-color-FFEBC4 { |
|||
color: #FFEBC4; |
|||
} |
|||
|
|||
.font-color-1CC363 { |
|||
color: #1CC363; |
|||
} |
|||
|
|||
.font-color-47A7EE { |
|||
color: #47A7EE; |
|||
} |
|||
|
|||
.font-color-C5AA7B { |
|||
color: #C5AA7B; |
|||
} |
|||
|
|||
.font-color-FF7700 { |
|||
color: #FF7700; |
|||
} |
|||
|
|||
.font-color-FF7911 { |
|||
color: #FF7911; |
|||
} |
|||
|
|||
.font-color-80 { |
|||
color: #808080; |
|||
} |
|||
|
|||
.font-color-DD { |
|||
color: #DD524D; |
|||
} |
|||
|
|||
.font-color-C83732 { |
|||
color: #C83732; |
|||
} |
|||
|
|||
.font-color-3F { |
|||
color: #3F536E; |
|||
} |
|||
|
|||
.font-color-009 { |
|||
color: #009688; |
|||
} |
|||
|
|||
.font-weight-500 { |
|||
font-weight: 500; |
|||
} |
|||
|
|||
.font-weight-bold { |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.overflow { |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
white-space: nowrap; |
|||
} |
|||
|
|||
.overflowNoDot { |
|||
display: block; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
.discountsPriceLine { |
|||
text-decoration: line-through; |
|||
} |
|||
|
|||
.border-bottom-Line { |
|||
border-bottom: 1upx solid #EDEDED; |
|||
} |
|||
|
|||
.decoration { |
|||
text-decoration: line-through; |
|||
} |
|||
|
|||
.anonymous { |
|||
margin-top: 25upx; |
|||
|
|||
.uni-checkbox-input { |
|||
border-color: #C5AA7B !important; |
|||
width: 30upx; |
|||
height: 30upx; |
|||
} |
|||
|
|||
.uni-checkbox-input-checked:before { |
|||
font-size: 30upx !important; |
|||
} |
|||
|
|||
.uni-checkbox-input-checked { |
|||
background: #C5AA7B; |
|||
} |
|||
} |
|||
|
|||
.footprint { |
|||
.itemList { |
|||
.uni-checkbox-input { |
|||
border-color: #C5AA7B !important; |
|||
width: 36upx; |
|||
height: 36upx; |
|||
border-radius: 50%; |
|||
margin-right: 20upx; |
|||
} |
|||
|
|||
.uni-checkbox-input-checked:before { |
|||
font-size: 36upx !important; |
|||
} |
|||
|
|||
.uni-checkbox-input-checked { |
|||
background: #C5AA7B; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.itemInfo { |
|||
uni-slider { |
|||
margin: 0; |
|||
|
|||
.uni-slider-thumb { |
|||
display: none; |
|||
} |
|||
|
|||
.uni-slider-handle-wrapper { |
|||
height: 18upx; |
|||
border-radius: 0; |
|||
border: 1upx solid #FF736C; |
|||
} |
|||
|
|||
.uni-slider-track { |
|||
border-radius: 0; |
|||
} |
|||
|
|||
.uni-slider-tap-area { |
|||
flex: 0 0 70%; |
|||
padding: 0; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.uni-modal { |
|||
padding: 20rpx; |
|||
box-sizing: border-box; |
|||
} |
|||
|
|||
uni-modal .uni-modal__ft:after { |
|||
border-top: none; |
|||
} |
|||
|
|||
uni-modal .uni-modal__btn { |
|||
color: #333333; |
|||
border: 2rpx solid #333333; |
|||
font-weight: 400; |
|||
margin: 0 10rpx; |
|||
font-size: 28rpx; |
|||
} |
|||
|
|||
.uni-tabbar .uni-tabbar__reddot { |
|||
background: #C5AA7B; |
|||
color: #FFFFFF; |
|||
} |
|||
|
|||
uni-checkbox:not([disabled]) .uni-checkbox-input:hover { |
|||
border-color: #C5AA7B; |
|||
} |
|||
|
|||
.u-arrow { |
|||
display: inline-block; |
|||
width: 20rpx; |
|||
height: 20rpx; |
|||
border-top: 1rpx solid #999; |
|||
border-right: 1rpx solid #999; |
|||
} |
|||
|
|||
.u-arrow-up { |
|||
transform: rotate(-45deg); |
|||
} |
|||
|
|||
.u-arrow-down { |
|||
transform: rotate(135deg); |
|||
} |
|||
|
|||
.u-arrow-left { |
|||
transform: rotate(-135deg); |
|||
} |
|||
|
|||
.u-arrow-right { |
|||
transform: rotate(45deg); |
|||
} |
|||
|
|||
.uni-picker-container .uni-picker-action.uni-picker-action-confirm { |
|||
color: #C5AA7B; |
|||
} |
|||
|
|||
.u-drawer-content { |
|||
//border-radius: 0 !important; |
|||
} |
|||
</style> |
|||
<style> |
|||
.uni-modal__btn_primary { |
|||
background: #333333; |
|||
color: #FFEBC4 !important; |
|||
} |
|||
</style> |
@ -0,0 +1,2 @@ |
|||
FROM registry.cn-shenzhen.aliyuncs.com/sumply-shop/nginx |
|||
COPY unpackage/dist/build/h5/ /home/ui-h5/ |
@ -0,0 +1,269 @@ |
|||
<template> |
|||
<div> |
|||
<u-popup v-model="shareShow" :round="10" mode="bottom" @close="cancel(1)"> |
|||
<view class="share"> |
|||
<!-- <u-mask :show="true" class="flex-items-plus flex-row"> --> |
|||
<text class="h3">邀请好友</text> |
|||
<view class="share-list"> |
|||
<view class="ul"> |
|||
<!-- #ifdef APP-PLUS --> |
|||
<view class="li" @click="share('weixin')"> |
|||
<image class="icon" src="../static/images/share/weixin2x.png"></image> |
|||
<label class="label">微信</label> |
|||
</view> |
|||
<view class="li" @click="share('weixinpyq')"> |
|||
<image class="icon" src="../static/images/share/pyq.png"></image> |
|||
<label class="label">朋友圈</label> |
|||
</view> |
|||
<!-- #endif --> |
|||
<!-- #ifdef MP-WEIXIN --> |
|||
<view class="li"> |
|||
<button open-type="share" @share='onShareAppMessage' :data-obj="wxShareData" class="share-button"> |
|||
<image class="icon" src="../static/images/share/forward.png"></image> |
|||
<label class="label">好友</label> |
|||
</button> |
|||
</view> |
|||
<view class="li" @click="share('weixinpyq')"> |
|||
<image class="icon" src="../static/images/share/pyq.png"></image> |
|||
<label class="label">朋友圈</label> |
|||
</view> |
|||
<!-- #endif --> |
|||
<view class="li" @click="share('lianjie')"> |
|||
<image class="icon" src="../static/images/share/lianjie.png"></image> |
|||
<label class="label">链接</label> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="btn-close" @click="cancel(1)">取消</view> |
|||
</view> |
|||
</u-popup> |
|||
<u-popup v-model="wapShow" :round="10" mode="bottom" :border-radius="10" @close="cancel(2)"> |
|||
<view class="share-h5"> |
|||
<view class="text"> |
|||
点击浏览器下方 |
|||
<view class="icon"> |
|||
<u-icon name="list" color="#fff" size="28"></u-icon> |
|||
</view> |
|||
即可进行分享 |
|||
</view> |
|||
</view> |
|||
</u-popup> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import ClipboardJS from "clipboard" |
|||
import UImage from "../uview-ui/components/u-image/u-image"; |
|||
|
|||
const API = require('../config/api') |
|||
export default { |
|||
components: {UImage}, |
|||
props: { |
|||
img: { |
|||
type: String, |
|||
default: "" |
|||
}, |
|||
url: { |
|||
type: String, |
|||
dafault: '' |
|||
}, |
|||
title: { |
|||
type: String, |
|||
dafault: '' |
|||
}, |
|||
urlParms: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
}, |
|||
onShareAppMessage(e) { |
|||
if(e.from=='button'){ |
|||
// 点击button |
|||
} |
|||
if(e.from=='menu'){ |
|||
// 点击右上角按钮 |
|||
} |
|||
// 获取按钮传进来的参数 data 中的item值 |
|||
let params = e.target.dataset.obj// 获取的为 data 中定义的item值 |
|||
return { |
|||
path: `/pages_category_page1/goodsModule/inviteSpell?${params.url}` |
|||
} |
|||
}, |
|||
name: "share", |
|||
data() { |
|||
return { |
|||
shareShow: false, |
|||
wapShow: false, |
|||
wxShareData: { |
|||
url: '' |
|||
} |
|||
// longUrl: '' |
|||
}; |
|||
}, |
|||
mounted() { |
|||
// this.longUrl = API.shareLink + '/#' + this.url |
|||
// console.log(this.longUrl, this.url |
|||
this.wxShareData = this.url |
|||
}, |
|||
computed:{ |
|||
longUrl(){ |
|||
return API.shareLink + '/#' + this.url |
|||
} |
|||
}, |
|||
methods: { |
|||
cancel(key) { |
|||
if (key === 1) { |
|||
this.shareShow = false |
|||
this.$emit('shareCancel') |
|||
} else if (key === 2) { |
|||
this.wapShow = false |
|||
} |
|||
|
|||
}, |
|||
wxShare(type) { |
|||
// #ifdef APP-PLUS |
|||
uni.share({ |
|||
provider: "weixin", |
|||
type: 0, |
|||
title: this.title, |
|||
scene: type,//WXSceneSession会话 WXSceneTimeline朋友圈 |
|||
imageUrl: this.img, |
|||
href: this.longUrl, |
|||
success: () => { |
|||
}, |
|||
fail: (err) => { |
|||
console.log("err",err) |
|||
} |
|||
}) |
|||
// #endif |
|||
// #ifdef MP-WEIXIN |
|||
uni.showToast({ |
|||
title:"请点击右上角打开菜单进行朋友圈分享", |
|||
icon:"none" |
|||
}) |
|||
// #endif |
|||
}, |
|||
share(key) { |
|||
switch (key) { |
|||
case 'weixin': |
|||
this.wxShare("WXSceneSession") |
|||
break |
|||
case 'weixinpyq': |
|||
|
|||
this.wxShare("WXSceneTimeline") |
|||
break |
|||
case 'qq': |
|||
|
|||
break |
|||
case 'weibo': |
|||
|
|||
break |
|||
case 'lianjie': |
|||
uni.setClipboardData({ |
|||
data: this.title + this.longUrl, |
|||
success: () => { |
|||
uni.showToast({ |
|||
title: '复制成功' |
|||
}) |
|||
} |
|||
}) |
|||
break |
|||
} |
|||
|
|||
}, |
|||
//重写分享方法 |
|||
overShare: function () { |
|||
//监听路由切换 |
|||
//间接实现全局设置分享内容 |
|||
wx.onAppRoute(function (res) { |
|||
//获取加载的页面 |
|||
let pages = getCurrentPages(), |
|||
//获取当前页面的对象 |
|||
view = pages[pages.length - 1], |
|||
data; |
|||
if (view) { |
|||
data = view.data; |
|||
console.log('是否重写分享方法', data.isOverShare); |
|||
if (!data.isOverShare) { |
|||
data.isOverShare = true; |
|||
view.onShareAppMessage = function () { |
|||
//你的分享配置 |
|||
return { |
|||
title: '标题', |
|||
path: '/pages/nearby/index' |
|||
}; |
|||
} |
|||
} |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
<style lang="scss"> |
|||
.share{ |
|||
background-color: #F8F8F8; |
|||
text-align: center; |
|||
.h3{ |
|||
font-size: 30rpx; |
|||
color: #333333; |
|||
line-height: 42rpx; |
|||
padding: 30rpx 0; |
|||
border-bottom: 2px solid #F0F0F0; |
|||
display: block; |
|||
} |
|||
.share-list{ |
|||
padding: 40rpx 0 54rpx; |
|||
.ul{ |
|||
display: flex; |
|||
justify-content: space-around; |
|||
.li{ |
|||
&::after { |
|||
border: none; |
|||
} |
|||
.icon{ |
|||
display: block; |
|||
width: 92rpx; |
|||
height: 92rpx; |
|||
} |
|||
.label{ |
|||
padding-top: 22rpx; |
|||
font-size: 24rpx; |
|||
line-height: 34rpx; |
|||
color: #333333; |
|||
display: block; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.btn-close{ |
|||
background-color: #fff; |
|||
padding: 30rpx 0; |
|||
font-size: 26rpx; |
|||
color: #333; |
|||
} |
|||
} |
|||
|
|||
.share-h5{ |
|||
padding:0 20rpx; |
|||
display: flex; |
|||
justify-content: center; |
|||
.text{ |
|||
line-height: 100rpx; |
|||
font-size: 30px; |
|||
.icon{ |
|||
background-color: #333; |
|||
border-radius: 50%; |
|||
display: inline-block; |
|||
width: 40rpx; |
|||
height: 40rpx; |
|||
text-align: center; |
|||
line-height: 40rpx; |
|||
margin: 0 10rpx; |
|||
} |
|||
} |
|||
} |
|||
.share-button::after { |
|||
border: none; |
|||
} |
|||
</style> |
@ -0,0 +1,388 @@ |
|||
<!-- |
|||
* @FileDescription: 阿里花呗分期支付 |
|||
* @Author: kahu |
|||
* @Date: 2022/11/21 |
|||
* @LastEditors: kahu |
|||
* @LastEditTime: 2022/11/21 |
|||
--> |
|||
<template> |
|||
<view class="ali-hb-pay-content"> |
|||
<u-popup |
|||
class="pay-type-popup" |
|||
v-model="showPopup" |
|||
mode="bottom" |
|||
border-radius="14" |
|||
close-icon-pos="top-right" |
|||
close-icon-size="20" |
|||
> |
|||
<view class="pay-type-item"> |
|||
<radio-group |
|||
@change="payTypeChange" |
|||
v-model="flowerObj.paymentMode" |
|||
> |
|||
<view class="pay-type-radio"> |
|||
<view class="pay-type-img"> |
|||
<img |
|||
class="pay-type-img-inner" |
|||
src="https://ceres.zkthink.com/static/images/alipay.png" |
|||
/> |
|||
</view> |
|||
<label class="pay-type-label">支付宝支付</label> |
|||
<radio |
|||
class="pay-type-radio-item" |
|||
style="transform:scale(0.7)" |
|||
:checked="flowerObj.paymentMode === '2'" |
|||
value="2" |
|||
/> |
|||
</view> |
|||
<view class="pay-type-radio"> |
|||
<view class="pay-type-img"> |
|||
<img |
|||
class="pay-type-img-inner" |
|||
src="https://ceres.zkthink.com/static/images/huabei.png" |
|||
/> |
|||
</view> |
|||
<label class="pay-type-label">花呗分期</label> |
|||
<radio |
|||
class="pay-type-radio-item" |
|||
style="transform:scale(0.7)" |
|||
:disabled="totalPrice < 0.03" |
|||
:checked="flowerObj.paymentMode === '3'" |
|||
value="3" |
|||
/> |
|||
</view> |
|||
</radio-group> |
|||
<view class="huabei-detail" v-if="flowerObj.paymentMode==='3'"> |
|||
<radio-group |
|||
@change="handleChangePeriods" |
|||
v-model="flowerObj.hbByStagesPeriods" |
|||
> |
|||
<view class="period-radio" v-for="stages in flowerObj.hbByStagesList"> |
|||
<view class="period-amount"> |
|||
<label class="period-each">¥ {{ stages.price }}x{{ stages.numberOfStages }}期</label> |
|||
<label class="period-each-charge">手续费¥{{ stages.serviceCharge}}/期</label> |
|||
</view> |
|||
<radio |
|||
class="period-type-radio-item" |
|||
style="transform:scale(0.7)" |
|||
:disabled="stages.disabled" |
|||
:checked="Number(flowerObj.hbByStagesPeriods) === stages.numberOfStages" |
|||
:value="stages.numberOfStages+''" |
|||
/> |
|||
</view> |
|||
</radio-group> |
|||
</view> |
|||
</view> |
|||
<view class="paytype-confirm"> |
|||
<view |
|||
class="fenqi-total-amount" |
|||
v-if="totalPrice >= 0.03 && flowerObj.paymentMode === '3'" |
|||
> |
|||
<label class="fenqi-all">分期总额 ¥{{ totalPrice }}</label> |
|||
<label class="charge-fee-all">手续费 ¥{{ flowerObj.hbServiceChargeTotal }}</label> |
|||
</view> |
|||
<view |
|||
class="fenqi-total-amount" |
|||
v-if="flowerObj.paymentMode === '2'" |
|||
> |
|||
<label class="order-amount">订单总额 ¥{{ totalPrice }}</label> |
|||
</view> |
|||
<view class="fenqi-confirm"> |
|||
<text |
|||
class="btn active" |
|||
@click="handleAliPayConfirm" |
|||
>确认 |
|||
</text> |
|||
</view> |
|||
</view> |
|||
</u-popup> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import NET from "../../utils/request"; |
|||
import API from "../../config/api"; |
|||
import { handleDoPay } from "../../utils/payUtil"; |
|||
|
|||
export default { |
|||
name: "AliHbPay", |
|||
data() { |
|||
return { |
|||
// 花呗相关 |
|||
flowerObj: { |
|||
paymentMode: '2',// 支付方式 1-微信支付 2-支付宝支付 3-花呗分期 |
|||
hbChargeType: 1,// 花呗手续费支付方式 1-商户支付 2-用户支付 后端接口返回 |
|||
hbByStagesPeriods: '-1', // 花呗分期期数 3 6 12 |
|||
hbByStagesList: [ |
|||
{ |
|||
rate: 0, |
|||
price: 0, |
|||
numberOfStages: 3, |
|||
serviceCharge: 0, |
|||
disabled: false |
|||
}, |
|||
{ |
|||
rate: 0, |
|||
price: 0, |
|||
numberOfStages: 6, |
|||
serviceCharge: 0, |
|||
disabled: false |
|||
}, |
|||
{ |
|||
rate: 0, |
|||
price: 0, |
|||
numberOfStages: 12, |
|||
serviceCharge: 0, |
|||
disabled: false |
|||
} |
|||
], // 花呗手续费比例列表 【{3期},{6期},{12期}】 |
|||
hbServiceChargeTotal: 0, // 花呗支付总手续费 |
|||
}, |
|||
} |
|||
}, |
|||
props:{ |
|||
totalPrice:{ |
|||
type:Number | String, |
|||
default:()=>0 |
|||
}, |
|||
show:{ |
|||
type:Boolean, |
|||
default:false |
|||
}, |
|||
alipayInfo:{ |
|||
type:Object, |
|||
default:()=>({}) |
|||
} |
|||
}, |
|||
computed:{ |
|||
showPopup:{ |
|||
get(){ |
|||
return this.show |
|||
}, |
|||
set(value){ |
|||
this.$emit('change',value) |
|||
} |
|||
} |
|||
}, |
|||
model:{ |
|||
prop:'show', |
|||
event:'change' |
|||
}, |
|||
mounted(){ |
|||
this.getTheFlowerConfig() |
|||
}, |
|||
methods: { |
|||
/** |
|||
* 获取花呗分期配置 |
|||
*/ |
|||
async getTheFlowerConfig() { |
|||
const {data} = await NET.request(API.GetHuabeiConfig, {}, 'GET') |
|||
const {flowerObj} = this |
|||
flowerObj.hbChargeType = data.huabeiChargeType |
|||
// 如果后端返回的是用户支付手续费,设置费率信息 |
|||
if (data.huabeiChargeType === 2) { |
|||
data.huabeiFeeRateList.forEach((rate, index) => { |
|||
flowerObj.hbByStagesList[index].rate = rate |
|||
}) |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 处理花呗期数选择 |
|||
* @param event |
|||
*/ |
|||
handleChangePeriods(event) { |
|||
this.flowerObj.hbByStagesPeriods = event |
|||
console.log(event) |
|||
this.handleHbStagesAndPrice() |
|||
}, |
|||
|
|||
/** |
|||
* 处理支付宝支付方式选择逻辑 |
|||
* @param event |
|||
*/ |
|||
payTypeChange(event) { |
|||
const flowerObj = this.flowerObj |
|||
const paymentMode = flowerObj.paymentMode = event.target.value; |
|||
if (paymentMode === '2') { |
|||
// 支付宝支付,取消分期选择 |
|||
flowerObj.hbByStagesPeriods = '-1' |
|||
// 3 6 12 全部禁止 |
|||
flowerObj.hbByStagesList.map(item => { |
|||
item.disabled = true |
|||
}) |
|||
} else { |
|||
// 分期支付,默认选三期 |
|||
flowerObj.hbByStagesPeriods = '3' |
|||
} |
|||
this.handleHbStagesAndPrice() |
|||
}, |
|||
|
|||
/** |
|||
* 处理花呗价格和手续费显示 |
|||
*/ |
|||
handleHbStagesAndPrice() { |
|||
const {flowerObj, totalPrice} = this |
|||
if (flowerObj.paymentMode !== '3') return |
|||
flowerObj.hbByStagesList.forEach(stages => { |
|||
// 根据价格填充每一期价格和手续费信息 |
|||
stages.price = ((totalPrice * (1 + stages.rate / 100)) / stages.numberOfStages).toFixed(2) // 每一期价格 |
|||
stages.serviceCharge = ((totalPrice * (stages.rate / 100)) / stages.numberOfStages).toFixed(2) // 每一期手续费 |
|||
// 计算总手续费 |
|||
if (stages.numberOfStages === Number(flowerObj.hbByStagesPeriods)) { |
|||
flowerObj.hbServiceChargeTotal = (totalPrice * (stages.rate / 100)).toFixed(2) |
|||
} |
|||
// 处理允许分期的区间,公式为总价格要大于分期数/100 |
|||
if (this.totalPrice < stages.numberOfStages / 100) { |
|||
stages.disabled = true |
|||
} |
|||
}) |
|||
}, |
|||
|
|||
/** |
|||
* 确认支付宝支付 |
|||
* @return {Promise<void>} |
|||
*/ |
|||
async handleAliPayConfirm() { |
|||
const payInfo = Object.assign({}, this.alipayInfo, { |
|||
'paymentMode': this.flowerObj.paymentMode, |
|||
'huabeiPeriod': this.flowerObj.hbByStagesPeriods |
|||
}); |
|||
await handleDoPay.call(this, payInfo) |
|||
this.$emit('confirm',{ |
|||
'paymentMode': this.flowerObj.paymentMode, |
|||
'huabeiPeriod': this.flowerObj.hbByStagesPeriods |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style |
|||
lang="scss" |
|||
scoped |
|||
> |
|||
.pay-type-item { |
|||
.pay-type-radio { |
|||
background-color: white; |
|||
border-bottom: 1upx solid #EDEDED; |
|||
margin-bottom: 20upx; |
|||
padding: 24upx 20upx 24upx 20upx; |
|||
|
|||
.pay-type-img { |
|||
display: inline-block; |
|||
|
|||
.pay-type-img-inner { |
|||
width: 50upx; |
|||
height: 50upx; |
|||
vertical-align: middle; |
|||
} |
|||
} |
|||
|
|||
.pay-type-label { |
|||
vertical-align: middle; |
|||
margin-left: 30upx; |
|||
} |
|||
|
|||
.pay-type-radio-item { |
|||
float: right; |
|||
margin-right: 20upx; |
|||
width: 50upx; |
|||
height: 50upx; |
|||
} |
|||
} |
|||
|
|||
.huabei-detail { |
|||
margin-top: 20upx; |
|||
|
|||
.fenqi-wenzi { |
|||
display: inline-block; |
|||
margin-left: 64upx; |
|||
} |
|||
|
|||
.fenqi-amount { |
|||
display: block; |
|||
margin-left: 64upx; |
|||
margin-top: 14upx; |
|||
color: #BABBBC; |
|||
} |
|||
|
|||
.fenqi-charge-fee { |
|||
float: right; |
|||
margin-right: 68upx; |
|||
color: #BABBBC; |
|||
} |
|||
|
|||
.fenqi-modal { |
|||
width: 40upx; |
|||
height: 40upx; |
|||
margin-left: 20upx; |
|||
float: right; |
|||
position: relative; |
|||
top: -80upx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.paytype-confirm { |
|||
height: 120upx; |
|||
padding: 0upx 108upx 0upx 32upx; |
|||
|
|||
.fenqi-all { |
|||
display: inline-block; |
|||
width: 100%; |
|||
} |
|||
|
|||
.fenqi-total-amount { |
|||
width: 65%; |
|||
float: left; |
|||
} |
|||
|
|||
.fenqi-confirm { |
|||
float: right; |
|||
width: 160upx; |
|||
padding: 0upx 20upx; |
|||
|
|||
.btn { |
|||
width: 216upx; |
|||
height: 80upx; |
|||
line-height: 80upx; |
|||
border-radius: 40upx; |
|||
font-size: 28upx; |
|||
text-align: center; |
|||
background: linear-gradient(90deg, rgba(255, 162, 0, 1), rgba(255, 121, 17, 1)); |
|||
color: #fff; |
|||
display: inline-block; |
|||
margin-right: 66upx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.period-radio { |
|||
margin: 30upx; |
|||
padding-right: 100upx; |
|||
width: 95%; |
|||
border-bottom: 1px solid #EFEFEF; |
|||
|
|||
.period-amount { |
|||
display: inline-block; |
|||
|
|||
.period-each-charge { |
|||
display: inline-block; |
|||
margin-top: 12upx; |
|||
margin-left: 6upx; |
|||
font-size: 26upx; |
|||
color: #b7b7b7; |
|||
margin-bottom: 13upx; |
|||
} |
|||
} |
|||
|
|||
.period-each { |
|||
display: block; |
|||
} |
|||
|
|||
.period-type-radio-item { |
|||
float: right; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,320 @@ |
|||
<!-- |
|||
* @FileDescription: 收银台 |
|||
* @Author: kahu |
|||
* @Date: 2022/11/21 |
|||
* @LastEditors: kahu |
|||
* @LastEditTime: 2022/11/21 |
|||
--> |
|||
<template> |
|||
<view class="cashier-list-content"> |
|||
<u-radio-group |
|||
v-model="paymentMode" |
|||
placement="row" |
|||
iconPlacement="right" |
|||
@change="handleChangePaymentMode" |
|||
> |
|||
<view |
|||
class="cashier" |
|||
v-for="payment in paymentList" |
|||
:key="payment.id" |
|||
> |
|||
<view class="cashier-item" @click="handleChangePaymentMode(payment.paymentMode,payment.disabled)" |
|||
> |
|||
<view class="icon-text"> |
|||
<image |
|||
class="pay-type-img-inner" |
|||
:src="payment.icon" |
|||
mode="widthFix" |
|||
/> |
|||
{{ payment.label }} |
|||
<span v-if="paymentMode===3 && paymentMode === payment.paymentMode">(手续费:¥{{ flowerObj.hbServiceChargeTotal }})</span> |
|||
</view> |
|||
<view class="radio"> |
|||
<u-radio |
|||
:disabled="payment.disabled" |
|||
activeColor="#c5aa7b" |
|||
:name="payment.paymentMode" |
|||
/> |
|||
</view> |
|||
</view> |
|||
<!-- 花呗分期 --> |
|||
<view |
|||
class="ali-hb-content" |
|||
v-if="paymentMode===3 && paymentMode === payment.paymentMode" |
|||
> |
|||
<u-radio-group |
|||
v-model="flowerObj.hbByStagesPeriods" |
|||
placement="row" |
|||
iconPlacement="right" |
|||
@change="handleChangePeriods" |
|||
> |
|||
<view |
|||
class="cashier" |
|||
v-for="(flowerItem,index) in flowerObj.hbByStagesList" |
|||
:key="index" |
|||
> |
|||
<view class="cashier-item" @click="handleChangePeriods(flowerItem.numberOfStages,flowerItem.disabled)"> |
|||
<view class="icon-text"> |
|||
{{ flowerItem.numberOfStages }}期(¥{{ flowerItem.price }}/期) |
|||
</view> |
|||
<view class="radio-context"> |
|||
手续费:¥{{ flowerItem.serviceCharge }}/期 |
|||
<u-radio |
|||
class="radio" |
|||
activeColor="#c5aa7b" |
|||
:disabled="flowerItem.disabled" |
|||
:name="flowerItem.numberOfStages" |
|||
/> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</u-radio-group> |
|||
</view> |
|||
</view> |
|||
</u-radio-group> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import NET from "../../utils/request"; |
|||
import API from "../../config/api"; |
|||
|
|||
export default { |
|||
name: "CashierList", |
|||
props: { |
|||
totalPrice: { |
|||
type: Number, |
|||
default: () => 200 |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
paymentMode: 1, // 支付方式 1微信 2支付宝 3花呗分期 |
|||
paymentList: [ |
|||
{ |
|||
id: 1, |
|||
label: '微信支付', |
|||
paymentMode: 1, |
|||
icon: 'https://ceres.zkthink.com/static/images/wechat_pay.png', |
|||
disabled:false |
|||
}, |
|||
{ |
|||
id: 2, |
|||
label: '支付宝支付', |
|||
paymentMode: 2, |
|||
icon: 'https://ceres.zkthink.com/static/images/alipay.png', |
|||
disabled:false |
|||
}, |
|||
{ |
|||
id: 3, |
|||
label: '花呗分期', |
|||
paymentMode: 3, |
|||
icon: 'https://ceres.zkthink.com/static/images/huabei.png', |
|||
disabled:false |
|||
} |
|||
], |
|||
// 花呗相关 |
|||
flowerObj: { |
|||
hbChargeType: 1,// 花呗手续费支付方式 1-商户支付 2-用户支付 后端接口返回 |
|||
hbByStagesPeriods: -1, // 花呗分期期数 3 6 12 |
|||
hbByStagesList: [ |
|||
{ |
|||
rate: 0, |
|||
price: 0, |
|||
numberOfStages: 3, |
|||
serviceCharge: 0, |
|||
disabled: false |
|||
}, |
|||
{ |
|||
rate: 0, |
|||
price: 0, |
|||
numberOfStages: 6, |
|||
serviceCharge: 0, |
|||
disabled: false |
|||
}, |
|||
{ |
|||
rate: 0, |
|||
price: 0, |
|||
numberOfStages: 12, |
|||
serviceCharge: 0, |
|||
disabled: false |
|||
} |
|||
], // 花呗手续费比例列表 【{3期},{6期},{12期}】 |
|||
hbServiceChargeTotal: 0, // 花呗支付总手续费 |
|||
}, |
|||
} |
|||
}, |
|||
mounted(){ |
|||
this.getTheFlowerConfig() |
|||
this.handleSetDisable() |
|||
this.handleNoticeFather() |
|||
}, |
|||
methods: { |
|||
/** |
|||
* 根据环境更改可选支付项 |
|||
*/ |
|||
handleSetDisable(){ |
|||
// #ifdef MP-WEIXIN |
|||
this.paymentList[0].disabled = false |
|||
this.paymentList[1].disabled = true |
|||
this.paymentList[2].disabled = true |
|||
this.paymentMode = 1 |
|||
// #endif |
|||
// #ifdef MP-ALIPAY |
|||
this.paymentList[0].disabled = true |
|||
this.paymentList[1].disabled = false |
|||
this.paymentList[2].disabled = false |
|||
this.paymentMode = 2 |
|||
// #endif |
|||
// #ifdef APP-PLUS || H5 |
|||
this.paymentList[0].disabled = false |
|||
this.paymentList[1].disabled = true |
|||
this.paymentList[2].disabled = true |
|||
this.paymentMode = 1 |
|||
// #endif |
|||
}, |
|||
/** |
|||
* 支付方式改变事件 |
|||
* @param paymentMode |
|||
* @param disabled |
|||
*/ |
|||
handleChangePaymentMode(paymentMode,disabled=false) { |
|||
if(disabled) return |
|||
this.paymentMode = paymentMode |
|||
const { flowerObj } = this |
|||
if ([1, 2].includes(paymentMode)) { |
|||
// 支付宝支付,取消分期选择 |
|||
flowerObj.hbByStagesPeriods = -1 |
|||
// 3 6 12 全部禁止 |
|||
flowerObj.hbByStagesList.map(item => { |
|||
item.disabled = true |
|||
}) |
|||
} else { |
|||
// 分期支付,默认选三期 |
|||
flowerObj.hbByStagesPeriods = 3 |
|||
} |
|||
this.handleHbStagesAndPrice() |
|||
this.handleNoticeFather() |
|||
}, |
|||
|
|||
/** |
|||
* 获取花呗分期配置 |
|||
*/ |
|||
async getTheFlowerConfig() { |
|||
const {data} = await NET.request(API.GetHuabeiConfig, {}, 'GET') |
|||
const {flowerObj} = this |
|||
flowerObj.hbChargeType = data.huabeiChargeType |
|||
// 如果后端返回的是用户支付手续费,设置费率信息 |
|||
if (data.huabeiChargeType === 1) { |
|||
data.huabeiFeeRateList.forEach((rate, index) => { |
|||
flowerObj.hbByStagesList[index].rate = rate |
|||
}) |
|||
} |
|||
console.log(flowerObj) |
|||
}, |
|||
|
|||
/** |
|||
* 处理花呗期数选择 |
|||
* @param periods 期数 |
|||
* @param disabled |
|||
*/ |
|||
handleChangePeriods(periods,disable=false) { |
|||
if(disable)return |
|||
const { flowerObj } = this |
|||
flowerObj.hbByStagesPeriods = periods |
|||
this.handleHbStagesAndPrice() |
|||
this.handleNoticeFather() |
|||
}, |
|||
|
|||
/** |
|||
* 处理花呗价格和手续费显示 |
|||
*/ |
|||
handleHbStagesAndPrice() { |
|||
const {flowerObj, totalPrice} = this |
|||
if (this.paymentMode !== 3) return |
|||
flowerObj.hbByStagesList.forEach(stages => { |
|||
// 根据价格填充每一期价格和手续费信息 |
|||
stages.price = ((totalPrice * (1 + stages.rate / 100)) / stages.numberOfStages).toFixed(2) // 每一期价格 |
|||
stages.serviceCharge = ((totalPrice * (stages.rate / 100)) / stages.numberOfStages).toFixed(2) // 每一期手续费 |
|||
// 计算总手续费 |
|||
if (stages.numberOfStages === Number(flowerObj.hbByStagesPeriods)) { |
|||
flowerObj.hbServiceChargeTotal = (totalPrice * (stages.rate / 100)).toFixed(2) |
|||
} |
|||
// 处理允许分期的区间,公式为总价格要大于分期数/100 |
|||
this.totalPrice < stages.numberOfStages / 100?stages.disabled = true:stages.disabled = false |
|||
}) |
|||
}, |
|||
|
|||
/** |
|||
* 通知父组件 |
|||
*/ |
|||
handleNoticeFather(){ |
|||
const { paymentMode,flowerObj } = this |
|||
const params = { |
|||
paymentMode, |
|||
huabeiPeriod:flowerObj.hbByStagesPeriods |
|||
} |
|||
this.$emit('change',params) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style |
|||
lang="scss" |
|||
scoped |
|||
> |
|||
.cashier-list-content { |
|||
width: 100%; |
|||
padding: 0rpx 15rpx; |
|||
box-sizing: border-box; |
|||
background: #fff; |
|||
|
|||
.u-radio-group { |
|||
display: block !important; |
|||
} |
|||
|
|||
.cashier { |
|||
border-bottom: 2rpx solid #d0d0d0; |
|||
|
|||
&:last-child { |
|||
border-bottom: none |
|||
} |
|||
|
|||
.cashier-item { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding: 20rpx 0; |
|||
box-sizing: border-box; |
|||
position: relative; |
|||
|
|||
.icon-text { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
|
|||
image { |
|||
width: 50rpx; |
|||
height: 50rpx; |
|||
margin-right: 15rpx; |
|||
} |
|||
} |
|||
.radio-context{ |
|||
display: flex; |
|||
align-items: center; |
|||
font-size: 14rpx; |
|||
.radio{ |
|||
margin-left: 15rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.ali-hb-content { |
|||
padding: 10rpx 20px; |
|||
box-sizing: border-box; |
|||
border-top: 2rpx solid #d0d0d0; |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,72 @@ |
|||
<!-- |
|||
* @FileDescription: index |
|||
* @Author: kahu |
|||
* @Date: 2022/11/11 |
|||
* @LastEditors: kahu |
|||
* @LastEditTime: 2022/11/11 |
|||
--> |
|||
<template> |
|||
<view v-if="show" class="empty-content" :style="{ |
|||
paddingTop: this.paddingTop+'rpx', |
|||
background: this.background |
|||
}"> |
|||
<image :src="iconUrl" /> |
|||
<p class="tips"> |
|||
<slot> |
|||
暂无数据~ |
|||
</slot> |
|||
</p> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: "empty", |
|||
data() { |
|||
return {} |
|||
}, |
|||
props:{ |
|||
show:{ |
|||
type:Boolean, |
|||
default:false |
|||
}, |
|||
paddingTop:{ |
|||
type:Number, |
|||
default:()=>500 |
|||
}, |
|||
background:{ |
|||
type:String, |
|||
default:()=>'#f8f8f8' |
|||
}, |
|||
iconUrl:{ |
|||
type:String, |
|||
default:()=>'https://ceres.zkthink.com/static/images/searchEmpty.png' |
|||
} |
|||
}, |
|||
computed:{ |
|||
|
|||
}, |
|||
methods: {} |
|||
} |
|||
</script> |
|||
|
|||
<style |
|||
lang="scss" |
|||
scoped |
|||
> |
|||
.empty-content{ |
|||
display: flex; |
|||
justify-content: center; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
image{ |
|||
width:150rpx; |
|||
height: 150rpx; |
|||
} |
|||
.tips{ |
|||
margin-top: 25rpx; |
|||
font-weight: bolder; |
|||
} |
|||
} |
|||
|
|||
</style> |
@ -0,0 +1,24 @@ |
|||
import Vue from 'vue' |
|||
import store from "../../store"; |
|||
import GlobalLoading from "./index.vue"; |
|||
export function showLoading(info=''){ |
|||
store.commit("SET_SHOW_LOADING",{flag:true,info}) |
|||
} |
|||
|
|||
export function hideLoading(){ |
|||
store.commit("SET_SHOW_LOADING",{flag:false,info:''}) |
|||
} |
|||
|
|||
export function showLoadingAuto(info='',time = 2000){ |
|||
store.commit("SET_SHOW_LOADING",{flag:true,info}) |
|||
setTimeout(()=>{ |
|||
store.commit("SET_SHOW_LOADING",{flag:false,info:''}) |
|||
},time) |
|||
} |
|||
|
|||
Vue.prototype.$showLoading = showLoading |
|||
Vue.prototype.$hideLoading = hideLoading |
|||
Vue.prototype.$showLoadingAuto = showLoadingAuto |
|||
// Vue.component("globalLoading",GlobalLoading)
|
|||
|
|||
// export default GlobalLoading
|
@ -0,0 +1,89 @@ |
|||
<template> |
|||
<view class="loading-content" v-if="loadingFlag" @touchmove.stop.prevent="moveHandle" |
|||
@click.stop.prevent="moveHandle"> |
|||
<!-- 遮罩 --> |
|||
<view catchtouchmove="true" class="full-mask" v-if="false"/> |
|||
<!-- loading --> |
|||
<view class="loading-gif"> |
|||
<view class="flex mask"> |
|||
<image src="@/static/images/loading/loading.gif"></image> |
|||
<!-- <p> {{ loadingInfo }} </p>--> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import {mapGetters} from 'vuex' |
|||
|
|||
export default { |
|||
name: "GlobalLoading", |
|||
methods: { |
|||
moveHandle() { |
|||
return; |
|||
} |
|||
}, |
|||
mounted() { |
|||
console.log("+++++++++++++++++++__++++++++++++++++++++") |
|||
console.log(this.loadingFlag, this.loadingInfo) |
|||
}, |
|||
computed: { |
|||
...mapGetters(["loadingFlag", "loadingInfo"]) |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.loading-content { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100vw; |
|||
height: 100vh; |
|||
z-index: 9999; |
|||
//pointer-events: none; |
|||
|
|||
.mask { |
|||
//background-color: rgba(75, 53, 53, 0.52); |
|||
} |
|||
|
|||
.full-mask { |
|||
position: absolute; |
|||
width: 100vw; |
|||
height: 100vh; |
|||
background-color: rgba(0, 0, 0, 0.52); |
|||
z-index: 9998; |
|||
pointer-events: none; |
|||
} |
|||
|
|||
.loading-gif { |
|||
z-index: 9999; |
|||
position: relative; |
|||
width: 100%; |
|||
height: 100%; |
|||
|
|||
.flex { |
|||
width: 200rpx; |
|||
height: 200rpx; |
|||
position: absolute; |
|||
border-radius: 15rpx; |
|||
top: 50%; |
|||
left: 50%; |
|||
transform: translate(-50%, -50%); |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
flex-direction: column; |
|||
|
|||
image { |
|||
width: 150rpx; |
|||
height: 150rpx; |
|||
} |
|||
|
|||
p { |
|||
color: #fff; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,250 @@ |
|||
<!-- @auth kahu --> |
|||
<template> |
|||
<view class="loading_box mask flex-center" |
|||
@touchmove.stop.prevent="HandlePageMove"> |
|||
<!-- 点动画 --> |
|||
<view class="dot_box theOuterRotation" |
|||
v-if="false"> |
|||
<view class="dot_item" |
|||
v-for="item in 4"></view> |
|||
</view> |
|||
|
|||
<!-- 进度条动画 --> |
|||
<view class="progress_box" v-if="false"> |
|||
<view class="progress_item progress_roll_center"></view> |
|||
</view> |
|||
Loading.... |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: "index", |
|||
data() { |
|||
return {} |
|||
|
|||
}, |
|||
onPageScroll(e) { |
|||
return false |
|||
}, |
|||
|
|||
mounted() { |
|||
console.log(getCurrentPages()) |
|||
//#ifdef H5 |
|||
//#endif |
|||
}, |
|||
|
|||
methods: { |
|||
HandlePageMove() { |
|||
return false |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" |
|||
scoped> |
|||
.mask { |
|||
width: 100vw; |
|||
height: 100vh; |
|||
background: rgba(0, 0, 0, 0.5); |
|||
color: #fff; |
|||
} |
|||
|
|||
.flex-center { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
flex-direction: column; |
|||
} |
|||
|
|||
.loading_box { |
|||
width: 100vw; |
|||
height: 100vh; |
|||
position: fixed; |
|||
top: 0; |
|||
bottom: 0; |
|||
z-index: 9999; |
|||
|
|||
/** 点动画*/ |
|||
.theOuterRotation { |
|||
animation: rotate 2s ease-in-out .5s infinite normal; |
|||
} |
|||
|
|||
.dot_box { |
|||
width: 80rpx; |
|||
height: 80rpx; |
|||
//background: #fff; |
|||
border-radius: 20rpx; |
|||
margin: 20rpx 0; |
|||
position: relative; |
|||
|
|||
// 原始dot |
|||
.dot_item { |
|||
width: 30rpx; |
|||
height: 30rpx; |
|||
background: #fff; |
|||
border-radius: 50%; |
|||
position: absolute; |
|||
transition: all .6s; |
|||
box-shadow: 0 0 2rpx #b4b4b4; |
|||
|
|||
&:nth-child(1) { |
|||
top: 0; |
|||
left: 0; |
|||
} |
|||
|
|||
&:nth-child(2) { |
|||
top: 0; |
|||
right: 0; |
|||
} |
|||
|
|||
&:nth-child(3) { |
|||
bottom: 0; |
|||
right: 0; |
|||
} |
|||
|
|||
&:nth-child(4) { |
|||
bottom: 0; |
|||
left: 0; |
|||
} |
|||
} |
|||
|
|||
// 单双放大动画 |
|||
.dot_scale { |
|||
&:nth-child(1) { |
|||
top: 0; |
|||
left: 0; |
|||
animation: magnify 2s ease-in-out 0s infinite alternate; |
|||
} |
|||
|
|||
&:nth-child(2) { |
|||
top: 0; |
|||
right: 0; |
|||
animation: magnify 2s ease-in-out 1s infinite alternate; |
|||
} |
|||
|
|||
&:nth-child(3) { |
|||
bottom: 0; |
|||
right: 0; |
|||
animation: magnify 2s ease-in-out 0s infinite alternate; |
|||
} |
|||
|
|||
&:nth-child(4) { |
|||
bottom: 0; |
|||
left: 0; |
|||
animation: magnify 2s ease-in-out 1s infinite alternate; |
|||
} |
|||
} |
|||
|
|||
// 单点移动动画 |
|||
.dot_move { |
|||
&:nth-child(1) { |
|||
z-index: 2; |
|||
animation: moveDot 2s ease-in-out 0s infinite normal; |
|||
} |
|||
} |
|||
|
|||
// 单偶放大 |
|||
@keyframes magnify { |
|||
0% { |
|||
transform: scale(1); |
|||
background: rgba(0, 255, 228, 0.82); |
|||
} |
|||
25% { |
|||
background: #32b5cc; |
|||
} |
|||
50% { |
|||
transform: scale(1.4); |
|||
background: #73e34e; |
|||
} |
|||
75% { |
|||
background: #0ec469; |
|||
} |
|||
100% { |
|||
transform: scale(1); |
|||
background: #868686; |
|||
} |
|||
} |
|||
|
|||
// 移动单点 |
|||
@keyframes moveDot { |
|||
0% { |
|||
top: 0; |
|||
left: 0; |
|||
background: #d0f598; |
|||
} |
|||
25% { |
|||
top: 0; |
|||
left: 100%; |
|||
transform: translateX(-100%); |
|||
background: #f5e298; |
|||
} |
|||
50% { |
|||
top: 100%; |
|||
left: 100%; |
|||
transform: translate(-100%, -100%); |
|||
background: #6bea91; |
|||
} |
|||
75% { |
|||
top: 100%; |
|||
left: 0; |
|||
transform: translateY(-100%); |
|||
background: #e84c7a; |
|||
} |
|||
100% { |
|||
top: 0; |
|||
left: 0; |
|||
} |
|||
|
|||
} |
|||
|
|||
@keyframes rotate { |
|||
0% { |
|||
transform: rotate(0deg); |
|||
} |
|||
100% { |
|||
transform: rotate(360deg); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
/** 进度条动画*/ |
|||
.progress_box{ |
|||
width: 300rpx; |
|||
height: 25rpx; |
|||
margin: 20rpx 0; |
|||
border-radius: 25rpx; |
|||
background-color: #fff; |
|||
position: relative; |
|||
overflow: hidden; |
|||
.progress_item{ |
|||
width: 0%; |
|||
height: 100%; |
|||
background: #f68686; |
|||
border-radius: 25rpx; |
|||
|
|||
} |
|||
.progress_roll{ |
|||
animation: roll 1s ease-in-out 0s infinite alternate-reverse; |
|||
} |
|||
.progress_roll_center{ |
|||
width: 5%; |
|||
transition: all .6s; |
|||
margin: 0 auto; |
|||
animation: roll 1s cubic-bezier(.15,.2,.05,.4) 0s infinite alternate-reverse; |
|||
} |
|||
} |
|||
|
|||
@keyframes roll { |
|||
from{ |
|||
width: 5%; |
|||
} |
|||
to{ |
|||
width: 100%; |
|||
} |
|||
} |
|||
|
|||
} |
|||
</style> |
@ -0,0 +1,54 @@ |
|||
<!-- |
|||
* @FileDescription: index.vue |
|||
* @Author: kahu |
|||
* @Date: 2022/11/21 |
|||
* @LastEditors: kahu |
|||
* @LastEditTime: 2022/11/21 |
|||
--> |
|||
<template> |
|||
<view class="no-more-content" v-if="show"> |
|||
<view class="line" /> |
|||
<view class="text"> |
|||
<slot>没有更多了</slot> |
|||
</view> |
|||
<view class="line" /> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: "NoMore", |
|||
data() { |
|||
return {} |
|||
}, |
|||
props:{ |
|||
show:{ |
|||
type:Boolean, |
|||
default:false |
|||
} |
|||
}, |
|||
methods: {} |
|||
} |
|||
</script> |
|||
|
|||
<style |
|||
lang="scss" |
|||
scoped |
|||
> |
|||
.no-more-content{ |
|||
margin-top: 35rpx; |
|||
width: 100%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
.line{ |
|||
width: 20vw; |
|||
height: 2rpx; |
|||
background-color: #808080; |
|||
} |
|||
.text{ |
|||
color: #808080; |
|||
margin: 0 50rpx; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,200 @@ |
|||
<template> |
|||
<view v-if="loading" :style="{ |
|||
width: windowWinth + 'px', |
|||
height: windowHeight + 'px', |
|||
backgroundColor: bgColor, |
|||
position: 'absolute', |
|||
left: left + 'px', |
|||
top: top + 'px', |
|||
zIndex: 100, |
|||
overflow: 'hidden' |
|||
}" |
|||
@touchmove.stop.prevent> |
|||
<view v-for="(item, index) in RectNodes" :key="$u.guid()" :class="[animation ? 'skeleton-fade' : '']" :style="{ |
|||
width: item.width + 'px', |
|||
height: item.height + 'px', |
|||
backgroundColor: elColor, |
|||
position: 'absolute', |
|||
left: (item.left - left) + 'px', |
|||
top:(item.top - top)<0?(item.top - top +windowHeight-80)+ 'px':(item.top - top) + 'px' |
|||
}"></view> |
|||
<view v-for="(item, index) in circleNodes" :key="$u.guid()" :class="animation ? 'skeleton-fade' : ''" :style="{ |
|||
width: item.width + 'px', |
|||
height: item.height + 'px', |
|||
backgroundColor: elColor, |
|||
borderRadius: item.width/2 + 'px', |
|||
position: 'absolute', |
|||
left: (item.left - left) + 'px', |
|||
top:(item.top - top)<0?(item.top - top +windowHeight-80)+ 'px':(item.top - top) + 'px' |
|||
}"></view> |
|||
<view v-for="(item, index) in filletNodes" :key="$u.guid()" :class="animation ? 'skeleton-fade' : ''" :style="{ |
|||
width: item.width + 'px', |
|||
height: item.height + 'px', |
|||
backgroundColor: elColor, |
|||
borderRadius: borderRadius + 'rpx', |
|||
position: 'absolute', |
|||
left: (item.left - left) + 'px', |
|||
top:(item.top - top)<0?(item.top - top +windowHeight-80)+ 'px':(item.top - top) + 'px' |
|||
}"> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
/** |
|||
* skeleton 骨架屏 |
|||
* @description 骨架屏一般用于页面在请求远程数据尚未完成时,页面用灰色块预显示本来的页面结构,给用户更好的体验。 |
|||
* @tutorial https://www.uviewui.com/components/skeleton.html |
|||
* @property {String} el-color 骨架块状元素的背景颜色(默认#e5e5e5) |
|||
* @property {String} bg-color 骨架组件背景颜色(默认#ffffff) |
|||
* @property {Boolean} animation 骨架块是否显示动画效果(默认false) |
|||
* @property {String Number} border-radius u-skeleton-fillet类名元素,对应的骨架块的圆角大小,单位rpx(默认10) |
|||
* @property {Boolean} loading 是否显示骨架组件,请求完成后,将此值设置为false(默认true) |
|||
* @example <u-skeleton :loading="true" :animation="true"></u-skeleton> |
|||
*/ |
|||
export default { |
|||
name: "u-skeleton", |
|||
props: { |
|||
// 需要渲染的元素背景颜色,十六进制或者rgb等都可以 |
|||
elColor: { |
|||
type: String, |
|||
default: '#e5e5e5' |
|||
}, |
|||
// 整个骨架屏页面的背景颜色 |
|||
bgColor: { |
|||
type: String, |
|||
default: '#ffffff' |
|||
}, |
|||
// 是否显示加载动画 |
|||
animation: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
// 圆角值,只对类名为u-skeleton-fillet的元素生效,为数值,不带单位 |
|||
borderRadius: { |
|||
type: [String, Number], |
|||
default: "10" |
|||
}, |
|||
// 是否显示骨架,true-显示,false-隐藏 |
|||
loading: { |
|||
type: Boolean, |
|||
default: true |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
windowWinth: 750, // 骨架屏宽度 |
|||
windowHeight: 1500, // 骨架屏高度 |
|||
filletNodes: [], // 圆角元素 |
|||
circleNodes: [], // 圆形元素 |
|||
RectNodes: [], // 矩形元素 |
|||
top: 0, |
|||
left: 0, |
|||
} |
|||
}, |
|||
methods: { |
|||
// 查询各节点的信息 |
|||
selecterQueryInfo() { |
|||
// 获取整个父组件容器的高度,当做骨架屏的高度 |
|||
// 在微信小程序中,如果把骨架屏放入组件中使用的话,需要调in(this)上下文为父组件才有效 |
|||
let query = ''; |
|||
// #ifdef MP-WEIXIN |
|||
query = uni.createSelectorQuery().in(this.$parent); |
|||
// #endif |
|||
// #ifndef MP-WEIXIN |
|||
query = uni.createSelectorQuery() |
|||
// #endif |
|||
query.selectAll('.u-skeleton').boundingClientRect().exec((res) => { |
|||
this.windowHeight = res[0][0].height; |
|||
this.windowWinth = res[0][0].width; |
|||
res[0][0].bottom = res[0][0].height |
|||
this.top = res[0][0].bottom - res[0][0].height; |
|||
this.left = res[0][0].left; |
|||
}); |
|||
// 矩形骨架元素 |
|||
this.getRectEls(); |
|||
// 圆形骨架元素 |
|||
this.getCircleEls(); |
|||
// 圆角骨架元素 |
|||
this.getFilletEls(); |
|||
}, |
|||
// 矩形元素列表 |
|||
getRectEls() { |
|||
let query = ''; |
|||
// 在微信小程序中,如果把骨架屏放入组件中使用的话,需要调in(this)上下文为父组件才有效 |
|||
// #ifdef MP-WEIXIN |
|||
query = uni.createSelectorQuery().in(this.$parent); |
|||
// #endif |
|||
// #ifndef MP-WEIXIN |
|||
query = uni.createSelectorQuery() |
|||
// #endif |
|||
query.selectAll('.u-skeleton-rect').boundingClientRect().exec((res) => { |
|||
this.RectNodes = res[0]; |
|||
}); |
|||
}, |
|||
// 圆角元素列表 |
|||
getFilletEls() { |
|||
let query = ''; |
|||
// 在微信小程序中,如果把骨架屏放入组件中使用的话,需要调in(this)上下文为父组件才有效 |
|||
// #ifdef MP-WEIXIN |
|||
query = uni.createSelectorQuery().in(this.$parent); |
|||
// #endif |
|||
// #ifndef MP-WEIXIN |
|||
query = uni.createSelectorQuery() |
|||
// #endif |
|||
query.selectAll('.u-skeleton-fillet').boundingClientRect().exec((res) => { |
|||
this.filletNodes = res[0]; |
|||
}); |
|||
}, |
|||
// 圆形元素列表 |
|||
getCircleEls() { |
|||
let query = ''; |
|||
// 在微信小程序中,如果把骨架屏放入组件中使用的话,需要调in(this)上下文为父组件才有效 |
|||
// #ifdef MP-WEIXIN |
|||
query = uni.createSelectorQuery().in(this.$parent); |
|||
// #endif |
|||
// #ifndef MP-WEIXIN |
|||
query = uni.createSelectorQuery() |
|||
// #endif |
|||
query.selectAll('.u-skeleton-circle').boundingClientRect().exec((res) => { |
|||
this.circleNodes = res[0]; |
|||
}); |
|||
} |
|||
}, |
|||
// 组件被挂载 |
|||
mounted() { |
|||
// 获取系统信息 |
|||
let systemInfo = uni.getSystemInfoSync(); |
|||
this.windowHeight = systemInfo.windowHeight; |
|||
this.windowWinth = systemInfo.windowWidth; |
|||
this.selecterQueryInfo(); |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
|
|||
.skeleton-fade { |
|||
width: 100%; |
|||
height: 100%; |
|||
background: rgb(194, 207, 214); |
|||
animation-duration: 1.5s; |
|||
animation-name: blink; |
|||
animation-timing-function: ease-in-out; |
|||
animation-iteration-count: infinite; |
|||
} |
|||
|
|||
@keyframes blink { |
|||
0% { |
|||
opacity: 1; |
|||
} |
|||
|
|||
50% { |
|||
opacity: 0.4; |
|||
} |
|||
|
|||
100% { |
|||
opacity: 1; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,633 @@ |
|||
<template> |
|||
<view class="group-list" v-if="selectComposeData && selectComposeData.length > 0"> |
|||
<view class="group-warp"> |
|||
<view class="title"> |
|||
<label> |
|||
<image class="title-img" src="https://ceres.zkthink.com/static/images/combinationIcon.png" alt="组合销售" mode="widthFix"></image> |
|||
</label> |
|||
<view class="price-text"> |
|||
组合价:¥{{composePrice}} |
|||
</view> |
|||
</view> |
|||
<view> |
|||
<scroll-view class="tabs-nav" scroll-x="true"> |
|||
<view class="ul"> |
|||
<view v-for="(item,index) in selectComposeData" :key="index" class="li" :class="tabIndex===index && 'on'" @click="tabChange(index)"> |
|||
{{ item.composeName }}</view> |
|||
</view> |
|||
</scroll-view> |
|||
<view class="tabs-item" v-for="(item,index) in selectComposeData" :key="index" :class="tabIndex===index && 'on'"> |
|||
<swiper class="swiper pro-box" :indicator-dots="false" :autoplay="true" :display-multiple-items="item.composeProductInfoList.length < 3?item.composeProductInfoList.length:3" @change="swiperChange" :disable-touch="item.composeProductInfoList.length <= 3"> |
|||
<swiper-item class="pro-item-warp" v-for="(itemJ,indexJ) in item.composeProductInfoList" :key="indexJ" > |
|||
<view class="pro-item-inner"> |
|||
<view class="pro-item"> |
|||
<view class="pro-item-img"> |
|||
<image class="img" :src="itemJ.productImage"></image> |
|||
</view> |
|||
<view class="pro-item-info"> |
|||
<h3 class="name"> |
|||
{{itemJ.productName}} |
|||
</h3> |
|||
<view class="sku" @click.stop="changeSkuItemValue(itemJ, indexJ)"> |
|||
<view class="text">{{itemJ.skuItem.skuName}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</swiper-item> |
|||
</swiper> |
|||
<view class="swiper-dots" v-if='item.composeProductInfoList.length > 3'> |
|||
<text :class="{'dot-active':swiperCurrent === index,'dot': true}" |
|||
v-for="(dot, index) in item.composeProductInfoList.length - 2" |
|||
:key="index" |
|||
></text> |
|||
</view> |
|||
</view> |
|||
<view class="btn-buy" @click="doBuy">立即购买</view> |
|||
</view> |
|||
</view> |
|||
<!-- 商品详情 --> |
|||
<u-popup v-model="goodsDetailShowFlag" mode="bottom" border-radius="14"> |
|||
<view class="goosDetailshow-box"> |
|||
<view class="detailImg-box flex-row-plus"> |
|||
<image class="detailImg" :src="selectedSku.image"></image> |
|||
<view class="flex-column-plus mar-left-40"> |
|||
<view class="font-color-C5AA7B"> |
|||
<label class="fs24">¥</label> |
|||
<label class="fs36 mar-left-10" |
|||
v-text="getPrice(selectedSku)"></label> |
|||
</view> |
|||
<label class="fs24 font-color-999 mar-top-20">库存 {{selectedSku.stockNumber}} 件</label> |
|||
<label class="fs24 mar-top-20">已选</label> |
|||
</view> |
|||
</view> |
|||
<view class="color-box flex-column-plus"> |
|||
<view v-for="(attritem,index) in skuProData.names" :key="index" class="skuStyle"> |
|||
<label class="fs24 font-color-999">{{attritem.skuName}}</label> |
|||
<view class="colorName-box"> |
|||
<view class="pad-bot-30" v-for="(attrRes, resIndex) in attritem.values" :key="resIndex"> |
|||
<view class="colorName" |
|||
:class="{'colorName-on' : getselectedAttrVal(attritem.nameCode) == attrRes.valueCode}" |
|||
@click="nameCodeValueCodeClick(attritem.nameCode, attrRes.valueCode, true)"> |
|||
{{attrRes.skuValue}} |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<!-- <view class="goodsNum-box flex-row-plus flex-sp-between" :class="{'bottom-line' :supportHuabei}">--> |
|||
<!-- <label class="font-color-999 fs24">数量</label>--> |
|||
<!-- <view class="goodsNum">--> |
|||
<!-- <text class="subtract" @click="updateNumSub()">-</text>--> |
|||
<!-- <text class="goodsNumber" v-model="buyNum">{{buyNum}}</text>--> |
|||
<!-- <text class="add" @click.stop="--> |
|||
<!-- ()">+</text>--> |
|||
<!-- </view>--> |
|||
<!-- </view>--> |
|||
<view class="goosDetailbut-box flex-items-plus"> |
|||
<!-- <button type="default" @click="goodsDateils(shopId,productId,skuId)" >查看详情</button>--> |
|||
<button type="default" class="submitBtn" @click="submitBtn()">确认</button> |
|||
</view> |
|||
</view> |
|||
</u-popup> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import NET from "../../utils/request"; |
|||
import API from "../../config/api"; |
|||
|
|||
export default { |
|||
name: "combinedSales", |
|||
props: { |
|||
pid: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
productData: { |
|||
type: Object, |
|||
default: ()=>{} |
|||
} |
|||
}, |
|||
data () { |
|||
return { |
|||
skuShowFalg: false, |
|||
tabIndex: 0, |
|||
swiperCurrent: 0, |
|||
selectComposeData: [], |
|||
curProIndex: 0, |
|||
selectedSku: [], |
|||
selectedAttr: [], |
|||
skuProData: {}, |
|||
goodsDetailShowFlag: false, |
|||
composePrice: 0 |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.getSelectCompose() |
|||
}, |
|||
methods:{ |
|||
// 切换套餐 |
|||
tabChange(index){ |
|||
this.tabIndex = index |
|||
this.calculatePrice() |
|||
}, |
|||
// 滑动回调方法 |
|||
swiperChange(e) { |
|||
this.swiperCurrent = e.detail.current; |
|||
}, |
|||
// 获取组合销售数据 |
|||
getSelectCompose() { |
|||
NET.request(API.selectCompose, { |
|||
productId: this.pid |
|||
}, |
|||
"GET").then(res => { |
|||
this.selectComposeData = res.data |
|||
for(let i=0;i< this.selectComposeData.length;i++) { |
|||
let proList = this.selectComposeData[i].composeProductInfoList |
|||
for (let j = 0; j < proList.length; j++) { |
|||
proList[j].skuItem = proList[j].composeSkuInfoList[0] |
|||
} |
|||
} |
|||
this.calculatePrice() |
|||
}).catch(res => { |
|||
|
|||
}) |
|||
}, |
|||
// 更换商品样式 |
|||
changeSkuItemValue(item,index) { |
|||
this.curProIndex = index |
|||
uni.showLoading({ |
|||
mask: true, |
|||
title: '加载中...' |
|||
}) |
|||
NET.request(API.QueryProductDetail, { |
|||
shopId: this.productData.shopId, |
|||
productId: item.productId, |
|||
skuId: item.skuItem.skuId, |
|||
terminal: 1 |
|||
}, |
|||
"GET").then(res => { |
|||
uni.hideLoading() |
|||
this.skuProData = res.data |
|||
// console.log(this.skuProData,'this.skuProData', res.data) |
|||
//如果是单款式商品,需要特殊处理productData.names |
|||
const mapKeys = Object.keys(this.skuProData.map) |
|||
if (mapKeys.length === 1 && mapKeys[0] === '单款项') { |
|||
this.skuProData.names[0].values.push({ |
|||
skuValue: '单款项', |
|||
valueCode: '单款项' |
|||
}) |
|||
} |
|||
|
|||
//如果sku的图像为空,设置为商品的图像 |
|||
for (var key in this.skuProData.map) { |
|||
let skuImage = this.skuProData.map[key].image |
|||
if (!skuImage) { |
|||
this.skuProData.map[key].image = this.skuProData.images[0] |
|||
} |
|||
} |
|||
this.goodsDetailShowFlag = true |
|||
this.selectBySkuId(item.skuItem.skuId) |
|||
}).catch(res => { |
|||
uni.hideLoading() |
|||
}) |
|||
}, |
|||
selectBySkuId(skuId) { |
|||
if (skuId) { |
|||
let mapinfo = this.skuProData.map |
|||
let flag = true |
|||
for (var key in mapinfo) { |
|||
if (parseInt(mapinfo[key].skuId) === parseInt(skuId)) { |
|||
flag = false |
|||
this.selectedSku = mapinfo[key] |
|||
// 选中sku对应的规格 |
|||
const valueCodeList = key.split(',') |
|||
this.selectedAttr = [] |
|||
this.skuProData.names.forEach(attr => { |
|||
for (var index in attr.values) { |
|||
let valueCode = attr.values[index].valueCode |
|||
if (valueCodeList.includes(valueCode)) { |
|||
this.nameCodeValueCodeClick(attr.nameCode, valueCode, false) |
|||
break |
|||
} |
|||
} |
|||
}) |
|||
break |
|||
} |
|||
} |
|||
// 匹配不上就赋值第一个 |
|||
if(flag){ |
|||
for (var key in mapinfo) { |
|||
console.log(key,'key') |
|||
this.selectedSku = mapinfo[key] |
|||
break |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
nameCodeValueCodeClick(nameCode, valueCode, reSelectSku) { |
|||
this.selectedAttr[nameCode] = valueCode |
|||
console.log(this.selectedAttr, 'this.selectedAttr') |
|||
if (reSelectSku) { |
|||
let attrList = [] |
|||
for (var key in this.selectedAttr) { |
|||
attrList.push(this.selectedAttr[key]) |
|||
} |
|||
const attrkey = attrList.join(',') |
|||
let mapinfo = this.skuProData.map |
|||
for (var key in mapinfo) { |
|||
if (attrkey === key) { |
|||
this.selectedSku = mapinfo[key] |
|||
} |
|||
} |
|||
} |
|||
this.$forceUpdate(); // 重绘 |
|||
}, |
|||
// 提交更换商品规格 |
|||
submitBtn() { |
|||
console.log(this.selectedSku,'this.selectedSku') |
|||
const curPro = this.selectComposeData[this.tabIndex].composeProductInfoList[this.curProIndex] |
|||
for(let i=0;i<curPro.composeSkuInfoList.length;i++){ |
|||
if(curPro.composeSkuInfoList[i].skuId === this.selectedSku.skuId){ |
|||
this.selectedSku.skuName = curPro.composeSkuInfoList[i].skuName |
|||
} |
|||
} |
|||
curPro.skuItem = this.selectedSku |
|||
this.calculatePrice() |
|||
this.goodsDetailShowFlag = false |
|||
}, |
|||
// 计算组合价 |
|||
calculatePrice(){ |
|||
const proList = this.selectComposeData[this.tabIndex].composeProductInfoList,composeType= this.selectComposeData[this.tabIndex].composeType,promote= this.selectComposeData[this.tabIndex].promote |
|||
let total = 0 |
|||
for(let i=0;i<proList.length;i++){ |
|||
total += this.getPrice(proList[i].skuItem) |
|||
} |
|||
switch (composeType){ |
|||
case 1: |
|||
this.composePrice = promote.toFixed(2) |
|||
break |
|||
case 2: |
|||
this.composePrice = (total - promote).toFixed(2) |
|||
break |
|||
case 3: |
|||
this.composePrice = parseFloat(total * promote / 10).toFixed(2) |
|||
break |
|||
} |
|||
console.log(total, this.composePrice, 'total') |
|||
}, |
|||
// 根据活动显示不同价格 |
|||
getPrice(item){ |
|||
// 所属活动 0-常规商品 1-拼团活动 2-秒杀活动 3-限时折扣活动 4-平台秒杀 5-平台折扣 6-定价捆绑 7-组合捆绑 8-场景营销 9-会员价 |
|||
if(item.activityType){ |
|||
if(item.activityType === 0 || item.activityType === 6 || item.activityType === 7){ |
|||
return item.price |
|||
} else { |
|||
return item.originalPrice |
|||
} |
|||
} else { |
|||
return item.price |
|||
} |
|||
}, |
|||
// 立即购买 |
|||
doBuy(){ |
|||
let addCart = [] |
|||
let shopObj = {} |
|||
shopObj["shopId"] = this.productData.shopId |
|||
shopObj["composeId"] = this.selectComposeData[this.tabIndex].composeId |
|||
shopObj["skus"] = [] |
|||
let proList = this.selectComposeData[this.tabIndex].composeProductInfoList |
|||
let len2 = proList.length |
|||
for (let j = 0; j < len2; j++) { |
|||
let skusObj = {} |
|||
skusObj["number"] = 1 |
|||
skusObj["skuId"] = proList[j].skuItem.skuId |
|||
shopObj.skus.push(skusObj) |
|||
} |
|||
addCart.push(shopObj) |
|||
uni.setStorageSync('skuItemDTOList', addCart) |
|||
uni.navigateTo({ |
|||
url: '../../pages_category_page1/orderModule/orderConfirm?type=1' |
|||
}) |
|||
}, |
|||
getselectedAttrVal(item){ |
|||
return this.selectedAttr[item] |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.group-list{ |
|||
padding: 10upx 20upx 60upx; |
|||
border-top: 12upx solid #F8F8F8; |
|||
.group-warp{ |
|||
height: 680upx; |
|||
|
|||
background: #333333; |
|||
box-shadow: 0 20upx 30upx rgba(0, 0, 0, 0.3); |
|||
opacity: 1; |
|||
border-radius: 20upx; |
|||
} |
|||
.title{ |
|||
display: flex; |
|||
align-items:center; |
|||
position: relative; |
|||
justify-content: space-between; |
|||
padding: 32upx 0 20upx 30upx; |
|||
.title-img{ |
|||
width: 203upx; |
|||
} |
|||
.price-text{ |
|||
padding: 0 34upx; |
|||
margin-right: 10upx; |
|||
height: 50upx; |
|||
background: linear-gradient(90deg, #C83732 0%, #E25C44 100%); |
|||
box-shadow: 0 6upx 12upx rgba(233, 0, 0, 0.3); |
|||
border-radius: 26upx; |
|||
font-size: 24upx; |
|||
color: #fff; |
|||
text-align: center; |
|||
line-height: 50upx; |
|||
margin-left: 20upx; |
|||
.swiper{ |
|||
height: 50upx; |
|||
} |
|||
} |
|||
} |
|||
.tabs-nav{ |
|||
padding: 0 10upx; |
|||
margin-bottom: 20upx; |
|||
.ul{ |
|||
display: flex; |
|||
.li{ |
|||
//flex: 1 0 auto; |
|||
text-align: center; |
|||
font-size: 26rpx; |
|||
color: #999; |
|||
position: relative; |
|||
padding: 12px 40px; |
|||
word-break: keep-all; |
|||
&:first-child{ |
|||
margin-left: 0; |
|||
} |
|||
&.on{ |
|||
color: #FFEBC4; |
|||
&:after{ |
|||
content: ''; |
|||
width: 100%; |
|||
height: 2rpx; |
|||
background: #FFEBC4; |
|||
position: absolute; |
|||
left: 0; |
|||
bottom: 0; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.tabs-item{ |
|||
display: none; |
|||
&.on{ |
|||
display: block; |
|||
} |
|||
} |
|||
.pro-box{ |
|||
height: 318upx; |
|||
padding: 0 2upx 20upx; |
|||
.pro-item-inner{ |
|||
padding: 0 8upx; |
|||
display: flex; |
|||
justify-content: center; |
|||
} |
|||
.pro-item{ |
|||
width: 219upx; |
|||
background: #FFFFFF; |
|||
padding: 10upx; |
|||
height: 318upx; |
|||
.pro-item-img{ |
|||
width: 100%; |
|||
height: 160upx; |
|||
.img{ |
|||
width: 100%; |
|||
height: 100%; |
|||
object-fit: contain; |
|||
|
|||
} |
|||
} |
|||
.pro-item-info{ |
|||
.name{ |
|||
font-size: 24upx; |
|||
line-height: 34upx; |
|||
color: #333333; |
|||
overflow: hidden; |
|||
text-overflow:ellipsis; |
|||
white-space: nowrap; |
|||
text-align: center; |
|||
font-weight: normal; |
|||
margin: 8upx 0 26upx; |
|||
} |
|||
.sku{ |
|||
width: 180upx; |
|||
height: 50upx; |
|||
margin: 0 auto; |
|||
line-height: 50upx; |
|||
border: 2upx solid #E4E5E6; |
|||
background: url("https://ceres.zkthink.com/static/images/arrow-suk-select.png") no-repeat right center / 60upx 60upx; |
|||
.text{ |
|||
font-size: 24upx; |
|||
color: #999; |
|||
padding-left: 20upx; |
|||
width: 126px; |
|||
text-overflow:ellipsis; |
|||
white-space: nowrap; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.swiper-dots{ |
|||
display: flex; |
|||
justify-content: center; |
|||
.dot{ |
|||
display: block; |
|||
width: 24upx; |
|||
height: 4upx; |
|||
background: #FFFFFF; |
|||
opacity: 0.5; |
|||
border-radius: 2upx; |
|||
margin: 0 20upx; |
|||
&.dot-active{ |
|||
opacity: 1; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.btn-buy{ |
|||
width: 688upx; |
|||
height: 84upx; |
|||
//border: 2upx solid rgba(0, 0, 0, 0); |
|||
background: linear-gradient(88deg, #C5AA7B 0%, #FFEBC4 100%); |
|||
font-size: 28upx; |
|||
color: #333; |
|||
line-height: 84upx; |
|||
margin: 30upx auto 0; |
|||
text-align: center; |
|||
} |
|||
|
|||
.goosDetailshow-box { |
|||
.detailImg-box { |
|||
margin-top: 30rpx; |
|||
margin-left: 30rpx; |
|||
border-radius: 10rpx; |
|||
border-bottom: 1rpx solid #EDEDED; |
|||
padding-bottom: 20rpx; |
|||
width: 690rpx; |
|||
|
|||
.detailImg { |
|||
width: 180rpx; |
|||
height: 180rpx; |
|||
} |
|||
} |
|||
|
|||
.color-box { |
|||
padding: 30rpx 30rpx; |
|||
border-bottom: 1rpx solid #EDEDED; |
|||
width: 690rpx; |
|||
.skuStyle{ |
|||
padding: 20rpx 0; |
|||
} |
|||
|
|||
.skuStyle:nth-child(2) { |
|||
border-top: 1px solid #F3F4F5; |
|||
} |
|||
|
|||
.colorName-box { |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
flex-direction: row; |
|||
justify-content: flex-start; |
|||
align-items: center; |
|||
margin-top: 30rpx; |
|||
margin-left: -30rpx; |
|||
|
|||
.colorName-on { |
|||
background-color: #FFE5D0; |
|||
color: #C5AA7B; |
|||
margin-left: 30rpx; |
|||
padding: 10rpx 32rpx; |
|||
border-radius: 28rpx; |
|||
border: 1rpx solid #C5AA7B; |
|||
font-size: 26rpx; |
|||
text-align: center; |
|||
z-index: 1; |
|||
} |
|||
|
|||
.colorName { |
|||
background-color: #F5F5F5; |
|||
margin-left: 30rpx; |
|||
padding: 10rpx 32rpx; |
|||
border-radius: 28rpx; |
|||
font-size: 26rpx; |
|||
z-index: 2; |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
.modelNum-box { |
|||
padding: 30rpx 30rpx; |
|||
border-bottom: 1rpx solid #EDEDED; |
|||
width: 690rpx; |
|||
|
|||
.modelNumName-box { |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
flex-direction: row; |
|||
justify-content: flex-start; |
|||
align-items: center; |
|||
margin-top: 30rpx; |
|||
margin-left: -30rpx; |
|||
|
|||
.modelNumName-on { |
|||
background-color: #FFE4D0; |
|||
color: #C5AA7B; |
|||
margin-left: 30rpx; |
|||
padding: 10rpx 32rpx; |
|||
border-radius: 28rpx; |
|||
border: 1rpx solid #C5AA7B; |
|||
font-size: 26rpx; |
|||
text-align: center; |
|||
} |
|||
|
|||
.modelNumName { |
|||
background-color: #F5F5F5; |
|||
margin-left: 30rpx; |
|||
padding: 10rpx 32rpx; |
|||
border-radius: 28rpx; |
|||
font-size: 26rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.goodsNum-box { |
|||
padding: 30rpx 30rpx; |
|||
width: 690rpx; |
|||
padding-bottom: 140rpx; |
|||
|
|||
.goodsNumber { |
|||
text-align: center; |
|||
border: 1rpx solid #999999; |
|||
padding: 3rpx 20rpx; |
|||
} |
|||
|
|||
.subtract { |
|||
border: 1rpx solid #999999; |
|||
padding: 3rpx 20rpx; |
|||
margin-right: -1rpx; |
|||
} |
|||
|
|||
.add { |
|||
border: 1rpx solid #999999; |
|||
padding: 3rpx 20rpx; |
|||
margin-left: -1rpx; |
|||
} |
|||
} |
|||
|
|||
.goosDetailbut-box { |
|||
.joinShopCartBut { |
|||
width: 343rpx; |
|||
height: 80rpx; |
|||
background-color: #FFC300; |
|||
color: #FFFEFE; |
|||
font-size: 28rpx; |
|||
line-height: 80rpx; |
|||
text-align: center; |
|||
margin-left: 30rpx; |
|||
} |
|||
|
|||
.buyNowBut { |
|||
width: 343rpx; |
|||
height: 80rpx; |
|||
border-radius: 0 40rpx 40rpx 0; |
|||
background-color: #FF6F00; |
|||
color: #FFFEFE; |
|||
font-size: 28rpx; |
|||
line-height: 80rpx; |
|||
text-align: center; |
|||
} |
|||
} |
|||
.submitBtn { |
|||
width: 342rpx; |
|||
height: 100rpx; |
|||
line-height: 100rpx; |
|||
font-size: 28rpx; |
|||
border: 1px solid; |
|||
border-radius: 0; |
|||
color: #FFEBC4; |
|||
background: #333333; |
|||
margin: 20rpx 0; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,430 @@ |
|||
<template> |
|||
<view v-if="visible"> |
|||
<view v-if="adInfo.jumpType === 3 && couponList && couponList.length> 0" |
|||
class="mask mask-coupon ad-coupons" |
|||
@touchmove.stop.prevent="moveHandle"> |
|||
<view class="ad-box-warp"> |
|||
<view class="ad-boxs"> |
|||
<image class="img" |
|||
:src="adInfo.popupImg" |
|||
></image> |
|||
<view class="coupon-list"> |
|||
<scroll-view :scroll-top="0" |
|||
class="scrollBox" |
|||
scroll-y="true"> |
|||
<view class="item" |
|||
v-for="(item, index) in couponList" |
|||
:key="index"> |
|||
<view class="leftBox borderBox"> |
|||
<view class="boxTop"></view> |
|||
<view class="boxCent"></view> |
|||
<view class="boxBottom"></view> |
|||
</view> |
|||
<view class="centerBox"> |
|||
<view class="money"> |
|||
<text class="num" |
|||
:class="[item.discountMode ===1?'num-minus':'num-discount']">{{ item.reduceMoney }} |
|||
</text> |
|||
<text class="text"> |
|||
满{{ item.fullMoney }}元可用 |
|||
</text> |
|||
</view> |
|||
<view class="text"> |
|||
<text> |
|||
{{ item.activityName }} |
|||
</text> |
|||
</view> |
|||
</view> |
|||
<view class="rightBox borderBox"> |
|||
<view class="boxTop"></view> |
|||
<view class="boxCent"></view> |
|||
<view class="boxBottom"></view> |
|||
</view> |
|||
</view> |
|||
</scroll-view> |
|||
</view> |
|||
<WxSendCoupon v-if="couponList && couponList.length > 0" |
|||
:couponList="couponList" |
|||
@closeAd="close"> |
|||
<view class="btn-receive">一键领取</view> |
|||
</WxSendCoupon> |
|||
</view> |
|||
<view class="close-btn"> |
|||
<image :src="adInfo.closeImg" |
|||
class='btn' |
|||
mode="widthFix" |
|||
@click="close()"></image> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view v-else-if="adInfo.jumpType !== 3" |
|||
class="mask mask-coupon ad-link"> |
|||
<view class="ad-box-warp"> |
|||
<view class="ad-boxs" |
|||
@click="goRoll()"> |
|||
<image class="img" |
|||
:src="adInfo.popupImg" |
|||
mode="widthFix"></image> |
|||
</view> |
|||
<view class="close-btn"> |
|||
<image :src="adInfo.closeImg" |
|||
class='btn' |
|||
mode="widthFix" |
|||
@click="close()"></image> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import WxSendCoupon from "./wx/wxSendCoupon"; |
|||
|
|||
const NET = require('../utils/request') |
|||
const API = require('../config/api') |
|||
|
|||
export default { |
|||
name: "adWindow", |
|||
components: { |
|||
WxSendCoupon |
|||
}, |
|||
props: { |
|||
triggerCondition: { |
|||
type: Number, |
|||
default: 1 |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
visible: false, |
|||
adInfo: {}, |
|||
jumpContent: {}, |
|||
couponList: [], |
|||
isLogin: false, |
|||
buyerUserId: 0, |
|||
cParams: {} |
|||
}; |
|||
}, |
|||
methods: { |
|||
// 阻止滑动 |
|||
moveHandle() { |
|||
return |
|||
}, |
|||
// 获取广告信息 |
|||
getAd() { |
|||
console.log(this.triggerCondition,'triggerCondition000000') |
|||
const res = uni.getStorageSync('storage_key'), |
|||
token = res.token; |
|||
setTimeout(() => { |
|||
this.buyerUserId = res.buyerUserId |
|||
this.isLogin = !!token |
|||
console.log(this.buyerUserId,this.isLogin,this.triggerCondition) |
|||
NET.request(API.GetAd, { |
|||
triggerCondition: this.triggerCondition |
|||
}, 'POST').then(res => { |
|||
console.log('123131321323', res) |
|||
if (res.data) { |
|||
this.adInfo = res.data[0] |
|||
if (this.adInfo.jumpContent) { |
|||
this.jumpContent = JSON.parse(this.adInfo.jumpContent) |
|||
} |
|||
this.visible = true |
|||
if (this.adInfo.jumpType === 3) { |
|||
this.getCoupons() |
|||
} |
|||
} |
|||
}).catch(res => { |
|||
|
|||
}) |
|||
}, 500) |
|||
}, |
|||
// 查询优惠券 |
|||
getCoupons() { |
|||
if (this.isLogin) { |
|||
const _items = this.jumpContent.items |
|||
if (_items) { |
|||
NET.request(API.getCoupons, { |
|||
page: 1, |
|||
pageSize: 99, |
|||
ids: _items |
|||
}, 'GET').then(res => { |
|||
if (res.data) { |
|||
this.couponList = res.data.list |
|||
} |
|||
}).catch(res => { |
|||
|
|||
}) |
|||
} |
|||
} else { |
|||
uni.showToast({ |
|||
title: '登录之后领取更多优惠', |
|||
icon: "none" |
|||
}) |
|||
// uni.navigateTo({ |
|||
// url: '/pages_category_page2/userModule/login' |
|||
// }) |
|||
} |
|||
}, |
|||
// 关闭弹窗 |
|||
close() { |
|||
this.visible = false |
|||
var params = {} |
|||
if (this.isLogin) { |
|||
params.buyerUserId = this.buyerUserId |
|||
} else { |
|||
uni.getSystemInfo({ |
|||
success: function (res) { |
|||
params.deviceId = res.deviceId |
|||
} |
|||
}) |
|||
} |
|||
NET.request(API.adClose, params, 'POST').then(res => { |
|||
}).catch(res => { |
|||
}) |
|||
}, |
|||
goRoll() { |
|||
this.visible = false |
|||
console.log(this.jumpContent, 'this.jumpContent') |
|||
switch (this.adInfo.jumpType) { |
|||
case 1: |
|||
uni.navigateTo({ |
|||
url: '/pages_category_page1/goodsModule/goodsDetails?shopId=' + this.jumpContent |
|||
.shopId + '&productId=' + this.jumpContent.id + '&skuId=' + this.jumpContent |
|||
.skuId |
|||
}) |
|||
break |
|||
case 2: |
|||
let _id = this.jumpContent.id[this.jumpContent.id.length - 1] |
|||
uni.navigateTo({ |
|||
url: `/pages_category_page1/goodsModule/goodsList?category3Id=${_id}` |
|||
}) |
|||
break |
|||
case 4: |
|||
uni.navigateToMiniProgram({ |
|||
appId: this.jumpContent.appId, |
|||
path: this.jumpContent.link, |
|||
success(res) { |
|||
// 打开成功 |
|||
} |
|||
}) |
|||
case 5: |
|||
uni.navigateTo({ |
|||
path: this.jumpContent.link |
|||
}) |
|||
break |
|||
} |
|||
}, |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped |
|||
lang="scss"> |
|||
.mask { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
z-index: 55; |
|||
background-color: rgba(0, 0, 0, 0.7); |
|||
} |
|||
|
|||
|
|||
.mask-coupon { |
|||
z-index: 9999; |
|||
/*background: rgba(39, 38, 39, .15);*/ |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
|
|||
.ad-box-warp { |
|||
width: 100%; |
|||
position: relative; |
|||
} |
|||
|
|||
flex-direction: column; |
|||
|
|||
.ad-boxs { |
|||
position: relative; |
|||
width: 100%; |
|||
text-align: center; |
|||
|
|||
.img { |
|||
width: 70%; |
|||
} |
|||
} |
|||
|
|||
.btn-receive { |
|||
width: 446rpx; |
|||
height: 84rpx; |
|||
background: #EC6F43; |
|||
border-radius: 42rpx; |
|||
display: block; |
|||
text-align: center; |
|||
font-size: 28rpx; |
|||
line-height: 84rpx; |
|||
color: #fff; |
|||
position: absolute; |
|||
bottom: 32rpx; |
|||
left: 50%; |
|||
margin-left: -223rpx; |
|||
} |
|||
|
|||
.close-btn { |
|||
position: absolute; |
|||
bottom: -70rpx; |
|||
left: 50%; |
|||
margin-left: -25rpx; |
|||
|
|||
.btn { |
|||
width: 50rpx; |
|||
height: 50rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.ad-coupons { |
|||
.ad-box-warp { |
|||
width: 510rpx; |
|||
position: relative; |
|||
|
|||
.ad-boxs { |
|||
min-height: 700rpx; |
|||
.img { |
|||
position: absolute; |
|||
top:0; |
|||
left:0; |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.coupon-list { |
|||
width: 446rpx; |
|||
height: 40%; |
|||
overflow: auto; |
|||
position: absolute; |
|||
top: 40%; |
|||
left: 50%; |
|||
margin-left: -223rpx; |
|||
|
|||
.scrollBox { |
|||
height: 450upx; |
|||
} |
|||
|
|||
.item { |
|||
width: 100%; |
|||
height: 140rpx; |
|||
margin-top: 15rpx; |
|||
border-radius: 8rpx; |
|||
display: flex; |
|||
position: relative; |
|||
align-items: center; |
|||
overflow: hidden; |
|||
|
|||
&:first-child { |
|||
margin-top: 0px; |
|||
} |
|||
|
|||
.borderBox { |
|||
width: 32rpx; |
|||
height: 140rpx; |
|||
overflow: hidden; |
|||
|
|||
.boxTop { |
|||
width: 32rpx; |
|||
height: 54rpx; |
|||
background: #FFFFFF; |
|||
} |
|||
|
|||
.boxCent { |
|||
height: 36rpx; |
|||
overflow: hidden; |
|||
position: relative; |
|||
|
|||
&:after { |
|||
content: ''; |
|||
width: 32rpx; |
|||
height: 32rpx; |
|||
border-radius: 50%; |
|||
display: block; |
|||
position: absolute; |
|||
top: 50%; |
|||
margin-top: -47rpx; |
|||
left: -15rpx; |
|||
border: 32rpx solid #FFFFFF; |
|||
} |
|||
} |
|||
|
|||
.boxBottom { |
|||
width: 32rpx; |
|||
height: 54rpx; |
|||
background: #FFFFFF; |
|||
} |
|||
} |
|||
|
|||
.leftBox { |
|||
.boxCent { |
|||
&:after { |
|||
left: -50rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.rightBox { |
|||
} |
|||
|
|||
.centerBox { |
|||
display: flex; |
|||
align-items: center; |
|||
height: 140rpx; |
|||
background: #FFFFFF; |
|||
flex: 1; |
|||
} |
|||
|
|||
.money { |
|||
width: 190rpx; |
|||
text-align: center; |
|||
|
|||
.num { |
|||
font-size: 48rpx; |
|||
color: #EC6F43; |
|||
display: block; |
|||
|
|||
&.num-minus::before { |
|||
content: '¥'; |
|||
font-size: 36rpx; |
|||
} |
|||
|
|||
&.num-discount::after { |
|||
content: '折'; |
|||
font-size: 36rpx; |
|||
} |
|||
} |
|||
|
|||
.text { |
|||
font-size: 24rpx; |
|||
color: #999; |
|||
} |
|||
} |
|||
|
|||
.text { |
|||
flex: 1; |
|||
padding-right: 16rpx; |
|||
width: 0; |
|||
|
|||
text { |
|||
font-size: 32rpx; |
|||
color: #333; |
|||
display: block; |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
white-space: nowrap; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,84 @@ |
|||
<template> |
|||
<view class="tabs-nav-warp"> |
|||
<scroll-view class="tabs-nav" scroll-x="true"> |
|||
<view class="ul"> |
|||
<view class="li" :class="{'on':activeTab===0}" @click="tabChange(0)">首页</view> |
|||
<view class="li" :class="{'on':activeTab===index+1}" v-for="(item,index) in categoryList" :key="index" @click="tabChange(index+1,item.classifyId)"> |
|||
{{item.classifyName}} |
|||
</view> |
|||
</view> |
|||
</scroll-view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
const NET = require('@/utils/request') |
|||
const API = require('@/config/api') |
|||
export default { |
|||
name: "categoryList", |
|||
data () { |
|||
return { |
|||
activeTab: 0, |
|||
categoryList: [] |
|||
} |
|||
}, |
|||
mounted () { |
|||
this.getCategoryData(); |
|||
}, |
|||
methods:{ |
|||
tabChange (index, id) { |
|||
this.activeTab = index |
|||
this.$emit('tabChange', index, id) |
|||
}, |
|||
getCategoryData(){ |
|||
uni.showLoading({ |
|||
title:'加载中...' |
|||
}) |
|||
NET.request(API.FindCategoryListByDepth, { |
|||
}, 'GET').then(res => { |
|||
this.categoryList = res.data |
|||
uni.hideLoading() |
|||
}).catch(res => { |
|||
uni.hideLoading() |
|||
}) |
|||
} |
|||
} |
|||
|
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.tabs-nav-warp{ |
|||
margin-top: 20rpx; |
|||
padding:0 30rpx; |
|||
.tabs-nav{ |
|||
.ul{ |
|||
display: flex; |
|||
.li{ |
|||
flex: 1 0 auto; |
|||
margin-left: 36rpx; |
|||
font-size: 30rpx; |
|||
color: #999999; |
|||
position: relative; |
|||
padding-bottom: 18rpx; |
|||
&:first-child{ |
|||
margin-left: 0; |
|||
} |
|||
&.on{ |
|||
&:after{ |
|||
content: ''; |
|||
width: 100%; |
|||
height: 4rpx; |
|||
background: #C5AA7B; |
|||
position: absolute; |
|||
left: 0; |
|||
bottom: 0; |
|||
} |
|||
font-weight:bold; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
</style> |
@ -0,0 +1,280 @@ |
|||
<template> |
|||
<view class="goodRecommend"> |
|||
<!-- 骨架屏 --> |
|||
<view class="product-list"> |
|||
<view class="product-list-box" > |
|||
<view class="product-list-item-warp" v-for="(item,index) in productList" :key="index"> |
|||
<view class="product-list-item" v-if="JSON.stringify(item)!=='{}'"> |
|||
<view class="product-list-img" @click="jumpProductDetail(item)"> |
|||
<img v-show="item.image" class="img" :src="item.image"> |
|||
</view> |
|||
<view class="product-list-info u-skeleton-fillet"> |
|||
<view class="product-name">{{item.productName}}</view> |
|||
<view class="flex"> |
|||
<view class="shop-box" @click.stop="jumpStore(item)"> |
|||
<view class="shop-name" @click="jumpProductDetail(item)">{{item.shopName}}</view> |
|||
<view class="shop-logo"> |
|||
<img :src="item.shopLogo"> |
|||
</view> |
|||
</view> |
|||
<view class="buy-count">{{item.users?item.users: 0}}人付款</view> |
|||
</view> |
|||
<div class="price-warp"> |
|||
<!-- #ifdef MP-WEIXIN --> |
|||
<img class="iconImg" v-if="item.activityType == 1" src="../canvasShow/static/images/groupBuyIcon.png"> |
|||
<img class="iconImg" v-if="item.activityType == 2" src="../canvasShow/static/images/spikeIcon.png"> |
|||
<img class="iconImg" v-if="item.activityType == 4" src="../canvasShow/static/images/spikeIcon.png"> |
|||
<img class="iconImg" v-if="item.activityType == 3" src="../canvasShow/static/images/discountListIcon.png"> |
|||
<img class="iconImg" v-if="item.activityType == 5" src="../canvasShow/static/images/discountListIcon.png"> |
|||
<img class="iconImg" v-if="item.activityType == 8" src="../canvasShow/static/images/memberCenterIcon.png"> |
|||
<!-- #endif --> |
|||
<!-- #ifdef H5 || APP-PLUS --> |
|||
<image class="iconImg" v-if="item.activityType == 1" src="../canvasShow/static/images/groupBuyIcon.png"></image> |
|||
<image class="iconImg" v-if="item.activityType == 2" src="../canvasShow/static/images/spikeIcon.png"></image> |
|||
<image class="iconImg" v-if="item.activityType == 4" src="../canvasShow/static/images/spikeIcon.png"></image> |
|||
<image class="iconImg" v-if="item.activityType == 3" src="../canvasShow/static/images/discountListIcon.png"></image> |
|||
<image class="iconImg" v-if="item.activityType == 5" src="../canvasShow/static/images/discountListIcon.png"></image> |
|||
<image class="iconImg" v-if="item.activityType == 8" src="../canvasShow/static/images/memberCenterIcon.png"></image> |
|||
<!-- #endif --> |
|||
<div class="price"> |
|||
¥ {{item.price}} |
|||
</div> |
|||
<div class="original-price"> |
|||
¥ {{item.originalPrice}} |
|||
</div> |
|||
</div> |
|||
</view> |
|||
</view> |
|||
<view class="product-list-item ske-loading" v-else> |
|||
<view class="product-list-img child-loading"> |
|||
<img v-show="item.image" class="img" :src="item.image"> |
|||
</view> |
|||
<view class="product-list-info"> |
|||
<view class="product-name child-loading" style="border-radius: 5rpx; margin-top: 10rpx;width: 100%;padding: 20rpx 0"></view> |
|||
<view class="product-name child-loading" style="border-radius: 5rpx; margin-top: 10rpx;width: 100%;padding: 20rpx 0"></view> |
|||
</view> |
|||
</view> |
|||
|
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view v-if="ifShow" class="emptyCart-box flex-items-plus flex-column"> |
|||
<image class="emptyCart-img" src="https://ceres.zkthink.com/static/img/bgnull.png" mode="widthFix" /> |
|||
<label class="font-color-999 fs26 mar-top-30">这里空空如也~</label> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
const NET = require('@/utils/request') |
|||
const API = require('@/config/api') |
|||
export default { |
|||
name: "categoryShow", |
|||
props: { |
|||
categoryid: { |
|||
type: Number, |
|||
default: 0 |
|||
} |
|||
}, |
|||
data () { |
|||
return { |
|||
activeTab: 0, |
|||
page:1, |
|||
pageSize:10, |
|||
total: 0, |
|||
productList: [], |
|||
ifShow: false |
|||
} |
|||
}, |
|||
mounted () { |
|||
this.productList = [{},{},{},{},{},{},{},{}] |
|||
this.getData(); |
|||
}, |
|||
methods:{ |
|||
getData(){ |
|||
console.log('加载了getData') |
|||
// uni.showLoading({ |
|||
// mask: true, |
|||
// title:'加载中...' |
|||
// }) |
|||
if (this.total!=0&&this.productList.length>=this.total){ |
|||
console.log("加载完了") |
|||
return |
|||
} |
|||
NET.request(API.getProducts, { |
|||
classifyId: this.categoryid, |
|||
page:this.page, |
|||
pageSize:this.pageSize |
|||
}, 'GET').then(res => { |
|||
this.productList = [...this.productList,...res.data.list] |
|||
this.productList = this.productList.filter(item=>JSON.stringify(item)!=='{}') |
|||
this.total = res.data.total |
|||
uni.hideLoading() |
|||
if (this.productList.length ===0) { |
|||
this.ifShow = true |
|||
} |
|||
|
|||
}).catch(res => { |
|||
uni.hideLoading() |
|||
}) |
|||
}, |
|||
// 跳转到店铺主页 |
|||
jumpStore(item){ |
|||
uni.navigateTo({ |
|||
url: `/pages_category_page1/store/index?storeId=${item.shopId}` |
|||
}) |
|||
}, |
|||
// 跳转到商品详情 |
|||
jumpProductDetail(item){ |
|||
uni.navigateTo({ |
|||
url: '/pages_category_page1/goodsModule/goodsDetails?shopId=' + item.shopId + '&productId=' + item.productId + '&skuId=' + item |
|||
.skuId |
|||
}) |
|||
} |
|||
}, |
|||
watch: { |
|||
'categoryid': { |
|||
handler(newVal, oldVal) { |
|||
this.ifShow = false |
|||
this.getData() |
|||
}, |
|||
deep: true |
|||
} |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.goodRecommend { |
|||
padding-top: 20rpx; |
|||
.product-list { |
|||
position: relative; |
|||
padding: 0 13upx; |
|||
width: 100%; |
|||
//min-height: 60vh; |
|||
&-box { |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
flex-direction: row; |
|||
&.swiper{ |
|||
height: 620upx; |
|||
} |
|||
} |
|||
&.product-swiper .product-list-box{ |
|||
padding-left: 0; |
|||
} |
|||
&-item-warp{ |
|||
margin: 0 0 20upx 0; |
|||
} |
|||
&-item { |
|||
width: 348upx; |
|||
padding: 0 7upx; |
|||
box-sizing: content-box; |
|||
} |
|||
|
|||
|
|||
&-img { |
|||
width: 348upx; |
|||
height: 348upx; |
|||
background-color: #d0d0d0; |
|||
border-radius: 10upx 10upx 0 0; |
|||
.img { |
|||
width: 100%; |
|||
height: 100%; |
|||
object-fit: contain; |
|||
} |
|||
} |
|||
&-info { |
|||
background-color: #FFFFFF; |
|||
//box-shadow: 0px 0px 15px 0px rgba(52, 52, 52, 0.15); |
|||
border-radius: 0 0 10upx 10upx; |
|||
padding: 20upx; |
|||
label{ |
|||
font-weight: normal; |
|||
} |
|||
.product-name{ |
|||
font-size: 28upx; |
|||
color: #333; |
|||
display: block; |
|||
overflow: hidden; |
|||
text-overflow:ellipsis; |
|||
white-space: nowrap; |
|||
margin-bottom: 18upx; |
|||
line-height: 40upx; |
|||
} |
|||
.flex{ |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
.shop-box{ |
|||
background-color: #333333; |
|||
border-radius: 0upx 20upx 20upx 0upx; |
|||
line-height: 40upx; |
|||
display: flex; |
|||
align-items: center; |
|||
height: 40upx; |
|||
margin-right: 10upx; |
|||
float: left; |
|||
.shop-name{ |
|||
font-size: 20upx; |
|||
color: #FFEBC4; |
|||
padding: 0 8upx 0 12upx; |
|||
line-height: 40upx; |
|||
display: inline-block; |
|||
float: left; |
|||
max-width: 170rpx; |
|||
white-space: nowrap; |
|||
overflow:hidden; |
|||
text-overflow:ellipsis; |
|||
} |
|||
.shop-logo{ |
|||
border: 2upx solid #707070; |
|||
border-radius: 50%; |
|||
overflow: hidden; |
|||
float: right; |
|||
img{ |
|||
width: 34upx; |
|||
height: 34upx; |
|||
display: block; |
|||
} |
|||
} |
|||
} |
|||
.buy-count{ |
|||
color: #C5AA7B; |
|||
font-size: 20upx; |
|||
border: 2upx solid #E4E5E6; |
|||
line-height: 36upx; |
|||
padding: 0 5upx; |
|||
} |
|||
.price-warp{ |
|||
display: flex; |
|||
align-items: baseline; |
|||
line-height: 56upx; |
|||
.iconImg { |
|||
width: 58rpx; |
|||
height: 36rpx; |
|||
margin-right: 10rpx; |
|||
} |
|||
.price{ |
|||
color: #C83732; |
|||
font-size: 40upx; |
|||
margin-right: 20upx; |
|||
} |
|||
.original-price{ |
|||
font-size: 24upx; |
|||
color: #ccc; |
|||
text-decoration: line-through; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.emptyCart-box { |
|||
margin-top: 70rpx; |
|||
.emptyCart-img { |
|||
width: 216rpx; |
|||
height: 156rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
</style> |
@ -0,0 +1,24 @@ |
|||
<template> |
|||
<div class="div" :style="{backgroundColor:componentContent.bgColor,height:componentContent.height + 'rpx'}"></div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'assistDiv', |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.div{ |
|||
width: 100%; |
|||
} |
|||
</style> |
@ -0,0 +1,107 @@ |
|||
<template> |
|||
<div class="banner" :class="'terminal' + terminal"> |
|||
<swiper class="swiper" :circular="true" :indicator-dots="false" :autoplay="true" :style="{'height':bannerHeight + 'rpx'}" @change="swiperChange"> |
|||
<swiper-item class="banner-item" v-for="(item,index) in bannerList" :key="index" :style="{backgroundImage: 'url('+ item.bannerUrl +')'}" @click="jumpLink(item.linkObj)"> |
|||
<!-- <div class="a-link" @click="jumpLink(item.linkObj)"><img class="img" :src="item.bannerUrl" v-show="item.bannerUrl" mode="widthFix"></div>--> |
|||
</swiper-item> |
|||
</swiper> |
|||
<view class="swiper-dots" v-if="bannerList && bannerList.length > 1"> |
|||
<text class="dot" :class="index === swiperCurrent && 'dot-active'" v-for="(dot, index) in bannerList.length" |
|||
:key="index"></text> |
|||
</view> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {funMixin} from '../config/mixin' |
|||
export default { |
|||
name: 'cereBanner', |
|||
mixins: [funMixin], |
|||
data () { |
|||
return { |
|||
bannerHeight: 0, |
|||
swiperCurrent: 0 |
|||
} |
|||
}, |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.bannerHeight = this.componentContent.height |
|||
this.$forceUpdate() // 刷新轮播图 |
|||
}, |
|||
computed: { |
|||
bannerList: function () { |
|||
console.log(this.componentContent) |
|||
return this.componentContent.bannerData.filter(function (item) { |
|||
return item.bannerUrl |
|||
}) |
|||
} |
|||
}, |
|||
methods:{ |
|||
swiperChange(e) { |
|||
this.swiperCurrent = e.detail.current; |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.banner{ |
|||
position: relative; |
|||
.banner-item{ |
|||
width: 100%; |
|||
background-repeat: no-repeat; |
|||
background-position: center; |
|||
background-size: auto 100%; |
|||
img{ |
|||
display: none; |
|||
} |
|||
} |
|||
&.terminal4{ |
|||
::v-deep .el-carousel{ |
|||
height: 100%; |
|||
.el-carousel__container{ |
|||
height: 100%; |
|||
} |
|||
} |
|||
.banner-item{ |
|||
background-repeat: no-repeat; |
|||
background-position: center; |
|||
background-size: auto 100%; |
|||
img{ |
|||
display: none; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.swiper-dots { |
|||
display: flex; |
|||
position: absolute; |
|||
left: 50%; |
|||
transform: translateX(-50%); |
|||
bottom: 20upx; |
|||
z-index: 200; |
|||
.dot { |
|||
width: 12upx; |
|||
height: 12upx; |
|||
background: #FFFFFF; |
|||
border-radius: 6upx; |
|||
opacity: 0.2; |
|||
margin: 0 10upx; |
|||
} |
|||
|
|||
.dot-active { |
|||
opacity: 1; |
|||
width: 24upx; |
|||
} |
|||
} |
|||
|
|||
} |
|||
</style> |
@ -0,0 +1,131 @@ |
|||
<template> |
|||
<div class="brand-list warp" :class="'terminal' + terminal"> |
|||
<h2 class="hom-title" :style="{textAlign:componentContent.textAlign}">{{componentContent.title}}</h2> |
|||
<div class="content-warp"> |
|||
<div class="ul clearfix"> |
|||
<div class="li" v-for="(item, index) in componentContent.imgList" :key="index"> |
|||
<a class="item a-link" @click="jumpLink(item.linkObj)"> |
|||
<div class="imgBox"> |
|||
<img :src="item.imgData" v-show="item.imgData" :alt="item.title"> |
|||
</div> |
|||
<h4 class="h4">{{item.title}}</h4> |
|||
</a> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {funMixin} from '../config/mixin' |
|||
export default { |
|||
name: 'brandList', |
|||
mixins: [funMixin], |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
<style lang="scss" scoped> |
|||
.brand-list{ |
|||
color: #fff; |
|||
padding: 20upx 0; |
|||
.hom-title{ |
|||
font-size: 22upx; |
|||
color: #333; |
|||
line-height: 1em; |
|||
margin-bottom: 23upx; |
|||
font-weight: bold; |
|||
} |
|||
.content-warp{ |
|||
display: flex; |
|||
} |
|||
.first{ |
|||
width: 24%; |
|||
padding-top: 10upx; |
|||
.item{ |
|||
background-color: #7A8594; |
|||
height: 336upx; |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: center; |
|||
.h3{ |
|||
font-size: 30upx; |
|||
line-height: 46upx; |
|||
margin-bottom: 10upx; |
|||
} |
|||
} |
|||
} |
|||
.ul{ |
|||
width: 100%; |
|||
.li{ |
|||
width: 25%; |
|||
float: left; |
|||
padding: 10upx 0 0 10upx; |
|||
box-sizing: border-box; |
|||
.item{ |
|||
height: auto; |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: center; |
|||
.imgBox { |
|||
padding-bottom: 80%; |
|||
background-color: #cacaca; |
|||
position: relative; |
|||
} |
|||
.h4{ |
|||
font-size: 18upx; |
|||
color: #333333; |
|||
text-align: center; |
|||
height: 40upx; |
|||
line-height: 40upx; |
|||
} |
|||
.p{ |
|||
font-size: 12upx; |
|||
margin: 7upx 0 12upx; |
|||
} |
|||
img { |
|||
max-width: 100%; |
|||
height: 100%; |
|||
max-height: 100%; |
|||
position: absolute; |
|||
margin: auto; |
|||
top: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
left: 0; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.terminal1,.terminal2,.terminal3{ |
|||
&.brand-list{ |
|||
width: 710upx; |
|||
margin: 0 auto; |
|||
.content-warp{ |
|||
display: block; |
|||
} |
|||
.first{ |
|||
width: 100%; |
|||
} |
|||
.ul{ |
|||
width: auto; |
|||
margin-left: -15upx; |
|||
.li{ |
|||
width: 50%; |
|||
padding: 15upx 0 0 15upx; |
|||
.item { |
|||
padding-left: 0; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,109 @@ |
|||
<template> |
|||
<div class="category-list warp" :class="'terminal' + terminal"> |
|||
<h2 class="hom-title" :style="{textAlign:componentContent.textAlign}">{{componentContent.title}}</h2> |
|||
<div class="content-warp"> |
|||
<div class="ul clearfix" :class="{number5: componentContent.categoryData.length === 5}"> |
|||
<div class="li" v-for="(item) of componentContent.categoryData" :key="item.id"> |
|||
<a class="item a-link" @click="jumpCategory(item)"> |
|||
<div class="imgBox"> |
|||
<img ref="getHeight" :src="item.img" v-show="item.img" :alt="item.name"> |
|||
</div> |
|||
</a> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {funMixin} from '../config/mixin' |
|||
export default { |
|||
name: 'categoryList', |
|||
mixins: [funMixin], |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
<style lang="scss" scoped> |
|||
.category-list{ |
|||
padding: 20upx 0; |
|||
.hom-title{ |
|||
font-size: 22upx; |
|||
color: #333; |
|||
line-height: 1em; |
|||
margin-bottom: 23upx; |
|||
font-weight: bold; |
|||
text-align: center; |
|||
} |
|||
.content-warp{ |
|||
display: flex; |
|||
.ul{ |
|||
width: 100%; |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
.li{ |
|||
flex: 1; |
|||
padding: 10upx 0 0 10upx; |
|||
box-sizing: border-box; |
|||
.item{ |
|||
height: auto; |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: center; |
|||
.imgBox { |
|||
padding-bottom: 80%; |
|||
background-color: #cacaca; |
|||
position: relative; |
|||
} |
|||
img { |
|||
max-width: 100%; |
|||
height: 100%; |
|||
max-height: 100%; |
|||
position: absolute; |
|||
margin: auto; |
|||
top: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
left: 0; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.number5 { |
|||
display: block; |
|||
.li { |
|||
width: 25%; |
|||
float: left; |
|||
} |
|||
.li:nth-child(1) { |
|||
width: 50%; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@media screen and (max-width: 768px) { |
|||
.category-list .content-warp .ul .li{ |
|||
flex: 0 0 50%; |
|||
} |
|||
} |
|||
.terminal1,.terminal2,.terminal3{ |
|||
&.category-list .content-warp{ |
|||
display: block; |
|||
.ul{ |
|||
margin: -15upx 0 0 -15upx; |
|||
width: auto; |
|||
.li{ |
|||
flex: 0 0 50%; |
|||
padding: 15upx 0 0 15upx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,113 @@ |
|||
<template> |
|||
<div class="coupon"> |
|||
<div class="coupon-list"> |
|||
<div class="coupon-item" v-for="(item,index) in couponsData" :key="index" :class="item.state && item.state !== 3 && 'isReceive'"> |
|||
<!-- #ifdef MP-WEIXIN --> |
|||
<img class="coupon-item-bg" src="../../../static/images/coupon/bg-coupon.png" v-if="item.state && item.state === 3" mode="widthFix"> |
|||
<img class="coupon-item-bg" src="../../../static/images/coupon/bg-coupon2.png" v-else mode="widthFix"> |
|||
<!-- #endif --> |
|||
<!-- #ifdef H5 || APP-PLUS --> |
|||
<image class="coupon-item-bg" src="../../../static/images/coupon/bg-coupon.png" v-if="item.state && item.state === 3" mode="widthFix"> |
|||
<image class="coupon-item-bg" src="../../../static/images/coupon/bg-coupon2.png" v-else mode="widthFix"> |
|||
<!-- #endif --> |
|||
<div class="coupon-item-cont"> |
|||
<div class="coupon-item-content"> |
|||
<div class="coupon-item-price"> |
|||
<div class="span" v-if="item.couponType !== 2">¥</div> |
|||
<div class="b" v-if="typeId !== 1">{{item.couponContent}}</div> |
|||
<div class="b" v-else>{{item.reduceMoney}}</div> |
|||
<div class="b" v-if="item.couponType == 2">折券</div> |
|||
</div> |
|||
<div class="coupon-item-date">{{item.startTime.split(' ')[0].replace(/-/g, '.')}}-{{item.endTime.split(' ')[0].replace(/-/g, '.')}}</div> |
|||
<div class="coupon-item-text">{{item.content}}</div> |
|||
</div> |
|||
<button v-if="item.state === 0" class="coupon-item-btn">已领取</button> |
|||
<button v-else-if="item.state === 1" class="coupon-item-btn">已使用</button> |
|||
<button v-else-if="item.state === 2" class="coupon-item-btn">已过期</button> |
|||
<button v-else @click="receiveCoupon(item)" class="coupon-item-btn">立即领取</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {commonMixin} from '../mixin' |
|||
export default { |
|||
mixins: [commonMixin] |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.coupon { |
|||
padding: 25upx; |
|||
&-list{ |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
} |
|||
&-item{ |
|||
width: 335upx; |
|||
height: 292upx; |
|||
margin-left: 28upx; |
|||
text-align: center; |
|||
position: relative; |
|||
margin-bottom: 10upx; |
|||
&-bg{ |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
&-cont{ |
|||
position: absolute; |
|||
width: 100%; |
|||
height: 100%; |
|||
left: 0; |
|||
top: 0; |
|||
} |
|||
&:nth-child(2n+1){ |
|||
margin-left: 0; |
|||
} |
|||
&-content{ |
|||
text-align: center; |
|||
} |
|||
&-price{ |
|||
color: #C5AA7B; |
|||
margin: 26upx 0 10upx; |
|||
.span{ |
|||
display: inline; |
|||
font-size: 36upx; |
|||
line-height: 68upx; |
|||
} |
|||
.b{ |
|||
display: inline; |
|||
font-size: 50upx; |
|||
line-height: 68upx; |
|||
} |
|||
} |
|||
&-date,&-text{ |
|||
font-size: 20upx; |
|||
line-height: 28upx; |
|||
color: #999999; |
|||
} |
|||
&-date{ |
|||
margin-bottom: 8upx; |
|||
} |
|||
&-btn{ |
|||
display: inline-block; |
|||
margin: 60upx auto 0; |
|||
height: 48upx; |
|||
line-height: 48upx; |
|||
background-color: #C5AA7B; |
|||
color: #fff; |
|||
font-size: 14upx |
|||
} |
|||
&.isReceive{ |
|||
&-price{ |
|||
color: #999; |
|||
} |
|||
&-btn{ |
|||
background-color: #ccc; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,109 @@ |
|||
import api from '../../config/api' |
|||
import NET from '../../../../utils/request' |
|||
import { funMixin } from '../../config/mixin' |
|||
|
|||
export const commonMixin = { |
|||
name: 'textComponent', |
|||
mixins: [funMixin], |
|||
data () { |
|||
return { |
|||
couponsData: [] |
|||
} |
|||
}, |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
typeId: { |
|||
type: Number, |
|||
default: 1 |
|||
}, |
|||
shopId: { |
|||
type: Number, |
|||
default: 0 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
}, |
|||
watch: { |
|||
'componentContent': { |
|||
handler(newVal, oldVal) { |
|||
this.getData() |
|||
}, |
|||
deep: true |
|||
} |
|||
}, |
|||
created() { |
|||
this.getData() |
|||
}, |
|||
methods: { |
|||
getData() { |
|||
const _ = this |
|||
if(_.componentContent.selectedCoupon && _.componentContent.selectedCoupon.length > 0){ |
|||
let _url = '' |
|||
if(_.typeId === 1){ |
|||
_url =`${api.getCoupons}?page=1&pageSize=99&ids=${_.componentContent.selectedCoupon}` |
|||
} else if(_.typeId === 3) { |
|||
_url =`${api.getShopCoupons}?page=1&pageSize=99&shopId=${_.shopId}&ids=${_.componentContent.selectedCoupon}` |
|||
} |
|||
const params = { |
|||
method: 'GET', |
|||
url: _url, |
|||
} |
|||
this.sendReq(params, (res) => { |
|||
_.couponsData = res.data.list |
|||
if(_.typeId === 1){ |
|||
_.couponsData.forEach(item=>{ |
|||
item.couponName = item.activityName |
|||
item.effectiveStart = item.activityStartTime |
|||
item.effectiveEnd = item.activityEndTime |
|||
}) |
|||
} |
|||
if(JSON.stringify(_.componentContent.couponList) !== JSON.stringify(_.couponsData)){ |
|||
_.componentContent.couponList = _.couponsData |
|||
} |
|||
}) |
|||
} else { |
|||
_.couponsData = [] |
|||
} |
|||
}, |
|||
// 领取优惠券
|
|||
receiveCoupon(item) { |
|||
const res = uni.getStorageSync('storage_key'); |
|||
const token = res.token |
|||
if (token) { |
|||
var paramsData = {} |
|||
if(this.typeId === 1){ |
|||
paramsData.couponId = item.couponId |
|||
} else if(this.typeId === 3) { |
|||
paramsData.shopCouponId = item.shopCouponId |
|||
paramsData.shopId = this.shopId |
|||
} |
|||
NET.request(api.takeCoupon, paramsData, 'POST').then(res => { |
|||
this.getData() |
|||
uni.showToast({ |
|||
title:'领取成功', |
|||
icon:"success" |
|||
}) |
|||
}).catch(res => { |
|||
if(res.data.code !== '200'){ |
|||
uni.showToast({ |
|||
title:res.data.message, |
|||
icon:"none" |
|||
}) |
|||
} |
|||
}) |
|||
} else { |
|||
uni.showToast({ |
|||
title:'请先登录', |
|||
icon:"none" |
|||
}) |
|||
uni.navigateTo({ |
|||
url:'/pages_category_page2/userModule/login' |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,375 @@ |
|||
<template> |
|||
<div class="couponBox warp" :class="['terminal' + terminal,'arrange'+(componentContent.arrangeActiveIndex+1),'color'+(componentContent.colorActiveIndex+1)]"> |
|||
<div class="couponListBox" v-if="componentContent.selectedCoupon"> |
|||
<div class="listItemBox" v-for="(item,index) in couponsData" :key="index" :class="item.state && item.state !== 3 && 'isReceive'"> |
|||
<div class="listItemBoxInner"> |
|||
<div class="itemInfo"> |
|||
<i class="flag" :class="'flag'+item.couponType"></i> |
|||
<div class="amount"> |
|||
<b v-if="item.couponType !== 2">¥</b> |
|||
<span v-if="typeId !== 1"> |
|||
{{item.couponContent}} |
|||
</span> |
|||
<span v-else> |
|||
{{item.reduceMoney}} |
|||
</span> |
|||
<b v-if="item.couponType == 2">折</b> |
|||
</div> |
|||
<div class="couponInfo"> |
|||
<p>{{item.content}}</p> |
|||
</div> |
|||
</div> |
|||
<!-- <div class="itemInfo" v-else>--> |
|||
<!-- <div class="amount">--> |
|||
<!-- <b>¥</b><span>{{item.reduceMoney}}<i>满减券</i></span>--> |
|||
<!-- </div>--> |
|||
<!-- <div class="couponInfo">--> |
|||
<!-- <p>{{item.content}}</p>--> |
|||
<!-- </div>--> |
|||
<!-- </div>--> |
|||
<div v-if="item.state === 0" class="receiveBtn"> |
|||
<span>己领取</span> |
|||
</div> |
|||
<div v-else-if="item.state === 1" class="receiveBtn"> |
|||
<span>已使用</span> |
|||
</div> |
|||
<div v-else-if="item.state === 2" class="receiveBtn"> |
|||
<span>已过期</span> |
|||
</div> |
|||
<div v-else class="receiveBtn" @click="receiveCoupon(item)"> |
|||
<span>立即领取</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {commonMixin} from '../mixin' |
|||
export default { |
|||
mixins: [commonMixin] |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.couponBox { |
|||
min-height: 177px; |
|||
margin: 0 auto; |
|||
padding: 20px 0; |
|||
.couponListBox { |
|||
flex-wrap: wrap; |
|||
/**默认**/ |
|||
.listItemBox { |
|||
//background-image:url('../../../static/images/coupon/border_L1.png'), url('../../../static/images/coupon/border_R1.png'); |
|||
//background-repeat: no-repeat, no-repeat; |
|||
//background-position: left top, right top; |
|||
box-sizing: border-box; |
|||
margin-bottom: 20px; |
|||
.listItemBoxInner { |
|||
width: 100%; |
|||
height: 150px; |
|||
display: flex; |
|||
background-color: #FAFAFA; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
position: relative; |
|||
.flag{ |
|||
display: block; |
|||
width: 71px; |
|||
height: 71px; |
|||
background-repeat: no-repeat; |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
&.flag1{ |
|||
background-image: url("../../../static/images/coupon/flag-coupon.png"); |
|||
} |
|||
&.flag2{ |
|||
background-image: url("../../../static/images/coupon/flag-coupon2.png"); |
|||
} |
|||
} |
|||
.itemInfo { |
|||
flex: 1; |
|||
} |
|||
.amount { |
|||
max-width: 90%; |
|||
margin: 0 auto; |
|||
display: flex; |
|||
align-items: baseline; |
|||
justify-content: center; |
|||
line-height: 60px; |
|||
b { |
|||
font-size: 30px; |
|||
} |
|||
span { |
|||
font-size: 60px; |
|||
font-weight: bold; |
|||
} |
|||
i { |
|||
font-style: normal; |
|||
font-size: 18px; |
|||
margin-left: 5px; |
|||
} |
|||
} |
|||
.couponInfo { |
|||
text-align: center; |
|||
p { |
|||
display: inline-block; |
|||
padding: 0 42px; |
|||
text-align: center; |
|||
font-size: 18px; |
|||
line-height: 40px; |
|||
color: #C83732; |
|||
background: #F5E5E5; |
|||
} |
|||
} |
|||
} |
|||
.receiveBtn { |
|||
width: 72px; |
|||
margin-right: 5px; |
|||
background: #C5AA7B; |
|||
height: 100%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
cursor: pointer; |
|||
position: relative; |
|||
&:before,&:after{ |
|||
content: ''; |
|||
display: block; |
|||
width: 25px; |
|||
height: 25px; |
|||
background-color: #fff; |
|||
position: absolute; |
|||
left: -12.5px; |
|||
border-radius: 50%; |
|||
} |
|||
&:before{ |
|||
top: -12.5px; |
|||
} |
|||
&:after{ |
|||
bottom: -12.5px; |
|||
} |
|||
span { |
|||
color: #FFFFFF !important; |
|||
writing-mode: vertical-lr; |
|||
font-size: 19px; |
|||
} |
|||
} |
|||
&.isReceive { |
|||
//background-image:url('../../../static/images/coupon/border_L4.png'), url('../../../static/images/coupon/border_R4.png'); |
|||
.listItemBoxInner { |
|||
.flag{ |
|||
&.flag1{ |
|||
background-image: url("../../../static/images/coupon/flag-coupon-r.png"); |
|||
} |
|||
&.flag2{ |
|||
background-image: url("../../../static/images/coupon/flag-coupon2-r.png"); |
|||
} |
|||
} |
|||
.itemInfo { |
|||
color: #999; |
|||
.couponInfo { |
|||
p { |
|||
color: #999; |
|||
background: #F1F1F1; |
|||
} |
|||
} |
|||
} |
|||
.receiveBtn { |
|||
cursor: auto; |
|||
background: #999; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
@mixin cardColor($bgColor: #FF3737,$fontColor: #fff) { |
|||
.couponListBox { |
|||
.listItemBox { |
|||
.listItemBoxInner{ |
|||
background: $bgColor; |
|||
} |
|||
.itemInfo { |
|||
.amount { |
|||
b { |
|||
color: #EC4B42; |
|||
} |
|||
span { |
|||
color: #EC4B42; |
|||
i { |
|||
color: #EC4B42; |
|||
} |
|||
} |
|||
} |
|||
.couponInfo { |
|||
color:#EC4B42; |
|||
} |
|||
} |
|||
.receiveBtn { |
|||
span { |
|||
color: #EC4B42; |
|||
} |
|||
} |
|||
&.cardStyle3{ |
|||
.itemInfo { |
|||
.amount { |
|||
span { |
|||
color: $bgColor; |
|||
i { |
|||
color: $bgColor; |
|||
} |
|||
} |
|||
} |
|||
.couponInfo { |
|||
color:$bgColor; |
|||
} |
|||
} |
|||
} |
|||
&.cardStyle4{ |
|||
border: 2px solid $bgColor; |
|||
padding: 5px; |
|||
.listItemBoxInner{ |
|||
padding: 20px 15px; |
|||
height: 85px; |
|||
border: 1px solid $bgColor; |
|||
} |
|||
.itemInfo { |
|||
.amount { |
|||
span { |
|||
color: $bgColor; |
|||
i { |
|||
color: $bgColor; |
|||
} |
|||
} |
|||
} |
|||
.couponInfo { |
|||
color:$bgColor; |
|||
} |
|||
} |
|||
.receiveBtn { |
|||
border-left: 1px $bgColor dashed; |
|||
span { |
|||
color: $bgColor; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
&.arrange1{ |
|||
|
|||
} |
|||
&.arrange2{ |
|||
max-width: 100%; |
|||
.couponListBox{ |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
justify-content: space-between; |
|||
.listItemBox{ |
|||
width: 48%; |
|||
} |
|||
} |
|||
} |
|||
&.arrange3{ |
|||
max-width: 100%; |
|||
.couponListBox{ |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
justify-content: space-between; |
|||
.listItemBox{ |
|||
width: 32%; |
|||
} |
|||
} |
|||
} |
|||
&.arrange4{ |
|||
max-width: 100%; |
|||
.couponListBox{ |
|||
display: flex; |
|||
overflow: hidden; |
|||
.listItemBox{ |
|||
width: 268px; |
|||
flex: 0 0 268px; |
|||
margin:0 25px 25px 0; |
|||
&:nth-child(4n){ |
|||
margin-right: 0; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
//&.color1{ |
|||
// .listItemBox { |
|||
// background-image:url('../../../static/images/coupon/border_L1.png'), url('../../../static/images/coupon/border_R1.png'); |
|||
// .listItemBoxInner { |
|||
// border-top: 1px solid #EC4B42; |
|||
// border-bottom: 1px solid #EC4B42; |
|||
// .itemInfo { |
|||
// color: #EC4B42; |
|||
// .amount { |
|||
// border-bottom: 1px solid #EC4B42; |
|||
// } |
|||
// .couponInfo { |
|||
// p { |
|||
// color: #EC4B42; |
|||
// } |
|||
// } |
|||
// } |
|||
// .receiveBtn { |
|||
// background: #EC4B42; |
|||
// } |
|||
// } |
|||
// } |
|||
//} |
|||
|
|||
&.color2{ |
|||
.listItemBox { |
|||
background-image:url('../../../static/images/coupon/border_L2.png'), url('../../../static/images/coupon/border_R2.png'); |
|||
.listItemBoxInner { |
|||
border-top: 1px solid #FF7800; |
|||
border-bottom: 1px solid #FF7800; |
|||
.itemInfo { |
|||
color: #FF7800; |
|||
.amount { |
|||
border-bottom: 1px solid #FF7800; |
|||
} |
|||
.couponInfo { |
|||
p { |
|||
color: #FF7800; |
|||
} |
|||
} |
|||
} |
|||
.receiveBtn { |
|||
background: #FF7800; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
&.color3{ |
|||
.listItemBox { |
|||
background-image:url('../../../static/images/coupon/border_L3.png'), url('../../../static/images/coupon/border_R3.png'); |
|||
.listItemBoxInner { |
|||
border-top: 1px solid #86A7FF; |
|||
border-bottom: 1px solid #86A7FF; |
|||
.itemInfo { |
|||
color: #86A7FF; |
|||
.amount { |
|||
border-bottom: 1px solid #86A7FF; |
|||
} |
|||
.couponInfo { |
|||
p { |
|||
color: #86A7FF; |
|||
} |
|||
} |
|||
} |
|||
.receiveBtn { |
|||
background: #86A7FF; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,238 @@ |
|||
<template> |
|||
<div class="custom" :class="'terminal' + terminal"> |
|||
<div class="rowLayout" v-if="componentContent.layoutType ==='L1' || componentContent.layoutType ==='L2' || componentContent.layoutType ==='L3' || componentContent.layoutType ==='L4'"> |
|||
<div class="customLayout" :style="{'padding':'0 ' + componentContent.pageSpacing + 'px','marginLeft':(-componentContent.imgClearance) +'px'}"> |
|||
<div class="ul clearfix" :class="'layout'+componentContent.layoutType"> |
|||
<div class='li' v-for="(item,index) of componentContent.imgData" :key="index" :style="{'width':getItemValue(item.width) + '%','height':getItemValue(item.height) + '%','left':getItemValue(item.left) + '%','top':getItemValue(item.top) + '%','paddingLeft':componentContent.imgClearance +'px'}"> |
|||
<a class="a-link" @click="jumpLink(item.linkObj)"><img class="img" :src="item.src" v-if="item.src" mode="widthFix"></a> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div v-else :style="{'padding':'0 ' + componentContent.pageSpacing + 'upx'}"> |
|||
<div class="boxLayout" :style="{'paddingBottom':componentContent.maxH !== 0?getItemValue(componentContent.maxH) + '%': '100%'}"> |
|||
<div class="boxLayoutInner"> |
|||
<div class="boxWarp"> |
|||
<div class="customLayout" :style="{'marginLeft':(-componentContent.imgClearance) +'px','top':(-componentContent.imgClearance) +'px'}"> |
|||
<div class="ul clearfix" :class="'layout'+componentContent.layoutType"> |
|||
<div class='li' v-for="(item,index) of componentContent.imgData" :key="index" :style="{'width':getItemValue(item.width) + '%','height':getItemValue(item.height) + '%','left':getItemValue(item.left) + '%','top':getItemValue(item.top) + '%','padding':componentContent.imgClearance +'px 0 0 ' + componentContent.imgClearance +'px'}"> |
|||
<a class="a-link" @click="jumpLink(item.linkObj)"><img class="img" :src="item.src" v-if="item.src" mode="widthFix"></a> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {funMixin} from '../config/mixin' |
|||
export default { |
|||
name: 'customComponent', |
|||
mixins: [funMixin], |
|||
data () { |
|||
return { |
|||
} |
|||
}, |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
}, |
|||
methods: { |
|||
// 计算生成格子百分比 |
|||
getItemValue (val) { |
|||
const density = parseInt(this.componentContent.density) |
|||
if (val === 0 || density === 0) { |
|||
return 0 |
|||
} |
|||
return (val / density * 10000 / 100.00)// 小数点后两位百分比 |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.custom{ |
|||
//width: 710upx; |
|||
//margin: 0 auto; |
|||
.boxLayout{ |
|||
position: relative; |
|||
.boxLayoutInner{ |
|||
padding-bottom: 100%; |
|||
position: absolute; |
|||
width: 100%; |
|||
left: 0; |
|||
top: 0; |
|||
} |
|||
.boxWarp{ |
|||
position: absolute; |
|||
width: 100%; |
|||
height: 100%; |
|||
left: 0; |
|||
top: 0; |
|||
overflow: hidden; |
|||
} |
|||
} |
|||
.customLayout{ |
|||
position: relative; |
|||
.ul{ |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
position: relative; |
|||
} |
|||
.li{ |
|||
box-sizing: border-box; |
|||
.img{ |
|||
width: 100%; |
|||
display: block; |
|||
} |
|||
} |
|||
.layoutL1 .li{ |
|||
flex: 0 0 100%; |
|||
} |
|||
.layoutL2 .li{ |
|||
flex: 0 0 50%; |
|||
} |
|||
.layoutL3 .li{ |
|||
flex: 0 0 33.3%; |
|||
} |
|||
.layoutL4 .li{ |
|||
flex: 0 0 25%; |
|||
} |
|||
.layoutT2B2{ |
|||
padding-bottom: 100%; |
|||
.li{ |
|||
width: 50%; |
|||
height: 50%; |
|||
position: absolute; |
|||
.img{ |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
&:nth-child(1){ |
|||
left: 0; |
|||
top: 0; |
|||
} |
|||
&:nth-child(2){ |
|||
right: 0; |
|||
top: 0; |
|||
} |
|||
&:nth-child(3){ |
|||
left: 0; |
|||
bottom: 0; |
|||
} |
|||
&:nth-child(4){ |
|||
right: 0; |
|||
bottom: 0; |
|||
} |
|||
} |
|||
} |
|||
.layoutL1R2{ |
|||
padding-bottom: 100%; |
|||
.li{ |
|||
width: 50%; |
|||
height: 50%; |
|||
position: absolute; |
|||
.img{ |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
&:nth-child(1){ |
|||
height: 100%; |
|||
left: 0; |
|||
top: 0; |
|||
} |
|||
&:nth-child(2){ |
|||
right: 0; |
|||
top: 0; |
|||
} |
|||
&:nth-child(3){ |
|||
right: 0; |
|||
bottom: 0; |
|||
} |
|||
} |
|||
} |
|||
.layoutT1B2{ |
|||
padding-bottom: 100%; |
|||
.li{ |
|||
width: 50%; |
|||
height: 50%; |
|||
position: absolute; |
|||
.img{ |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
&:nth-child(1){ |
|||
width: 100%; |
|||
left: 0; |
|||
top: 0; |
|||
} |
|||
&:nth-child(2){ |
|||
left: 0; |
|||
bottom: 0; |
|||
} |
|||
&:nth-child(3){ |
|||
right: 0; |
|||
bottom: 0; |
|||
} |
|||
} |
|||
} |
|||
.layoutL1T1B2{ |
|||
padding-bottom: 50%; |
|||
.li{ |
|||
position: absolute; |
|||
.img{ |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
&:nth-child(1){ |
|||
width: 50%; |
|||
height: 100%; |
|||
left: 0; |
|||
top: 0; |
|||
} |
|||
&:nth-child(2){ |
|||
right: 0; |
|||
top: 0; |
|||
width: 50%; |
|||
height: 50%; |
|||
} |
|||
&:nth-child(3){ |
|||
left: 50%; |
|||
bottom: 0; |
|||
width: 25%; |
|||
height: 50%; |
|||
} |
|||
&:nth-child(4){ |
|||
right: 0; |
|||
bottom: 0; |
|||
width: 25%; |
|||
height: 50%; |
|||
} |
|||
} |
|||
} |
|||
.layoutaverage{ |
|||
padding-bottom: 100%; |
|||
.li{ |
|||
position: absolute; |
|||
.img{ |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
} |
|||
} |
|||
// #ifdef MP |
|||
.layoutaverage{ |
|||
padding-bottom: 91%; |
|||
} |
|||
// #endif |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,300 @@ |
|||
<template> |
|||
<div class="hom-pro-list" v-if="productData.products.length"> |
|||
<div class="title"> |
|||
<!-- #ifdef MP-WEIXIN --> |
|||
<img class="title-img" src="../../../static/images/discount/img-title.png" alt="限时折扣" mode="widthFix"/> |
|||
<!-- #endif --> |
|||
<!-- #ifdef H5 || APP-PLUS --> |
|||
<image class="title-img" src="../../../static/images/discount/img-title.png" alt="限时折扣" mode="widthFix"/> |
|||
<!-- #endif --> |
|||
</div> |
|||
<div v-if="componentContent.arrangeType == '横向滑动' && productData.products.length > 2" class="product-list"> |
|||
<swiper ref="mySwiper" class="swiper product-list-box" :circular="true" :indicator-dots="false" :autoplay="true" :display-multiple-items="2" @change="swiperChange"> |
|||
<swiper-item class="swiper-slide product-list-item-warp" v-for="(item,index) in productData.products.slice(0, 10)" :key="index" @click="jumpProductDetail(item)"> |
|||
<div class="product-list-item"> |
|||
<div class="product-list-img"> |
|||
<img class="img default-img" :src="item.image"> |
|||
</div> |
|||
<div class="product-list-info"> |
|||
<label class="product-name">{{item.productName}}</label> |
|||
<div> |
|||
<div class="flag"> |
|||
<!-- #ifdef MP-WEIXIN --> |
|||
<img class="icon" src="../../../static/images/discount/flag-discount2.png" alt="限时折扣" mode="widthFix"/> |
|||
<!-- #endif --> |
|||
<!-- #ifdef H5 || APP-PLUS --> |
|||
<image class="icon" src="../../../static/images/discount/flag-discount2.png" alt="限时折扣" mode="widthFix"/> |
|||
<!-- #endif --> |
|||
</div> |
|||
<label class="buy-count">剩余{{item.stockNumber}}件</label> |
|||
</div> |
|||
<div class="price-warp"> |
|||
<div class="price"> |
|||
¥ {{item.price}} |
|||
</div> |
|||
<div class="original-price"> |
|||
¥ {{item.originalPrice}} |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</swiper-item> |
|||
</swiper> |
|||
<view class="swiper-dots" v-if="productData.products && productData.products.length > 2"> |
|||
<text class="dot" :class="index - swiperCurrent <= 1 && index - swiperCurrent >=0 && 'dot-active'" v-for="(dot, index) in productData.products.length" |
|||
:key="index"></text> |
|||
</view> |
|||
<!-- <div class="pagination discount-pagination" slot="pagination"></div>--> |
|||
</div> |
|||
<div v-else class="product-list"> |
|||
<div class="product-list-box" > |
|||
<div class="product-list-item-warp" v-for="(item,index) in productData.products" :key="index" @click="jumpProductDetail(item)"> |
|||
<div class="product-list-item"> |
|||
<div class="product-list-img"> |
|||
<img class="img default-img" :src="item.image"> |
|||
</div> |
|||
<div class="product-list-info"> |
|||
<label class="product-name">{{item.productName}}</label> |
|||
<div> |
|||
<div class="flag"> |
|||
<!-- #ifdef MP-WEIXIN --> |
|||
<img class="icon" src="../../../static/images/discount/flag-discount2.png" alt="限时折扣" mode="widthFix"/> |
|||
<!-- #endif --> |
|||
<!-- #ifdef H5 || APP-PLUS --> |
|||
<image class="icon" src="../../../static/images/discount/flag-discount2.png" alt="限时折扣" mode="widthFix"/> |
|||
<!-- #endif --> |
|||
</div> |
|||
<label class="buy-count">剩余{{item.stockNumber}}件</label> |
|||
</div> |
|||
<div class="price-warp"> |
|||
<div class="price"> |
|||
¥ {{item.price}} |
|||
</div> |
|||
<div class="original-price"> |
|||
¥ {{item.originalPrice}} |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<button v-show="componentContent.showMore" class="btn-more" @click="jumpDiscount(productData)">查看全部 <span class="icon iconfont icon-arrow-right"></span></button> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {commonMixin} from '../mixin' |
|||
export default { |
|||
mixins: [commonMixin], |
|||
data () { |
|||
return { |
|||
swiperCurrent: 0, |
|||
} |
|||
}, |
|||
methods:{ |
|||
swiperChange(e) { |
|||
this.swiperCurrent = e.detail.current; |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.hom-pro-list{ |
|||
padding: 20px 0; |
|||
.title{ |
|||
text-align: center; |
|||
margin-bottom: 20upx; |
|||
.title-img{ |
|||
width: 203upx; |
|||
} |
|||
} |
|||
/**多行多列**/ |
|||
.product-list { |
|||
position: relative; |
|||
&-box { |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
flex-direction: row; |
|||
padding-left: 20upx; |
|||
&.swiper{ |
|||
height: 620upx; |
|||
} |
|||
} |
|||
&.product-swiper .product-list-box{ |
|||
margin: 0 20upx; |
|||
padding-left: 0; |
|||
} |
|||
&-item-warp{ |
|||
margin: 0 0 20upx 0; |
|||
} |
|||
&-item { |
|||
width: 348upx; |
|||
padding: 0 7upx; |
|||
box-sizing: content-box; |
|||
} |
|||
&-img { |
|||
width: 348upx; |
|||
height: 348upx; |
|||
background-color: #f5f5f5; |
|||
border-radius: 10upx 10upx 0 0; |
|||
.img { |
|||
width: 100%; |
|||
height: 100%; |
|||
object-fit: contain; |
|||
} |
|||
} |
|||
&-info { |
|||
background-color: #FFFFFF; |
|||
//box-shadow: 0px 0px 15px 0px rgba(52, 52, 52, 0.15); |
|||
border-radius: 0 0 10upx 10upx; |
|||
padding: 20upx; |
|||
label{ |
|||
font-weight: normal; |
|||
} |
|||
.product-name{ |
|||
font-size: 28upx; |
|||
color: #333; |
|||
display: block; |
|||
overflow: hidden; |
|||
text-overflow:ellipsis; |
|||
white-space: nowrap; |
|||
margin-bottom: 18upx; |
|||
line-height: 40upx; |
|||
} |
|||
.shop-box{ |
|||
background-color: #333333; |
|||
border-radius: 0px 20upx 20upx 0upx; |
|||
line-height: 40upx; |
|||
display: inline-block; |
|||
height: 40upx; |
|||
margin-right: 10upx; |
|||
.shop-name{ |
|||
font-size: 20upx; |
|||
color: #FFEBC4; |
|||
padding: 0 8px 0 12upx; |
|||
} |
|||
.shop-logo{ |
|||
border: 2px solid #707070; |
|||
border-radius: 50%; |
|||
overflow: hidden; |
|||
float: right; |
|||
img{ |
|||
width: 34upx; |
|||
height: 34upx; |
|||
display: block; |
|||
} |
|||
} |
|||
} |
|||
.flag{ |
|||
float: left; |
|||
margin-right: 20upx; |
|||
.icon{ |
|||
width: 100rpx; |
|||
height: 40rpx; |
|||
display: block; |
|||
} |
|||
} |
|||
.buy-count{ |
|||
color: #C5AA7B; |
|||
font-size: 20upx; |
|||
border: 2upx solid #E4E5E6; |
|||
line-height: 40upx; |
|||
padding: 0 5upx; |
|||
display: inline-block; |
|||
} |
|||
.price-warp{ |
|||
display: flex; |
|||
align-items: baseline; |
|||
line-height: 56upx; |
|||
margin-top: 16upx; |
|||
.price{ |
|||
color: #C83732; |
|||
font-size: 40upx; |
|||
margin-right: 20upx; |
|||
} |
|||
.original-price{ |
|||
font-size: 24upx; |
|||
color: #ccc; |
|||
text-decoration: line-through; |
|||
} |
|||
} |
|||
} |
|||
//::v-deep .swiper-pagination-bullet{ |
|||
// display: none; |
|||
//} |
|||
} |
|||
} |
|||
|
|||
//::v-deep .uni-swiper-dots{ |
|||
// display: flex; |
|||
// justify-content: center; |
|||
// padding: 10upx 0; |
|||
// .uni-swiper-dot{ |
|||
// width: 10upx; |
|||
// height: 10upx; |
|||
// background: #333333; |
|||
// opacity: 0.3; |
|||
// border-radius: 5upx; |
|||
// margin: 0 5upx; |
|||
// &-active{ |
|||
// width: 20upx; |
|||
// height: 10upx; |
|||
// opacity: 1; |
|||
// } |
|||
// } |
|||
//} |
|||
.swiper-dots { |
|||
display: flex; |
|||
position: absolute; |
|||
left: 50%; |
|||
transform: translateX(-50%); |
|||
bottom: 15rpx; |
|||
z-index: 66; |
|||
.dot { |
|||
width: 10upx; |
|||
height: 10upx; |
|||
background: #333333; |
|||
opacity: 0.3; |
|||
border-radius: 5upx; |
|||
margin: 0 10upx; |
|||
} |
|||
|
|||
.dot-active { |
|||
width: 20upx; |
|||
opacity: 1; |
|||
} |
|||
} |
|||
//.pagination{ |
|||
// display: flex; |
|||
// justify-content: center; |
|||
// padding: 20upx 0; |
|||
// ::v-deep .swiper-pagination-bullet{ |
|||
// width: 10upx; |
|||
// height: 10upx; |
|||
// background: #333333; |
|||
// opacity: 0.3; |
|||
// border-radius: 5upx; |
|||
// margin: 0 5upx; |
|||
// } |
|||
// ::v-deep .swiper-pagination-bullet-active{ |
|||
// width: 20upx; |
|||
// height: 10upx; |
|||
// opacity: 1; |
|||
// } |
|||
//} |
|||
.btn-more { |
|||
width: 170upx; |
|||
height: 54upx; |
|||
line-height: 54upx; |
|||
border: 2upx solid #C5AA7B; |
|||
color: #C5AA7B; |
|||
font-size: 24upx; |
|||
background-color: transparent; |
|||
margin: 20upx auto 0; |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
|
|||
</style> |
@ -0,0 +1,110 @@ |
|||
// import { directive, Swiper, SwiperSlide } from 'vue-awesome-swiper'
|
|||
// import 'swiper/css/swiper.css'
|
|||
import api from '../../config/api' |
|||
import {funMixin} from '../../config/mixin' |
|||
|
|||
export const commonMixin = { |
|||
name: 'discountList', |
|||
mixins: [funMixin], |
|||
data () { |
|||
return { |
|||
value: 100, |
|||
productData: { |
|||
products: [] |
|||
}, |
|||
count: [], |
|||
timer: null |
|||
} |
|||
}, |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
typeId: { |
|||
type: Number, |
|||
default: 1 |
|||
}, |
|||
shopId: { |
|||
type: Number, |
|||
default: 0 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
}, |
|||
// components: {
|
|||
// Swiper,
|
|||
// SwiperSlide
|
|||
// },
|
|||
// directives: {
|
|||
// swiper: directive
|
|||
// },
|
|||
watch: { |
|||
'componentContent': { |
|||
handler(newVal, oldVal) { |
|||
this.getData() |
|||
}, |
|||
deep: true |
|||
} |
|||
}, |
|||
created() { |
|||
this.getData() |
|||
}, |
|||
methods: { |
|||
getData() { |
|||
const _ = this |
|||
if(_.componentContent.discountId){ |
|||
var _url= '' |
|||
if(this.typeId === 1){ |
|||
_url= `${api.getMinDiscount}?ids=${_.componentContent.discountId}` |
|||
} |
|||
if(this.typeId === 3){ |
|||
_url= `${api.getDiscounts}?shopId=${_.shopId}&ids=${_.componentContent.discountId}` |
|||
} |
|||
const params = { |
|||
method: 'GET', |
|||
url: _url, |
|||
} |
|||
this.sendReq(params, (res) => { |
|||
if(res.data.length> 0){ |
|||
_.productData = res.data[0] |
|||
// 只有进行中和未开始活动, 用倒计时
|
|||
if(_.productData.state !==2) { |
|||
this.timer = setInterval(()=>{ |
|||
_.getTime(_.productData) |
|||
}, 1000) |
|||
} |
|||
} |
|||
}) |
|||
} else { |
|||
_.productData = { |
|||
products:[] |
|||
} |
|||
} |
|||
}, |
|||
getTime(info) { |
|||
const date = new Date().getTime() |
|||
const startTime = new Date(info.startTime.replace(/-/g,'/')).getTime() |
|||
const endTime = new Date(info.endTime.replace(/-/g,'/')).getTime() |
|||
if(startTime > date) { |
|||
this.countDown(startTime-date,true) // 未开始
|
|||
} else { |
|||
this.countDown(endTime-date) // 进行中
|
|||
} |
|||
|
|||
}, |
|||
countDown(time, isStart) { |
|||
const fn = (v) => v < 10 ? `0${v}` : v |
|||
const t = parseInt(time / 1000) |
|||
const text = isStart ? '开始' : '结束' |
|||
const hour = parseInt(t / 3600) |
|||
const min = parseInt((t % 3600) / 60) |
|||
const s = t % 60 |
|||
this.count = [text, fn(hour), fn(min), fn(s)] |
|||
} |
|||
}, |
|||
beforeDestroy() { |
|||
clearInterval(this.timer) |
|||
} |
|||
} |
@ -0,0 +1,247 @@ |
|||
<template> |
|||
<div class="discount"> |
|||
<div class="discount-top"> |
|||
<div class="discount-top-text">全场5折起</div> |
|||
<div class="discount-top-time"> |
|||
<!-- 距{{count[0]}}--> |
|||
距离本场结束还有 |
|||
<div class="time"><span>{{count[1]}}</span>:<span>{{count[2]}}</span>:<span>{{count[3]}}</span></div></div> |
|||
</div> |
|||
<div class="discount-more" :style="{backgroundImage: 'url('+ componentContent.moreBg +')'}"> |
|||
<div class="discount-more-overlay"> |
|||
<button class="btn-more" @click="jumpDiscount(productData)">查看全部</button> |
|||
</div> |
|||
</div> |
|||
<div class="discount-list"> |
|||
<div class="swiper-button-prev"></div> |
|||
<div class="swiper-button-next"></div> |
|||
<swiper class="products-swiper" :options="swiperOption"> |
|||
<swiper-slide class="products-swiper-slide item" v-for="(item,index) in productData.products" :key="index"> |
|||
<div class="a-link" @click="jumpProductDetail(item)"> |
|||
<div class="itemImgBox"> |
|||
<div class="imgBox"> |
|||
<el-image |
|||
:src="item.image" |
|||
fit="contain"></el-image> |
|||
</div> |
|||
</div> |
|||
<div class="text"> |
|||
<h4 class="h4">{{item.productName}}</h4> |
|||
<div class="priceBox"> |
|||
<span class="discount" v-if="item.originalPrice">¥{{item.originalPrice}}</span> |
|||
<dl> |
|||
<dt><img src="../../../static/images/discount/flag-discount.png" alt="折扣价"></dt> |
|||
<dd> |
|||
¥{{item.price}} |
|||
</dd> |
|||
</dl> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</swiper-slide> |
|||
</swiper> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {commonMixin} from '../mixin' |
|||
export default { |
|||
mixins: [commonMixin], |
|||
data () { |
|||
return { |
|||
swiperOption: { |
|||
slidesPerView: 3, // 显示数量 |
|||
spaceBetween: 13, // 间隔 |
|||
autoplay: false, // 可选选项,自动滑动 |
|||
loop: true, |
|||
pagination: { |
|||
el: '.discount-pagination' |
|||
}, |
|||
navigation: { |
|||
nextEl: '.swiper-button-next', |
|||
prevEl: '.swiper-button-prev' |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.discount{ |
|||
width: 1200px; |
|||
max-width: 100%; |
|||
margin: 0 auto; |
|||
overflow: hidden; |
|||
&-top{ |
|||
height: 250px; |
|||
padding-top: 96px; |
|||
margin-bottom: 15px; |
|||
background: url("../../../static/images/discount/bg-discount-top.png") no-repeat; |
|||
&-text{ |
|||
background: url("../../../static/images/discount/bg-discount-top-text.png") no-repeat; |
|||
width: 176px; |
|||
height: 83px; |
|||
padding-top: 13px; |
|||
line-height: 50px; |
|||
font-size: 25px; |
|||
color: #fff; |
|||
margin: 0px auto 18px; |
|||
text-align: center; |
|||
} |
|||
&-time{ |
|||
margin: 0 auto; |
|||
text-align: center; |
|||
font-size: 16px; |
|||
color: #FFEBC4; |
|||
.time{ |
|||
font-size: 20px; |
|||
color: #999; |
|||
display: inline-block; |
|||
span{ |
|||
display: inline-block; |
|||
line-height: 40px; |
|||
padding: 0 9px; |
|||
margin: 0 5px; |
|||
background-color: #343434; |
|||
color: #fff; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
&-list{ |
|||
margin-right: 303px; |
|||
position: relative; |
|||
.swiper-button-prev,.swiper-button-next{ |
|||
width: 95px; |
|||
height: 95px; |
|||
position: absolute; |
|||
cursor:pointer; |
|||
top: 115px; |
|||
background-repeat: no-repeat; |
|||
&:after{ |
|||
content: ''; |
|||
} |
|||
} |
|||
.swiper-button-prev{ |
|||
left: -22px; |
|||
background: url('../../../static/images/btn-prev2.png'); |
|||
} |
|||
.swiper-button-next{ |
|||
right: -22px; |
|||
background: url('../../../static/images/btn-next2.png'); |
|||
} |
|||
.a-link{ |
|||
cursor: pointer; |
|||
&:hover{ |
|||
box-shadow: 3px 4px 20px 0px rgba(186, 186, 186, 0.5); |
|||
} |
|||
.itemImgBox { |
|||
height: auto; |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: center; |
|||
.imgBox { |
|||
padding-bottom: 100%; |
|||
background-color: #cacaca; |
|||
position: relative; |
|||
.el-image { |
|||
width: 100%; |
|||
height: 100%; |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
} |
|||
} |
|||
} |
|||
.text{ |
|||
padding:25px 20px 17px; |
|||
text-align: center; |
|||
//height: 180px; |
|||
.h4{ |
|||
font-size: 18px; |
|||
line-height: 24px; |
|||
overflow: hidden; |
|||
text-overflow:ellipsis; |
|||
white-space: nowrap; |
|||
color: #333333; |
|||
//max-height: 48px; |
|||
} |
|||
.p{ |
|||
color: #999; |
|||
font-size: 16px; |
|||
overflow: hidden; |
|||
text-overflow:ellipsis; |
|||
white-space: nowrap; |
|||
padding-top: 18px; |
|||
position: relative; |
|||
margin-top: 8px; |
|||
&:after{ |
|||
position: absolute; |
|||
top: 0; |
|||
left: 50%; |
|||
margin-left: -80px; |
|||
width: 160px; |
|||
height: 2px; |
|||
background: #F0F0F0; |
|||
content: ''; |
|||
} |
|||
} |
|||
.priceBox { |
|||
dl { |
|||
display: inline-block; |
|||
min-width: 130px; |
|||
dt{ |
|||
float: left; |
|||
img{ |
|||
display: block; |
|||
} |
|||
} |
|||
dd{ |
|||
border: 1px solid #F3F4F5; |
|||
font-size: 25px; |
|||
line-height: 34px; |
|||
color: #C83732; |
|||
margin-left: 57px; |
|||
padding: 0 10px; |
|||
} |
|||
} |
|||
span.discount { |
|||
display: block; |
|||
font-size: 18px; |
|||
line-height: 24px; |
|||
padding: 15px 0 11px; |
|||
color: #ccc; |
|||
text-decoration: line-through; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
&-more{ |
|||
width: 290px; |
|||
height: 466px; |
|||
float: right; |
|||
position: relative; |
|||
&-overlay{ |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
background-color: rgba(0,0,0,0.6); |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
.btn-more{ |
|||
width: 130px; |
|||
height: 41px; |
|||
background-color: #fff; |
|||
font-size: 18px; |
|||
color: #C5AA7B; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,213 @@ |
|||
<template> |
|||
<div class="group-list" v-if="productData.products&&productData.products.length>0"> |
|||
<div class="group-warp"> |
|||
<div class="title"> |
|||
<label> |
|||
<!-- #ifdef MP-WEIXIN --> |
|||
<img class="title-img" src="../../../static/images/group/img-title.png" alt="拼团专区" mode="widthFix"/> |
|||
<!-- #endif --> |
|||
<!-- #ifdef H5 || APP-PLUS --> |
|||
<image class="title-img" src="../../../static/images/group/img-title.png" alt="拼团专区" mode="widthFix"/> |
|||
<!-- #endif --> |
|||
</label> |
|||
<a v-show="componentContent.showMore" class="btn-all a-link" @click="jumpGroupWorks(productData)">更多<i class="iconfont icon-arrow-right"></i></a> |
|||
</div> |
|||
<div> |
|||
<swiper class="swiper pro-box" :circular="true" :indicator-dots="false" :autoplay="true" :display-multiple-items="3" @change="swiperChange"> |
|||
<swiper-item class="swiper-slide pro-item-warp" v-for="(item,index) in productData.products" :key="index" @click="jumpProductDetail(item)"> |
|||
<div class="pro-item-inner"> |
|||
<div class="pro-item"> |
|||
<div class="pro-item-img"> |
|||
<img class="img default-img" :src="item.image"> |
|||
</div> |
|||
<div class="pro-item-info"> |
|||
<label class="name">{{item.productName}}</label> |
|||
<div class="price"> |
|||
<label class="unit">¥ </label> |
|||
<label class="val"> {{item.price}}</label> |
|||
</div> |
|||
<label class="buyCount">{{item.workUsers?item.workUsers:0}}人已拼</label> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</swiper-item> |
|||
<!-- #ifdef MP-WEIXIN --> |
|||
<swiper-item v-if="productData.products.length" class="swiper-slide pro-item-warp" v-for="item in (3 - productData.products.length)"> |
|||
</swiper-item> |
|||
<!-- #endif --> |
|||
</swiper> |
|||
<view class="swiper-dots" v-if="productData.products && productData.products.length > 3"> |
|||
<text class="dot" :class="index - swiperCurrent <= 2 && index - swiperCurrent >=0 && 'dot-active'" v-for="(dot, index) in productData.products.length" |
|||
:key="index"></text> |
|||
</view> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {commonMixin} from '../mixin' |
|||
export default { |
|||
mixins: [commonMixin], |
|||
data () { |
|||
return { |
|||
swiperCurrent: 0, |
|||
} |
|||
}, |
|||
methods:{ |
|||
swiperChange(e) { |
|||
this.swiperCurrent = e.detail.current; |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.group-list{ |
|||
padding: 30upx 20upx 60upx; |
|||
.group-warp{ |
|||
width: 710upx; |
|||
height: 528upx; |
|||
padding: 0 2upx; |
|||
background: #333333; |
|||
box-shadow: 0px 20upx 30upx rgba(0, 0, 0, 0.3); |
|||
opacity: 1; |
|||
border-radius: 20upx; |
|||
position: relative; |
|||
} |
|||
.title{ |
|||
display: flex; |
|||
align-items:center; |
|||
position: relative; |
|||
padding: 40upx 0 25upx 20upx; |
|||
.title-img{ |
|||
width: 189upx; |
|||
height: 34rpx; |
|||
} |
|||
.btn-all{ |
|||
position: absolute; |
|||
right: 8upx; |
|||
top: 40upx; |
|||
line-height: 33upx; |
|||
padding-right: 25upx; |
|||
font-size: 24upx; |
|||
color: #FFEBC4; |
|||
.iconfont{ |
|||
content: ''; |
|||
font-size: 26upx; |
|||
position: absolute; |
|||
right: 0; |
|||
top: 0; |
|||
} |
|||
} |
|||
} |
|||
.pro-box{ |
|||
height: 390upx; |
|||
display: flex; |
|||
&.swiper-disabled{ |
|||
.uni-swiper-wrapper{ |
|||
position: static; |
|||
} |
|||
} |
|||
.pro-item-warp{ |
|||
width: 236px; |
|||
} |
|||
.pro-item{ |
|||
width: 220upx; |
|||
height: 382upx; |
|||
background: #FFFFFF; |
|||
.pro-item-img{ |
|||
.img{ |
|||
width: 100%; |
|||
height: 220upx; |
|||
} |
|||
} |
|||
&-inner{ |
|||
padding: 0 8upx; |
|||
} |
|||
.pro-item-info{ |
|||
text-align: center; |
|||
padding: 0px 10upx 20upx; |
|||
.name{ |
|||
font-size: 24upx; |
|||
font-weight: normal; |
|||
color: #FFEBC4; |
|||
line-height: 50upx; |
|||
background-color: #333333; |
|||
text-align: center; |
|||
margin-bottom: 18upx; |
|||
padding: 0 5px; |
|||
display: block; |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
white-space: nowrap; |
|||
} |
|||
.price{ |
|||
color: #C83732; |
|||
font-size: 28upx; |
|||
font-weight: bold; |
|||
line-height: 40upx; |
|||
} |
|||
.buyCount{ |
|||
font-size: 24upx; |
|||
color: #ccc; |
|||
line-height: 34upx; |
|||
font-weight: normal; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
::v-deep .uni-swiper-dots{ |
|||
display: flex; |
|||
justify-content: center; |
|||
bottom: 27px; |
|||
.uni-swiper-dot{ |
|||
width: 24upx; |
|||
height: 4upx; |
|||
background: #fff; |
|||
opacity: 0.5; |
|||
border-radius: 2upx; |
|||
margin: 0 5upx; |
|||
&-active{ |
|||
opacity: 1; |
|||
} |
|||
} |
|||
} |
|||
|
|||
//.pagination{ |
|||
// display: flex; |
|||
// justify-content: center; |
|||
// ::v-deep .swiper-pagination-bullet{ |
|||
// width: 24upx; |
|||
// height: 4upx; |
|||
// background: #fff; |
|||
// opacity: 0.5; |
|||
// border-radius: 2upx; |
|||
// margin: 0 5upx; |
|||
// } |
|||
// ::v-deep .swiper-pagination-bullet-active{ |
|||
// opacity: 1; |
|||
// } |
|||
//} |
|||
.swiper-dots { |
|||
display: flex; |
|||
position: absolute; |
|||
left: 50%; |
|||
transform: translateX(-50%); |
|||
bottom: 15rpx; |
|||
z-index: 66; |
|||
.dot { |
|||
width: 24upx; |
|||
height: 4upx; |
|||
background: #fff; |
|||
opacity: 0.5; |
|||
border-radius: 2upx; |
|||
margin: 0 10upx; |
|||
} |
|||
|
|||
.dot-active { |
|||
opacity: 1; |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,86 @@ |
|||
// import { directive, Swiper, SwiperSlide } from 'vue-awesome-swiper'
|
|||
// import 'swiper/css/swiper.css'
|
|||
import api from '../../config/api' |
|||
import {funMixin} from '../../config/mixin' |
|||
|
|||
export const commonMixin = { |
|||
name: 'productList', |
|||
mixins: [funMixin], |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
typeId: { |
|||
type: Number, |
|||
default: 1 |
|||
}, |
|||
shopId: { |
|||
type: Number, |
|||
default: 0 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
}, |
|||
// components: {
|
|||
// Swiper,
|
|||
// SwiperSlide
|
|||
// },
|
|||
// directives: {
|
|||
// swiper: directive
|
|||
// },
|
|||
data () { |
|||
return { |
|||
productData: { |
|||
products: [] |
|||
} |
|||
} |
|||
}, |
|||
watch: { |
|||
'componentContent': { |
|||
handler(newVal, oldVal) { |
|||
this.getData() |
|||
}, |
|||
deep: true |
|||
} |
|||
}, |
|||
created() { |
|||
this.getData() |
|||
}, |
|||
methods: { |
|||
getData() { |
|||
const _ = this |
|||
let _url = '' |
|||
if(_.typeId === 1){ |
|||
const params = { |
|||
method: 'GET', |
|||
url: `${api.getAdminGroupWorks}`, |
|||
} |
|||
this.sendReq(params, (res) => { |
|||
_.productData.products = res.data |
|||
if (_.productData.products.length > 2) { |
|||
_.productData.show = true |
|||
} else { |
|||
_.productData.show = false |
|||
} |
|||
}) |
|||
} else if(_.typeId === 3) { |
|||
if(_.componentContent.shopGroupWorkId){ |
|||
const params = { |
|||
method: 'GET', |
|||
url: `${api.getGroupWorks}?shopId=${_.shopId}&ids=${_.componentContent.shopGroupWorkId}`, |
|||
} |
|||
this.sendReq(params, (res) => { |
|||
_.productData = res.data[0] |
|||
}) |
|||
} else { |
|||
_.productData = { |
|||
products:[] |
|||
} |
|||
} |
|||
} |
|||
|
|||
}, |
|||
} |
|||
} |
@ -0,0 +1,250 @@ |
|||
<template> |
|||
<div class="product-list" :class="'terminal'+terminal"> |
|||
<div class="picListWarp" v-if="componentContent.arrangeType == '横向滑动'"> |
|||
<div class="picList" v-if="productData.products && productData.products.length>0"> |
|||
<div class="swiper-button-prev"></div> |
|||
<div class="swiper-button-next"></div> |
|||
<swiper class="products-swiper" :options="swiperOption"> |
|||
<swiper-slide class="products-swiper-slide item" v-for="(item,index) in productData.products" :key="index"> |
|||
<div class="a-link" @click="jumpProductDetail(item)"> |
|||
<div class="itemImgBox"> |
|||
<div class="imgBox"> |
|||
<el-image |
|||
:src="item.image" |
|||
fit="contain"></el-image> |
|||
</div> |
|||
</div> |
|||
<div class="text"> |
|||
<h4 class="h4">{{item.productName}}</h4> |
|||
<div class="priceBox"> |
|||
<span class="discount" v-if="item.originalPrice">¥{{item.originalPrice}}</span> |
|||
<dl> |
|||
<dt><img src="../../../static/images/group/flag-group.png" alt="拼团价"></dt> |
|||
<dd> |
|||
¥{{item.price}} |
|||
</dd> |
|||
</dl> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</swiper-slide> |
|||
</swiper> |
|||
</div> |
|||
</div> |
|||
<div v-else class="picList" > |
|||
<ul class="clearfix" :class="'imgTextNum' + componentContent.productNum" v-if="productData.products && productData.products.length>0"> |
|||
<li class="item" v-for="(item,index) in productData.products.slice(0, componentContent.productRowNum * componentContent.productNum)" :key="index"> |
|||
<div class="a-link" @click="jumpProductDetail(item)"> |
|||
<div class="itemImgBox"> |
|||
<div class="imgBox"> |
|||
<el-image |
|||
:src="item.image" |
|||
fit="contain"></el-image> |
|||
</div> |
|||
</div> |
|||
<div class="text"> |
|||
<h4 class="h4">{{item.productName}}</h4> |
|||
<div class="priceBox"> |
|||
<span class="discount" v-if="item.originalPrice">¥{{item.originalPrice}}</span> |
|||
<dl> |
|||
<dt><img src="../../../static/images/group/flag-group.png" alt="拼团价"></dt> |
|||
<dd> |
|||
¥{{item.price}} |
|||
</dd> |
|||
</dl> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</li> |
|||
</ul> |
|||
</div> |
|||
<button v-show="componentContent.showMore" class="btn-more" @click="jumpGroupWorks(productData)">查看全部 <span class="icon iconfont icon-arrow-right"></span></button> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {commonMixin} from '../mixin' |
|||
export default { |
|||
mixins: [commonMixin], |
|||
data () { |
|||
return { |
|||
swiperOption: { |
|||
slidesPerView: 4, // 显示数量 |
|||
spaceBetween: 13, // 间隔 |
|||
autoplay: false, // 可选选项,自动滑动 |
|||
loop: true, |
|||
pagination: { |
|||
el: '.group-pagination' |
|||
}, |
|||
navigation: { |
|||
nextEl: '.swiper-button-next', |
|||
prevEl: '.swiper-button-prev' |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.product-list{ |
|||
padding: 20px 0; |
|||
background-color: #fff; |
|||
.picListWarp{ |
|||
width: 1380px; |
|||
max-width: 100%; |
|||
margin: 0 auto; |
|||
position: relative; |
|||
} |
|||
.picList{ |
|||
width: 1200px; |
|||
max-width: 100%; |
|||
margin: 0 auto; |
|||
.swiper-button-prev,.swiper-button-next{ |
|||
width: 50px; |
|||
height: 50px; |
|||
position: absolute; |
|||
cursor:pointer; |
|||
top: 140px; |
|||
background-repeat: no-repeat; |
|||
&:after{ |
|||
content: ''; |
|||
} |
|||
} |
|||
.swiper-button-prev{ |
|||
left: 0; |
|||
background: url('../../../static/images/btn-prev.png'); |
|||
} |
|||
.swiper-button-next{ |
|||
right: 0; |
|||
background: url('../../../static/images/btn-next.png'); |
|||
} |
|||
.a-link{ |
|||
cursor: pointer; |
|||
&:hover{ |
|||
box-shadow: 3px 4px 20px 0px rgba(186, 186, 186, 0.5); |
|||
} |
|||
.itemImgBox { |
|||
height: auto; |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: center; |
|||
.imgBox { |
|||
padding-bottom: 100%; |
|||
background-color: #cacaca; |
|||
position: relative; |
|||
.el-image { |
|||
width: 100%; |
|||
height: 100%; |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
} |
|||
} |
|||
} |
|||
.text{ |
|||
padding:25px 20px 17px; |
|||
text-align: center; |
|||
//height: 180px; |
|||
.h4{ |
|||
font-size: 18px; |
|||
line-height: 24px; |
|||
overflow: hidden; |
|||
text-overflow:ellipsis; |
|||
white-space: nowrap; |
|||
color: #333333; |
|||
//max-height: 48px; |
|||
} |
|||
.p{ |
|||
color: #999; |
|||
font-size: 16px; |
|||
overflow: hidden; |
|||
text-overflow:ellipsis; |
|||
white-space: nowrap; |
|||
padding-top: 18px; |
|||
position: relative; |
|||
margin-top: 8px; |
|||
&:after{ |
|||
position: absolute; |
|||
top: 0; |
|||
left: 50%; |
|||
margin-left: -80px; |
|||
width: 160px; |
|||
height: 2px; |
|||
background: #F0F0F0; |
|||
content: ''; |
|||
} |
|||
} |
|||
.priceBox { |
|||
dl { |
|||
display: inline-block; |
|||
min-width: 130px; |
|||
dt{ |
|||
float: left; |
|||
img{ |
|||
display: block; |
|||
} |
|||
} |
|||
dd{ |
|||
border: 1px solid #F3F4F5; |
|||
font-size: 25px; |
|||
line-height: 34px; |
|||
color: #C83732; |
|||
margin-left: 57px; |
|||
padding: 0 10px; |
|||
} |
|||
} |
|||
span.discount { |
|||
display: block; |
|||
font-size: 18px; |
|||
line-height: 24px; |
|||
padding: 15px 0 11px; |
|||
color: #ccc; |
|||
text-decoration: line-through; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
ul{ |
|||
margin: -15px 0 0 -15px; |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
li{ |
|||
flex: 0 0 50%; |
|||
padding: 15px 0 0 15px; |
|||
width: 0; |
|||
} |
|||
} |
|||
.imgTextNum2 { |
|||
li { |
|||
flex: 0 0 50%; |
|||
} |
|||
} |
|||
.imgTextNum3 { |
|||
li { |
|||
flex: 0 0 33.33%; |
|||
} |
|||
} |
|||
.imgTextNum4 { |
|||
li { |
|||
flex: 0 0 25%; |
|||
} |
|||
} |
|||
.imgTextNum5 { |
|||
li { |
|||
flex: 0 0 20%; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.btn-more { |
|||
width: 130px; |
|||
height: 41px; |
|||
border: 2px solid #C5AA7B; |
|||
color: #C5AA7B; |
|||
font-size: 18px; |
|||
background-color: transparent; |
|||
margin: 20px auto 0; |
|||
display: block; |
|||
} |
|||
</style> |
@ -0,0 +1,118 @@ |
|||
<template> |
|||
<view class="header"> |
|||
<view class="top-box"> |
|||
<image v-if="componentContent.logoType === 1" class="logo" |
|||
:src="componentContent.imageUrl" |
|||
mode="heightFix"></image> |
|||
<view v-else class="h3" :style="{fontSize:componentContent.fontSizeNum+'px',fontWeight:componentContent.textFontW,color:componentContent.titColor}">{{componentContent.title}}</view> |
|||
<view class="search-btn" @click="searchPro"> |
|||
<image class="search-icon" |
|||
src="https://ceres.zkthink.com/static/img/search.png" |
|||
mode="widthFix"></image> |
|||
</view> |
|||
</view> |
|||
<view class="tabs-nav-warp"> |
|||
<scroll-view class="tabs-nav" scroll-x="true"> |
|||
<view class="ul"> |
|||
<view class="li" :class="{'on':activeTab===0}" @click="tabChange(0)">首页</view> |
|||
<view class="li" :class="{'on':activeTab===index+1}" v-for="(item,index) in classifyData" :key="index" @click="tabChange(index+1,item.id)"> |
|||
{{item.categoryName}} |
|||
</view> |
|||
</view> |
|||
</scroll-view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import {commonMixin} from '../mixin' |
|||
export default { |
|||
mixins: [commonMixin], |
|||
data () { |
|||
return { |
|||
activeTab: 0 |
|||
} |
|||
}, |
|||
computed: { |
|||
|
|||
}, |
|||
methods:{ |
|||
tabChange (index, id) { |
|||
this.activeTab = index |
|||
this.$emit('tabChange', index, id) |
|||
}, |
|||
searchPro(key, type) { |
|||
uni.navigateTo({ |
|||
url: `/pages_category_page1/search/index/index` |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.header { |
|||
.top-box { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding-left: 30upx; |
|||
width: 100%; |
|||
.logo { |
|||
// width: 280upx; |
|||
height: 70upx; |
|||
margin-top: 0upx; |
|||
} |
|||
|
|||
.search-btn { |
|||
height: 66upx; |
|||
background: rgba(255, 255, 255, 1); |
|||
border-radius: 33upx; |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
margin-right: 30upx; |
|||
.search-icon { |
|||
width: 60upx; |
|||
height: 60upx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.tabs-nav-warp{ |
|||
margin-top: 20upx; |
|||
padding:0 30upx; |
|||
overflow: hidden; |
|||
.tabs-nav{ |
|||
.ul{ |
|||
display: flex; |
|||
flex-wrap: nowrap; |
|||
justify-content: space-between; |
|||
.li{ |
|||
flex: 1 0 auto; |
|||
margin-left: 36upx; |
|||
font-size: 30upx; |
|||
color: #999999; |
|||
position: relative; |
|||
padding-bottom: 18upx; |
|||
text-align: center; |
|||
&:first-child{ |
|||
margin-left: 0; |
|||
} |
|||
&.on{ |
|||
&:after{ |
|||
content: ''; |
|||
width: 100%; |
|||
height: 4upx; |
|||
background: #C5AA7B; |
|||
position: absolute; |
|||
left: 0; |
|||
bottom: 0; |
|||
} |
|||
font-weight:bold; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,45 @@ |
|||
import api from '../../config/api' |
|||
import {funMixin} from '../../config/mixin' |
|||
|
|||
export const commonMixin = { |
|||
name: 'headerComponent', |
|||
mixins: [funMixin], |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
typeId: { |
|||
type: Number, |
|||
default: 1 |
|||
}, |
|||
shopId: { |
|||
type: Number, |
|||
default: 0 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
}, |
|||
data () { |
|||
return { |
|||
classifyData: [] |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.getData() |
|||
}, |
|||
methods: { |
|||
getData() { |
|||
const _ = this |
|||
_.sendReq({ |
|||
url: `${api.getClassify}?page=1&pageSize=20`, |
|||
method: 'GET' |
|||
}, (res) => { |
|||
_.classifyData = res.data |
|||
console.log(_.classifyData) |
|||
},(err)=>{ |
|||
}) |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,119 @@ |
|||
<template> |
|||
<div class="imageText warp" :class="['terminal'+terminal,'pos-' + componentContent.positionValue]"> |
|||
<div class="img img-left"> |
|||
<a class="item a-link" @click="jumpLink(componentContent.linkObj)"><img :src="componentContent.imageUrl" alt=""></a> |
|||
</div> |
|||
<div class="text"> |
|||
<h3 class="h3">{{componentContent.title}}</h3> |
|||
<div v-html="componentContent.content"></div> |
|||
</div> |
|||
<div class="img img-right"> |
|||
<a class="item a-link" @click="jumpLink(componentContent.linkObj)"><img :src="componentContent.imageUrl" alt=""></a> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {funMixin} from '../config/mixin' |
|||
export default { |
|||
name: 'imageTextComponent', |
|||
mixins: [funMixin], |
|||
data () { |
|||
return { |
|||
} |
|||
}, |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.imageText{ |
|||
width: 710upx; |
|||
margin: 0 auto; |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
padding: 20upx 0; |
|||
.img{ |
|||
width: 50%; |
|||
padding-bottom: 30%; |
|||
background-color: #cacaca; |
|||
position: relative; |
|||
img{ |
|||
max-width: 100%; |
|||
height: 100%; |
|||
max-height: 100%; |
|||
position: absolute; |
|||
margin: auto; |
|||
top: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
left: 0; |
|||
} |
|||
} |
|||
.text{ |
|||
width: 40%; |
|||
.h3{ |
|||
font-size: 30upx; |
|||
margin-bottom: 24upx; |
|||
} |
|||
.p{ |
|||
font-size: 16upx; |
|||
} |
|||
} |
|||
&.pos-top{ |
|||
display: block; |
|||
text-align: center; |
|||
.img{ |
|||
width: 100%; |
|||
} |
|||
.text{ |
|||
width: 100%; |
|||
margin-top: 30upx; |
|||
} |
|||
.img-right{ |
|||
display: none; |
|||
} |
|||
} |
|||
&.pos-bottom{ |
|||
display: block; |
|||
text-align: center; |
|||
.img{ |
|||
width: 100%; |
|||
} |
|||
.text{ |
|||
width: 100%; |
|||
margin-bottom: 30upx; |
|||
} |
|||
.img-left{ |
|||
display: none; |
|||
} |
|||
} |
|||
&.pos-left{ |
|||
.img-right{ |
|||
display: none; |
|||
} |
|||
} |
|||
&.pos-right{ |
|||
.text{ |
|||
padding-left: 20upx; |
|||
} |
|||
.img-left{ |
|||
display: none; |
|||
} |
|||
} |
|||
|
|||
} |
|||
.terminal1,.terminal2,.terminal3{ |
|||
width: 710upx; |
|||
margin: 0 auto; |
|||
} |
|||
</style> |
@ -0,0 +1,136 @@ |
|||
<template> |
|||
<div class="hom-pro-list warp" :class="'terminal'+terminal"> |
|||
<div class="title"> |
|||
<h2 class="h2" :style="{textAlign:componentContent.textAlign}">{{componentContent.title}}</h2> |
|||
</div> |
|||
<div class="ul clearfix" :class="{imgTextNum4: componentContent.imgTextData.length === 4, imgTextNum5: componentContent.imgTextData.length === 5, imgTextStyle: componentContent.imgTextData.length >= 6 || componentContent.imgTextData.length === 3}"> |
|||
<div class="li" v-for="(item,index) in componentContent.imgTextData" :key="index"> |
|||
<a class="item a-link" @click="jumpLink(item.linkObj)"> |
|||
<div class="itemImgBox" v-show="item.isShow"> |
|||
<div class="imgBox"> |
|||
<img ref="getHeight" :src="item.imgData" v-show="item.imgData" :alt="item.title"> |
|||
</div> |
|||
</div> |
|||
<div class="text"> |
|||
<h4 class="h4">{{item.title}}</h4> |
|||
<p class="p">{{item.describe}}</p> |
|||
</div> |
|||
</a> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {funMixin} from '../config/mixin' |
|||
export default { |
|||
name: 'imageTextList', |
|||
mixins: [funMixin], |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.hom-pro-list{ |
|||
min-height: 450upx; |
|||
padding: 20upx 0; |
|||
.title{ |
|||
margin-bottom: 23upx; |
|||
position: relative; |
|||
.h2{ |
|||
font-size: 22upx; |
|||
color: #333; |
|||
line-height: 1em; |
|||
font-weight: bold; |
|||
} |
|||
} |
|||
.ul{ |
|||
margin: -15upx 0 0 -15upx; |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
.li{ |
|||
flex: 0 0 50%; |
|||
padding: 15upx 0 0 15upx; |
|||
box-sizing: border-box; |
|||
.item{ |
|||
.itemImgBox { |
|||
height: auto; |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: center; |
|||
.imgBox { |
|||
padding-bottom: 80%; |
|||
background-color: #cacaca; |
|||
position: relative; |
|||
img { |
|||
max-width: 100%; |
|||
height: 100%; |
|||
max-height: 100%; |
|||
position: absolute; |
|||
margin: auto; |
|||
top: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
left: 0; |
|||
} |
|||
} |
|||
} |
|||
.text{ |
|||
padding:16upx 20upx; |
|||
text-align: center; |
|||
.h4{ |
|||
line-height: 25upx; |
|||
overflow: hidden; |
|||
color: #333333; |
|||
} |
|||
.p{ |
|||
color: #666666; |
|||
padding: 5upx 0 10upx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.imgTextNum4 { |
|||
.li { |
|||
flex: 0 0 50%; |
|||
} |
|||
} |
|||
.imgTextNum5 { |
|||
.li { |
|||
flex: 0 0 33.33%; |
|||
} |
|||
.li:nth-child(1) { |
|||
flex: 0 0 50%; |
|||
} |
|||
.li:nth-child(2) { |
|||
flex: 0 0 50%; |
|||
} |
|||
} |
|||
.imgTextStyle { |
|||
.li { |
|||
flex: 0 0 33.33%; |
|||
} |
|||
} |
|||
} |
|||
@media screen and (max-width: 768px) { |
|||
.hom-pro-list .ul .li{ |
|||
flex: 0 0 50%; |
|||
} |
|||
} |
|||
.terminal1,.terminal2,.terminal3{ |
|||
width: 710upx; |
|||
margin: 0 auto; |
|||
&.hom-pro-list .ul .li{ |
|||
flex: 0 0 50%; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,101 @@ |
|||
<template> |
|||
<div class="ul image-text-nav" :class="'terminal' + terminal"> |
|||
<div class="li" v-for="(item,index) in componentContent.imgTextData" :key="index" :style="{'flex':'0 0 '+ getItemValue() + '%'}" @click="jumpLink(item.linkObj)"> |
|||
<!--<router-link class="item" :to="jumpLink(item.linkObj)">--> |
|||
<div class="img-box"> |
|||
<div class="img-box-inner"> |
|||
<div class="imgBox"> |
|||
<img class="img" :src="item.img"/> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<h4 class="h4">{{item.title}}</h4> |
|||
<!--</router-link>--> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {funMixin} from '../config/mixin' |
|||
export default { |
|||
name: 'imageTextNav', |
|||
mixins: [funMixin], |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
}, |
|||
methods: { |
|||
// 计算生成格子百分比 |
|||
getItemValue (val) { |
|||
const len = parseInt(this.componentContent.imgTextData.length) |
|||
if (len === 0) { |
|||
return 0 |
|||
} else { |
|||
return (1 / len * 10000 / 100.00) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.image-text-nav{ |
|||
min-height: 100upx; |
|||
width: 710upx; |
|||
margin: 0 auto; |
|||
display: flex; |
|||
padding: 20upx 0; |
|||
.li{ |
|||
text-align: center; |
|||
.img-box{ |
|||
.imgBox{ |
|||
width: 100upx; |
|||
height: 100upx; |
|||
display: inline-block; |
|||
.img{ |
|||
width: 100%; |
|||
height: 100%; |
|||
object-fit: cover; |
|||
} |
|||
} |
|||
} |
|||
.h4{ |
|||
font-size: 26upx; |
|||
color: #333; |
|||
line-height: 33upx; |
|||
} |
|||
} |
|||
&.terminal4{ |
|||
width: 1000upx; |
|||
.li{ |
|||
.img-box{ |
|||
display: inline-block; |
|||
width: 100upx; |
|||
height: 100upx; |
|||
box-shadow: 0 10upx 30upx rgba(51, 51, 51, 0.15); |
|||
&-inner{ |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
height: 100%; |
|||
} |
|||
.imgBox{ |
|||
width: 60upx; |
|||
height: 60upx; |
|||
} |
|||
} |
|||
.h4{ |
|||
font-size: 18upx; |
|||
color: #ccc; |
|||
line-height: 1em; |
|||
padding-top: 20upx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,71 @@ |
|||
<template> |
|||
<div class="live-list-page" v-if="roomList && roomList.length > 0"> |
|||
<div class="title"> |
|||
<!-- #ifdef MP-WEIXIN --> |
|||
<img class="title-img" src="../../../static/images/live/img-title.png" alt="直播" mode="widthFix"/> |
|||
<!-- #endif --> |
|||
<!-- #ifdef H5 || APP-PLUS --> |
|||
<image class="title-img" src="../../../static/images/live/img-title.png" alt="直播" mode="widthFix"/> |
|||
<!-- #endif --> |
|||
</div> |
|||
<div class="live-list"> |
|||
<LiveBox class="live-item" |
|||
v-for="item in roomList" |
|||
:key="item.roomid" |
|||
:liveData.sync="item" |
|||
@click="toLiveRoom(item)" |
|||
/> |
|||
</div> |
|||
<button v-show="componentContent.showMore" class="btn-more" @click="jumpLive()">查看全部 <span class="icon iconfont icon-arrow-right"></span></button> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
// const NET = require('../../../../../utils/request') |
|||
// const API = require('../../../../../config/api') |
|||
import {commonMixin} from '../mixin' |
|||
import LiveBox from './item.vue' |
|||
export default { |
|||
mixins: [commonMixin], |
|||
components: { |
|||
LiveBox |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.live-list-page{ |
|||
.title{ |
|||
text-align: center; |
|||
margin-bottom: 20rpx; |
|||
.title-img{ |
|||
width: 211rpx; |
|||
height: 32rpx; |
|||
} |
|||
} |
|||
.live-list{ |
|||
padding-left: 20rpx; |
|||
width: 100%; |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
.live-item{ |
|||
margin:0 14rpx 14rpx 0; |
|||
width: 348rpx; |
|||
height: 464rpx; |
|||
border-radius: 8rpx; |
|||
overflow: hidden; |
|||
} |
|||
} |
|||
.btn-more { |
|||
width: 170rpx; |
|||
height: 54rpx; |
|||
border: 2rpx solid #C5AA7B; |
|||
color: #C5AA7B; |
|||
font-size: 24rpx; |
|||
background-color: transparent; |
|||
margin: 20rpx auto 0; |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,461 @@ |
|||
<template> |
|||
<view class="live-box"> |
|||
<view class="live-ongoing" v-if="liveData.liveStatus === 101" @click="toLive"> |
|||
<image class="cover-img" :src="liveData.feedsImg" /> |
|||
<view class="status"> |
|||
<view class="status-state"> |
|||
<!-- #ifdef MP-WEIXIN --> |
|||
<img class="img" src="../../../static/images/live/icon-live-num.png" mode="widthFix"/> |
|||
<!-- #endif --> |
|||
<!-- #ifdef H5 || APP-PLUS --> |
|||
<image class="img" src="../../../static/images/live/icon-live-num.png" mode="widthFix"/> |
|||
<!-- #endif --> |
|||
直播中 |
|||
</view> |
|||
<!-- <view class="status-num">1000人</view> --> |
|||
</view> |
|||
<view class="user"> |
|||
<view class="user-pic"> |
|||
<image class="img" :src="liveData.anchorHeadImg" /> |
|||
</view> |
|||
<view class="user-name">{{ liveData.anchorNickName }}</view> |
|||
</view> |
|||
<view class="products"> |
|||
<view class="uni-padding-wrap"> |
|||
<view class="page-section swiper"> |
|||
<view class="page-section-spacing"> |
|||
<swiper class="swiper" |
|||
:indicator-dots="indicatorDots" |
|||
:autoplay="autoplay" |
|||
:interval="interval" |
|||
:duration="duration" |
|||
:vertical="true" |
|||
> |
|||
<swiper-item |
|||
v-for="item in liveData.goods" |
|||
:key="item.goods_id" |
|||
> |
|||
<view class="swiper-item">{{ item.name }}</view> |
|||
</swiper-item> |
|||
</swiper> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="live-other" v-else @click="toLive"> |
|||
<image class="cover-img" :src="liveData.feedsImg" /> |
|||
<div class="filter-box-warp"> |
|||
<div class="filter-box"> |
|||
<image class="cover-img" :src="liveData.feedsImg" /> |
|||
</div> |
|||
</div> |
|||
<view class="user"> |
|||
<view class="user-pic"><image class="img" :src="liveData.anchorHeadImg" /></view> |
|||
<view class="user-name">{{ liveData.anchorNickName }}</view> |
|||
</view> |
|||
<view class="count-down" v-if="liveStatus === 102"> |
|||
<image v-if="isLate" class="img" src="@/static/images/live/live-late.png"/> |
|||
<view class="text">{{ liveTimeTitle }}</view> |
|||
<view v-if="!isLate" class="time"> |
|||
<view class="time-item">{{times[0]}}</view> |
|||
<view class="dot">:</view> |
|||
<view class="time-item">{{times[1]}}</view> |
|||
<view class="dot">:</view> |
|||
<view class="time-item">{{times[2]}}</view> |
|||
</view> |
|||
</view> |
|||
<!-- #ifdef MP-WEIXIN --> |
|||
<view |
|||
v-if="liveStatus === 102 && !isLate" |
|||
class="btn-subscribe" |
|||
:class="{subscribed : subscribeLive === '已预约'}" |
|||
@click.stop="onSubscribe" |
|||
>{{ subscribeLive }}</view> |
|||
<!-- #endif --> |
|||
<view class="endContainer" v-if="liveStatus === 103"> |
|||
<view class="endBox"> |
|||
<view></view> |
|||
<view></view> |
|||
<view></view> |
|||
<view></view> |
|||
</view> |
|||
<view>直播已结束</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
const NET = require('@/utils/request') |
|||
const API = require('@/config/api') |
|||
|
|||
import { startLiveTemplate } from '@/config/subscribe.js' |
|||
import { liveAppid } from '@/config/live.js' |
|||
|
|||
// #ifdef MP-WEIXIN |
|||
const livePlayer = requirePlugin('live-player-plugin') |
|||
// #endif |
|||
export default { |
|||
props: { |
|||
liveData: { |
|||
type: Object, |
|||
default: () => ({ |
|||
roomId: 0, |
|||
anchorNickName: '', |
|||
feedsImg: '' // 官方收录封面 |
|||
}) |
|||
} |
|||
}, |
|||
data () { |
|||
return { |
|||
background: ['color1', 'color2', 'color3'], |
|||
indicatorDots: false, |
|||
autoplay: true, |
|||
interval: 2000, // 自动播放间隔时长 |
|||
duration: 500, // 幻灯片切换时长(ms) |
|||
d: 0, |
|||
m: 0, |
|||
s: 0, |
|||
times: [], |
|||
liveStatus: 100, |
|||
liveTimeTitle: '开播倒计时', |
|||
subscribeLive: '立即预约', |
|||
timer: null, |
|||
isLate: false, |
|||
} |
|||
}, |
|||
created() { |
|||
this.liveStatus = this.liveData.liveStatus |
|||
this.subscribeLive = this.liveData.subscribeStatus === 0 ? '立即预约' : '已预约' |
|||
this.getStatus() |
|||
this.countTime() |
|||
// this.getSubscribeStatus() |
|||
}, |
|||
destroyed() { |
|||
clearTimeout(this.timer) |
|||
}, |
|||
methods: { |
|||
getStatus() { |
|||
if (!this.liveData.roomId) { return } |
|||
let _this = this |
|||
// #ifdef MP-WEIXIN |
|||
livePlayer.getLiveStatus({ room_id: this.liveData.roomId }) |
|||
.then(res => { |
|||
// 101: 直播中, 102: 未开始, 103: 已结束, 104: 禁播, 105: 暂停中, 106: 异常,107:已过期 |
|||
// _this.liveData.liveStatus = res.liveStatus |
|||
_this.liveStatus = res.liveStatus |
|||
}) |
|||
.catch(err => { |
|||
console.log('get live status', err) |
|||
}) |
|||
this.timer = setInterval(() => { |
|||
livePlayer.getLiveStatus({ room_id: this.liveData.roomId }) |
|||
.then(res => { |
|||
// 101: 直播中, 102: 未开始, 103: 已结束, 104: 禁播, 105: 暂停中, 106: 异常,107:已过期 |
|||
_this.liveStatus = res.liveStatus |
|||
this.countTime() |
|||
console.log('get live status', res.liveStatus) |
|||
}) |
|||
.catch(err => { |
|||
console.log('get live status', err) |
|||
}) |
|||
}, 60000) |
|||
// #endif |
|||
}, |
|||
changeIndicatorDots(e) { |
|||
this.indicatorDots = !this.indicatorDots |
|||
}, |
|||
changeAutoplay(e) { |
|||
this.autoplay = !this.autoplay |
|||
}, |
|||
intervalChange(e) { |
|||
this.interval = e.target.value |
|||
}, |
|||
durationChange(e) { |
|||
this.duration = e.target.value |
|||
}, |
|||
countTime(){ |
|||
var nowtime = new Date().getTime() //获取当前时间 |
|||
const starttime = new Date(this.liveData.startTime).getTime() |
|||
if(this.liveStatus === 102){ |
|||
if(starttime > nowtime){ |
|||
var lefttime = starttime - nowtime //距离结束时间的毫秒数 |
|||
var leftd = Math.floor(lefttime/(1000*60*60)), //计算小时数 |
|||
leftm = Math.floor(lefttime/(1000*60)%60), //计算分钟数 |
|||
lefts = Math.floor(lefttime/1000%60); //计算秒数 |
|||
this.times = [leftd < 10?'0'+ leftd:leftd,leftm < 10?'0'+ leftm:leftm,lefts < 10?'0'+ lefts:lefts] |
|||
this.liveTimeTitle = '开播倒计时' |
|||
setTimeout(() => { |
|||
this.countTime() |
|||
},1000) |
|||
} else { |
|||
this.times = ['00', '00', '00'] |
|||
this.isLate = true |
|||
this.liveTimeTitle = '正在赶来的路上...' |
|||
} |
|||
} |
|||
}, |
|||
toLive() { |
|||
console.log(liveAppid,'liveAppid') |
|||
console.log(this.liveData.roomId,'this.liveData.roomId') |
|||
if (!liveAppid || !this.liveData) { return } |
|||
// 跳转直播间携带路由参数 |
|||
// let customParams = encodeURIComponent(JSON.stringify({ path: 'livePage/index', pid: 1 })) |
|||
// #ifdef MP-WEIXIN |
|||
wx.navigateTo({ |
|||
url: `plugin-private://${liveAppid}/pages/live-player-plugin?room_id=${this.liveData.roomId}` |
|||
// url: `plugin-private://${liveAppid}/pages/live-player-plugin?room_id=${this.liveData.roomId}&custom_params=${customParams}` |
|||
}) |
|||
// #endif |
|||
}, |
|||
onSubscribe() { |
|||
if (this.subscribeLive === '立即预约') { |
|||
const _this = this |
|||
// #ifdef MP-WEIXIN |
|||
uni.requestSubscribeMessage({ |
|||
tmplIds: [startLiveTemplate], |
|||
success (res) { |
|||
if (res[startLiveTemplate] === "accept") { |
|||
NET.request(API.SubScribeLive, {id: _this.liveData.id }, 'post') |
|||
.then(res => { |
|||
if (res.data) { |
|||
_this.subscribeLive = '已预约' |
|||
} else { |
|||
uni.showToast({ |
|||
title: res.message || '订阅失败,请稍后再试!', |
|||
icon: "none" |
|||
}) |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
console.log(err) |
|||
uni.showToast({ |
|||
title: res.message || '订阅失败,请稍后再试!', |
|||
icon: "none" |
|||
}) |
|||
}) |
|||
} |
|||
} |
|||
}) |
|||
// #endif |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.live-box{ |
|||
position: relative; |
|||
color: #fff; |
|||
width: 100%; |
|||
height: 100%; |
|||
.cover-img{ |
|||
width: 100%; |
|||
height: 100%; |
|||
position: absolute; |
|||
z-index: 0; |
|||
} |
|||
.user{ |
|||
display: flex; |
|||
line-height: 60rpx; |
|||
height: 64rpx; |
|||
&-pic{ |
|||
.img{ |
|||
width: 60rpx; |
|||
height: 60rpx; |
|||
border: 2px solid rgba(255, 255, 255, 0.5019607843137255); |
|||
border-radius: 50%; |
|||
overflow: hidden; |
|||
} |
|||
} |
|||
&-name{ |
|||
font-size: 28rpx; |
|||
margin-left: 16rpx; |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
white-space: nowrap; |
|||
width: 245rpx; |
|||
} |
|||
} |
|||
.live-ongoing{ |
|||
width: 100%; |
|||
height: 100%; |
|||
position: relative; |
|||
.status{ |
|||
position: absolute; |
|||
top: 22rpx; |
|||
left: 22rpx; |
|||
//width: 212upx; |
|||
height: 48rpx; |
|||
// background: rgba(0,0,0,0.3); |
|||
// border: 2rpx solid rgba(255,255,255,0.3); |
|||
border-radius: 24rpx; |
|||
font-size: 20rpx; |
|||
line-height: 44rpx; |
|||
display: flex; |
|||
// padding-right: 8rpx; |
|||
&-state{ |
|||
width: 118rpx; |
|||
height: 44rpx; |
|||
background: linear-gradient(90deg, #C83732 0%, #E25C44 100%); |
|||
opacity: 1; |
|||
border-radius: 26rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
.img{ |
|||
width: 20rpx; |
|||
height: 20rpx; |
|||
margin-right: 6rpx; |
|||
} |
|||
} |
|||
&-num{ |
|||
min-width: 80rpx; |
|||
padding: 0 8rpx; |
|||
} |
|||
} |
|||
.user{ |
|||
position: absolute; |
|||
bottom: 62rpx; |
|||
left: 20rpx; |
|||
} |
|||
.products{ |
|||
position: absolute; |
|||
left: 0rpx; |
|||
bottom: 20rpx; |
|||
width: 100%; |
|||
padding:0 20rpx; |
|||
.swiper{ |
|||
height: 34rpx; |
|||
line-height: 34rpx; |
|||
font-size: 24rpx; |
|||
overflow: hidden; |
|||
text-overflow:ellipsis; |
|||
white-space: nowrap; |
|||
} |
|||
} |
|||
} |
|||
.live-other{ |
|||
position: relative; |
|||
height: 100%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
.filter-box-warp{ |
|||
background-color: #000000; |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
.filter-box{ |
|||
position: absolute; |
|||
top: -30rpx; |
|||
left: -30rpx; |
|||
width: 348rpx; |
|||
height: 464rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
-webkit-filter: blur(20px); |
|||
-moz-filter: blur(21px); |
|||
-ms-filter: blur(20px); |
|||
-o-filter: blur(20px); |
|||
padding: 30rpx; |
|||
box-sizing: content-box; |
|||
} |
|||
} |
|||
.user{ |
|||
position: absolute; |
|||
top: 20rpx; |
|||
left: 20rpx; |
|||
} |
|||
.count-down{ |
|||
position: relative; |
|||
.text{ |
|||
font-size: 26rpx; |
|||
line-height: 36rpx; |
|||
margin-bottom: 16rpx; |
|||
opacity: 0.5; |
|||
text-align: center; |
|||
} |
|||
.img{ |
|||
display: block; |
|||
width: 80rpx; |
|||
height: 80rpx; |
|||
margin: 16rpx auto; |
|||
} |
|||
.time{ |
|||
display: flex; |
|||
justify-content: space-around; |
|||
align-items: center; |
|||
&-item{ |
|||
min-width: 52rpx; |
|||
padding: 0 5rpx; |
|||
height: 52rpx; |
|||
line-height: 52rpx; |
|||
background: #FFFFFF; |
|||
opacity: 1; |
|||
border-radius: 6rpx; |
|||
font-size: 26rpx; |
|||
color: #C83732; |
|||
text-align: center; |
|||
.dot{ |
|||
line-height: 52rpx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.btn-subscribe{ |
|||
width: 200rpx; |
|||
height: 64rpx; |
|||
line-height: 64rpx; |
|||
background: linear-gradient(90deg, #C83732 0%, #E25C44 100%); |
|||
box-shadow: 0rpx 6rpx 12rpx rgba(233, 0, 0, 0.3); |
|||
opacity: 1; |
|||
border-radius: 6rpx; |
|||
color: #fff; |
|||
font-size: 24rpx; |
|||
text-align: center; |
|||
position: absolute; |
|||
bottom: 60rpx; |
|||
left: 50%; |
|||
margin-left: -100rpx; |
|||
&.subscribed{ |
|||
background: #FFFFFF; |
|||
color: #999999; |
|||
box-shadow: none; |
|||
} |
|||
} |
|||
.endContainer{ |
|||
position: relative; |
|||
.endBox{ |
|||
width: 40%; |
|||
height: 60rpx; |
|||
margin: 20rpx auto; |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: flex-end; |
|||
view{ |
|||
width: 0; |
|||
border: 2rpx solid #FFF; |
|||
} |
|||
view:nth-of-type(1){ |
|||
height: 20%; |
|||
} |
|||
view:nth-of-type(2){ |
|||
height: 50%; |
|||
} |
|||
view:nth-of-type(3){ |
|||
height: 30%; |
|||
} |
|||
view:nth-of-type(4){ |
|||
height: 70%; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,60 @@ |
|||
const NET = require('@/utils/request') |
|||
const API = require('@/config/api') |
|||
import {funMixin} from '../../config/mixin' |
|||
|
|||
export const commonMixin = { |
|||
mixins: [funMixin], |
|||
data() { |
|||
return { |
|||
appid: 'wx2b03c6e691cd7370', |
|||
roomId: [], // 填写具体的房间号
|
|||
roomList: [], |
|||
page: { |
|||
page: 1, |
|||
pageSize: 6, |
|||
}, |
|||
} |
|||
}, |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
typeId: { |
|||
type: Number, |
|||
default: 1 |
|||
}, |
|||
shopId: { |
|||
type: Number, |
|||
default: 0 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
}, |
|||
created() { |
|||
this.getLiveRooms() |
|||
}, |
|||
methods: { |
|||
// 获取直播间列表
|
|||
getLiveRooms () { |
|||
NET.request(API.LiveRoomes, this.page, 'get').then(res => { |
|||
console.log(res) |
|||
this.roomList = res.data.list |
|||
}) |
|||
}, |
|||
toLiveRoom (item) { |
|||
this.roomId.push(item.roomid) |
|||
if (!this.appid || !this.roomId.length) { return } |
|||
// 路由参数
|
|||
let customParams = encodeURIComponent(JSON.stringify({ path: 'livePage/index', pid: 1 })) |
|||
// let customParams
|
|||
// 开发者在直播间页面路径上携带自定义参数(如示例中的path和pid参数),后续可以在分享卡片链接和跳转至商详页时获取,详见【获取自定义参数】、【直播间到商详页面携带参数】章节(上限600个字符,超过部分会被截断)
|
|||
// #ifdef MP-WEIXIN
|
|||
wx.navigateTo({ |
|||
url: `plugin-private://${this.appid}/pages/live-player-plugin?room_id=${this.roomId}&custom_params=${customParams}` |
|||
}) |
|||
// #endif
|
|||
} |
|||
} |
|||
} |
@ -0,0 +1,196 @@ |
|||
<template> |
|||
<div class="hom-pro-list" v-if="productData.length>0"> |
|||
<div class="product-swiper"> |
|||
<div class="product-swiper-box"> |
|||
<div class="product-swiper-warp" v-for="(item,index) in productData.slice(0, 3)" :key="index"> |
|||
<div class=" product-swiper-item" @click="jumpProductDetail(item)"> |
|||
<div class="product-swiper-img"> |
|||
<img class="img pic-img default-img" :src="item.image"> |
|||
</div> |
|||
<div class="product-swiper-info"> |
|||
<label class="product-name">{{item.productName}}</label> |
|||
<div class="price-warp"> |
|||
<!-- #ifdef MP-WEIXIN --> |
|||
<img class="iconImg" v-if="item.activityType == 1" src="../../../static/images/groupBuyIcon.png"> |
|||
<img class="iconImg" v-if="item.activityType == 2" src="../../../static/images/spikeIcon.png"> |
|||
<img class="iconImg" v-if="item.activityType == 4" src="../../../static/images/spikeIcon.png"> |
|||
<img class="iconImg" v-if="item.activityType == 3" src="../../../static/images/discountListIcon.png"> |
|||
<img class="iconImg" v-if="item.activityType == 5" src="../../../static/images/discountListIcon.png"> |
|||
<img class="iconImg" v-if="item.activityType == 9" src="../../../static/images/memberCenterIcon.png"> |
|||
<img class="iconImg" v-if="item.activityType == 8" src="https://zk-cereshop.oss-cn-shenzhen.aliyuncs.com/zkthink/2022-02-15/d0d8d96f28904167b271de4ae924d1a8_sceneMarketing.png"> |
|||
<!-- #endif --> |
|||
<!-- #ifdef H5 || APP-PLUS --> |
|||
<image class="iconImg" v-if="item.activityType == 1" src="../../../static/images/groupBuyIcon.png"></image> |
|||
<image class="iconImg" v-if="item.activityType == 2" src="../../../static/images/spikeIcon.png"></image> |
|||
<image class="iconImg" v-if="item.activityType == 4" src="../../../static/images/spikeIcon.png"></image> |
|||
<image class="iconImg" v-if="item.activityType == 3" src="../../../static/images/discountListIcon.png"></image> |
|||
<image class="iconImg" v-if="item.activityType == 5" src="../../../static/images/discountListIcon.png"></image> |
|||
<image class="iconImg" v-if="item.activityType == 9" src="../../../static/images/memberCenterIcon.png"></image> |
|||
<image class="iconImg" v-if="item.activityType == 8" src="https://zk-cereshop.oss-cn-shenzhen.aliyuncs.com/zkthink/2022-02-15/d0d8d96f28904167b271de4ae924d1a8_sceneMarketing.png"></image> |
|||
<!-- #endif --> |
|||
<div class="price"> |
|||
¥ {{item.price}} |
|||
</div> |
|||
<!-- <div class="original-price">--> |
|||
<!-- ¥ {{item.originalPrice}}--> |
|||
<!-- </div>--> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="pagination new-pagination"></div> |
|||
</div> |
|||
<button v-show="componentContent.showMore" class="btn-more" @click="jumpProList(componentContent.productData)">查看全部 <span class="icon iconfont icon-arrow-right"></span></button> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {commonMixin} from '../mixin' |
|||
export default { |
|||
mixins: [commonMixin], |
|||
// data () { |
|||
// return { |
|||
// index: 1, |
|||
// swiperOption: { |
|||
// slidesPerView: 3, |
|||
// spaceBetween: 12, |
|||
// autoplay: false, // 可选选项,自动滑动 |
|||
// loop: true, |
|||
// pagination: { |
|||
// el: '.new-pagination' |
|||
// } |
|||
// } |
|||
// } |
|||
// } |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.hom-pro-list{ |
|||
::v-deep .swiper-wrapper{ |
|||
position: static; |
|||
} |
|||
/**横向滑动**/ |
|||
.product-swiper{ |
|||
width: 100%; |
|||
height: 454upx; |
|||
padding: 90upx 34upx 0; |
|||
background: url("../../../static/images/newProduct/bg-product-card.png") no-repeat center; |
|||
background-size: 710upx 454upx; |
|||
box-sizing: border-box; |
|||
position: relative; |
|||
&+.btn-more{ |
|||
margin-top: 20upx; |
|||
} |
|||
.title{ |
|||
padding: 22upx 0upx 0 0; |
|||
label{ |
|||
background-image: none; |
|||
color: #A56C4C; |
|||
font-style: italic; |
|||
padding: 0; |
|||
} |
|||
} |
|||
&-box { |
|||
padding-bottom: 20upx; |
|||
display: flex; |
|||
} |
|||
&-warp{ |
|||
padding: 0 5upx; |
|||
} |
|||
&-item { |
|||
width: 220upx; |
|||
position: relative; |
|||
background-color: #FFFFFF; |
|||
} |
|||
&-img { |
|||
width: 220upx; |
|||
height: 220upx; |
|||
position: relative; |
|||
&:after{ |
|||
content: ''; |
|||
display: block; |
|||
width: 54upx; |
|||
height: 54upx; |
|||
background: url("../../../static/images/newProduct/flag-new.png") no-repeat; |
|||
background-size: 100% 100%; |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
} |
|||
.img { |
|||
width: 100%; |
|||
height: 100%; |
|||
object-fit: contain; |
|||
} |
|||
} |
|||
&-info { |
|||
background-color: #FFFFFF; |
|||
padding: 10upx; |
|||
text-align: center; |
|||
.product-name{ |
|||
font-size: 20upx; |
|||
color: #333; |
|||
display: block; |
|||
overflow: hidden; |
|||
text-overflow:ellipsis; |
|||
white-space: nowrap; |
|||
margin-bottom: 6upx; |
|||
line-height: 28upx; |
|||
} |
|||
.price-warp{ |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
line-height: 28upx; |
|||
.iconImg { |
|||
width: 58rpx; |
|||
height: 36rpx; |
|||
margin-right: 10rpx; |
|||
} |
|||
.price{ |
|||
color: #C83732; |
|||
font-size: 20upx; |
|||
margin-right: 10upx; |
|||
} |
|||
.original-price{ |
|||
font-size: 16upx; |
|||
color: #ccc; |
|||
text-decoration: line-through; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.pagination{ |
|||
display: flex; |
|||
justify-content: center; |
|||
width: 100%; |
|||
bottom: 0; |
|||
::v-deep .swiper-pagination-bullet{ |
|||
width: 24upx; |
|||
height: 4upx; |
|||
background: #FFFFFF; |
|||
opacity: 0.5; |
|||
border-radius: 2upx; |
|||
margin: 0 10upx; |
|||
} |
|||
::v-deep .swiper-pagination-bullet-active{ |
|||
opacity: 1; |
|||
} |
|||
} |
|||
.btn-more { |
|||
width: 170upx; |
|||
height: 54upx; |
|||
border: 2upx solid #C5AA7B; |
|||
color: #C5AA7B; |
|||
font-size: 24upx; |
|||
background-color: transparent; |
|||
margin: 20upx auto 0; |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
|
|||
</style> |
@ -0,0 +1,89 @@ |
|||
|
|||
import {funMixin} from '../../config/mixin' |
|||
// import { directive, Swiper, SwiperSlide } from 'vue-awesome-swiper'
|
|||
// import 'swiper/css/swiper.css'
|
|||
import api from '../../config/api' |
|||
|
|||
export const commonMixin = { |
|||
name: 'productList', |
|||
mixins: [funMixin], |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
typeId: { |
|||
type: Number, |
|||
default: 1 |
|||
}, |
|||
shopId: { |
|||
type: Number, |
|||
default: 0 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
}, |
|||
// components: {
|
|||
// Swiper,
|
|||
// SwiperSlide
|
|||
// },
|
|||
// directives: {
|
|||
// swiper: directive
|
|||
// },
|
|||
data () { |
|||
return { |
|||
productData: [] |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.getData(true) |
|||
}, |
|||
watch: { |
|||
'componentContent': { |
|||
handler(newVal, oldVal) { |
|||
this.getData() |
|||
}, |
|||
deep: true |
|||
} |
|||
}, |
|||
methods: { |
|||
getData(isFirst) { |
|||
const _ = this |
|||
if (_.componentContent.productData.sourceType === '1') { |
|||
if(_.componentContent.productData.productIdList && _.componentContent.productData.productIdList.length>0){ |
|||
_.sendReq({ |
|||
url: `${api.getProducts}?page=1&pageSize=99&ids=${_.componentContent.productData.productIdList}`, |
|||
method: 'GET' |
|||
}, (proRes) => { |
|||
_.productData = proRes.data.list |
|||
if(isFirst){ |
|||
_.componentContent.productData.imgTextData = _.productData |
|||
} |
|||
// _.$forceUpdate() // 刷新轮播图
|
|||
|
|||
}) |
|||
} else { |
|||
_.productData = [] |
|||
} |
|||
} else if(_.componentContent.productData.sourceType === '2'){ |
|||
if(_.componentContent.productData.categoryId) { |
|||
_.sendReq({ |
|||
url: `${api.getProducts}?page=1&pageSize=99&classifyId=${_.componentContent.productData.categoryId}`, |
|||
method: 'GET' |
|||
}, (proRes) => { |
|||
_.productData = proRes.data.list |
|||
if(isFirst){ |
|||
_.componentContent.productData.imgTextData = _.productData |
|||
} |
|||
_.$forceUpdate() // 刷新轮播图
|
|||
// _.swiper.update()
|
|||
}) |
|||
} else { |
|||
_.productData = [] |
|||
|
|||
} |
|||
} |
|||
} |
|||
}, |
|||
} |
@ -0,0 +1,96 @@ |
|||
<template> |
|||
<div class="notice-list" :class="'terminal'+terminal" :style="{backgroundColor:componentContent.bgColor}"> |
|||
<swiper class="swiper-wrapper" :circular="true" :indicator-dots="false" :autoplay="true" :vertical="true"> |
|||
<swiper-item class="swiper-slide" v-for="(item,index) in noticesList" :key="index"> |
|||
<div class="a-link" @click="jumpNoticeDetail(item)" :style="{color:componentContent.titColor}"><span>{{item.noticeTitle}}</span></div> |
|||
</swiper-item> |
|||
</swiper> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import api from '../config/api' |
|||
import { funMixin } from '../config/mixin' |
|||
import { directive, Swiper, SwiperSlide } from 'vue-awesome-swiper' |
|||
import 'swiper/css/swiper.css' |
|||
export default { |
|||
name: "noticeComponent", |
|||
mixins: [funMixin], |
|||
data () { |
|||
return { |
|||
noticesList: [], |
|||
} |
|||
}, |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.getData() |
|||
}, |
|||
methods: { |
|||
getData() { |
|||
const _ = this |
|||
let _url = `${api.getNotices}` |
|||
const params = { |
|||
method: 'GET', |
|||
url: _url, |
|||
} |
|||
this.sendReq(params, (res) => { |
|||
_.noticesList = res.data |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.notice-list{ |
|||
height: 60upx; |
|||
line-height: 60upx; |
|||
overflow: hidden; |
|||
.a-link{ |
|||
// display: block; |
|||
cursor: pointer; |
|||
overflow: hidden; |
|||
text-overflow:ellipsis; |
|||
white-space: nowrap; |
|||
margin: 0 20upx; |
|||
span{ |
|||
display: inline-block; |
|||
padding-left: 50upx; |
|||
font-size: 24upx; |
|||
background: url("../static/images/notice/ico_notice2.png") no-repeat left center; |
|||
background-size: 30upx 30upx; |
|||
} |
|||
} |
|||
&.terminal4{ |
|||
height: 50upx; |
|||
line-height: 50upx; |
|||
padding: 0; |
|||
.swiper-container{ |
|||
height: 100%; |
|||
width: 1200upx; |
|||
max-width: 100%; |
|||
margin: 0 auto; |
|||
} |
|||
.a-link{ |
|||
cursor: pointer; |
|||
display: block; |
|||
text-align: left; |
|||
margin: 0 20upx; |
|||
span{ |
|||
display: block; |
|||
padding-left: 25upx; |
|||
font-size: 14upx; |
|||
background: url("../static/images/notice/ico_notice.png") no-repeat left center; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,218 @@ |
|||
<template> |
|||
<div class="group-list" v-if="productData&&productData.composeProducts&&productData.composeProducts.length>0"> |
|||
<div class="group-warp"> |
|||
<div class="title"> |
|||
<label> |
|||
<!-- #ifdef MP-WEIXIN --> |
|||
<img class="title-img" src="../../../static/images/price/img-title.png" alt="组合优惠" mode="widthFix"/> |
|||
<!-- #endif --> |
|||
<!-- #ifdef H5 || APP-PLUS --> |
|||
<image class="title-img" src="../../../static/images/price/img-title.png" alt="组合优惠" mode="widthFix"/> |
|||
<!-- #endif --> |
|||
</label> |
|||
<div class="price-text"> |
|||
<swiper class="swiper" :autoplay="true" :vertical="true"> |
|||
<swiper-item v-for="(item,index) in productData.rules" :key="index"> |
|||
{{item.price}}元任选{{item.number}}件 |
|||
</swiper-item> |
|||
</swiper> |
|||
</div> |
|||
<a v-show="componentContent.showMore" class="btn-all a-link" @click="jumpCombination(productData)">更多<i class="iconfont icon-arrow-right"></i></a> |
|||
</div> |
|||
<div> |
|||
<swiper class="swiper pro-box" :indicator-dots="false" :autoplay="true" :display-multiple-items="2" @change="swiperChange"> |
|||
<swiper-item class="pro-item-warp" v-for="(item,index) in productData.composeProducts" :key="index" @click="jumpProductDetail(item)"> |
|||
<div class="pro-item-inner"> |
|||
<div class="pro-item"> |
|||
<div class="pro-item-img"> |
|||
<img class="img default-img" :src="item.image"> |
|||
</div> |
|||
<div class="pro-item-info"> |
|||
<h3 class="name"> |
|||
{{item.productName}} |
|||
</h3> |
|||
<div class="stock"> |
|||
还剩{{item.stockNumber}}件 |
|||
</div> |
|||
<div class="price-warp"> |
|||
<div class="price"> |
|||
¥ {{item.price}} |
|||
</div> |
|||
<div class="original-price"> |
|||
¥ {{item.originalPrice}} |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</swiper-item> |
|||
</swiper> |
|||
<view class="swiper-dots" v-if="productData.composeProducts && productData.composeProducts.length > 2"> |
|||
<text class="dot" :class="index - swiperCurrent <= 1 && index - swiperCurrent >=0 && 'dot-active'" v-for="(dot, index) in productData.composeProducts.length" |
|||
:key="index"></text> |
|||
</view> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
</template> |
|||
|
|||
<script> |
|||
import {commonMixin} from '../mixin' |
|||
export default { |
|||
mixins: [commonMixin], |
|||
data () { |
|||
return { |
|||
swiperCurrent: 0, |
|||
} |
|||
}, |
|||
methods:{ |
|||
swiperChange(e) { |
|||
this.swiperCurrent = e.detail.current; |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.group-list{ |
|||
padding: 30upx 20upx 60upx; |
|||
.group-warp{ |
|||
height: 544upx; |
|||
padding: 0 10upx; |
|||
background: #333333; |
|||
box-shadow: 0 20upx 30upx rgba(0, 0, 0, 0.3); |
|||
opacity: 1; |
|||
border-radius: 20upx; |
|||
position: relative; |
|||
} |
|||
.title{ |
|||
display: flex; |
|||
align-items:center; |
|||
position: relative; |
|||
padding: 32upx 0 20upx 20upx; |
|||
.title-img{ |
|||
width: 203upx; |
|||
} |
|||
.price-text{ |
|||
width: 300upx; |
|||
height: 50upx; |
|||
background: linear-gradient(90deg, #C83732 0%, #E25C44 100%); |
|||
box-shadow: 0 6upx 12upx rgba(233, 0, 0, 0.3); |
|||
border-radius: 26upx; |
|||
font-size: 24upx; |
|||
color: #fff; |
|||
text-align: center; |
|||
line-height: 50upx; |
|||
margin-left: 20upx; |
|||
.swiper{ |
|||
height: 50upx; |
|||
} |
|||
} |
|||
.btn-all{ |
|||
position: absolute; |
|||
right: 8upx; |
|||
top: 40upx; |
|||
line-height: 33upx; |
|||
padding-right: 25upx; |
|||
font-size: 24upx; |
|||
color: #FFEBC4; |
|||
.iconfont{ |
|||
content: ''; |
|||
font-size: 26upx; |
|||
position: absolute; |
|||
right: 0; |
|||
top: 0; |
|||
} |
|||
} |
|||
} |
|||
.pro-box{ |
|||
padding-bottom: 20upx; |
|||
height: 450upx; |
|||
.pro-item-inner{ |
|||
padding: 0 10upx; |
|||
} |
|||
.pro-item{ |
|||
width: 100%; |
|||
height: 412upx; |
|||
background: #FFFFFF; |
|||
.pro-item-img{ |
|||
.img{ |
|||
width: 100%; |
|||
height: 236upx; |
|||
} |
|||
} |
|||
.pro-item-info{ |
|||
padding: 0 20upx; |
|||
.name{ |
|||
font-size: 24upx; |
|||
line-height: 40upx; |
|||
color: #333333; |
|||
overflow: hidden; |
|||
text-overflow:ellipsis; |
|||
white-space: nowrap; |
|||
} |
|||
.stock{ |
|||
padding: 0 8upx; |
|||
height: 40upx; |
|||
border: 2upx solid #E4E5E6; |
|||
line-height: 40upx; |
|||
margin: 10upx 0; |
|||
display: inline-block; |
|||
font-size: 20upx; |
|||
color: #C5AA7B; |
|||
} |
|||
.price{ |
|||
font-size: 32upx; |
|||
font-weight: bold; |
|||
line-height: 44upx; |
|||
color: #C83732; |
|||
padding-right: 10upx; |
|||
display: inline-block; |
|||
} |
|||
.original-price{ |
|||
font-size: 20upx; |
|||
line-height: 28upx; |
|||
color: #CCCCCC; |
|||
display: inline-block; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
//.pagination{ |
|||
// display: flex; |
|||
// justify-content: center; |
|||
// ::v-deep .swiper-pagination-bullet{ |
|||
// width: 24upx; |
|||
// height: 4upx; |
|||
// background: #fff; |
|||
// opacity: 0.5; |
|||
// border-radius: 2upx; |
|||
// margin: 0 5upx; |
|||
// } |
|||
// ::v-deep .swiper-pagination-bullet-active{ |
|||
// opacity: 1; |
|||
// } |
|||
//} |
|||
.swiper-dots { |
|||
display: flex; |
|||
position: absolute; |
|||
left: 50%; |
|||
transform: translateX(-50%); |
|||
bottom: 15rpx; |
|||
z-index: 66; |
|||
.dot { |
|||
width: 24upx; |
|||
height: 4upx; |
|||
background: #fff; |
|||
opacity: 0.5; |
|||
border-radius: 2upx; |
|||
margin: 0 10upx; |
|||
} |
|||
|
|||
.dot-active { |
|||
opacity: 1; |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,73 @@ |
|||
import { directive, Swiper, SwiperSlide } from 'vue-awesome-swiper' |
|||
import 'swiper/css/swiper.css' |
|||
import api from '../../config/api' |
|||
import {funMixin} from '../../config/mixin' |
|||
|
|||
export const commonMixin = { |
|||
name: 'price', |
|||
mixins: [funMixin], |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
typeId: { |
|||
type: Number, |
|||
default: 1 |
|||
}, |
|||
shopId: { |
|||
type: Number, |
|||
default: 0 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
}, |
|||
components: { |
|||
Swiper, |
|||
SwiperSlide |
|||
}, |
|||
directives: { |
|||
swiper: directive |
|||
}, |
|||
data () { |
|||
return { |
|||
productData: { |
|||
composeProducts: [], |
|||
rules: [] |
|||
} |
|||
} |
|||
}, |
|||
watch: { |
|||
'componentContent': { |
|||
handler(newVal, oldVal) { |
|||
this.getData() |
|||
}, |
|||
deep: true |
|||
} |
|||
}, |
|||
created() { |
|||
this.getData() |
|||
}, |
|||
methods: { |
|||
getData() { |
|||
const _ = this |
|||
if(_.componentContent.priceId){ |
|||
const params = { |
|||
method: 'GET', |
|||
url: `${api.getPrices}?shopId=${_.shopId}&ids=${_.componentContent.priceId}&page=1&pageSize=10`, |
|||
} |
|||
this.sendReq(params, (res) => { |
|||
if( res.data.length > 0){ |
|||
_.productData = res.data[0] |
|||
} |
|||
}) |
|||
} else { |
|||
_.productData = { |
|||
composeProducts: [], |
|||
rules: [] |
|||
} |
|||
} |
|||
}, |
|||
} |
|||
} |
@ -0,0 +1,253 @@ |
|||
<template> |
|||
<div class="product-list" :class="'terminal'+terminal"> |
|||
<div class="picListWarp" v-if="componentContent.arrangeType == '横向滑动'"> |
|||
<div class="picList" v-if="productData.products && productData.products.length>0"> |
|||
<div class="swiper-button-prev"></div> |
|||
<div class="swiper-button-next"></div> |
|||
<swiper class="products-swiper" :options="swiperOption"> |
|||
<swiper-slide class="products-swiper-slide item" v-for="(item,index) in productData.composeProducts" :key="index"> |
|||
<div class="a-link" @click="jumpProductDetail(item)"> |
|||
<div class="itemImgBox"> |
|||
<div class="imgBox"> |
|||
<el-image |
|||
:src="item.image" |
|||
fit="contain"></el-image> |
|||
</div> |
|||
</div> |
|||
<div class="text"> |
|||
<div class="discount-text"> |
|||
<span>任选{{productData.rules[0].number}}件{{productData.rules[0].price}}元</span> |
|||
</div> |
|||
<h4 class="h4">{{item.productName}}</h4> |
|||
<div class="priceBox"> |
|||
<span>¥{{item.price}}</span> |
|||
</div> |
|||
<button class="btn-cart" @click="addCart(item.id)">加入购物车</button> |
|||
</div> |
|||
</div> |
|||
</swiper-slide> |
|||
</swiper> |
|||
</div> |
|||
</div> |
|||
<div v-else class="picList" > |
|||
<ul class="clearfix" :class="'imgTextNum' + componentContent.productNum"> |
|||
<li class="item" v-for="(item,index) in productData.composeProducts.slice(0, componentContent.productRowNum * componentContent.productNum)" :key="index"> |
|||
<div class="a-link" @click="jumpProductDetail(item)"> |
|||
<div class="itemImgBox"> |
|||
<div class="imgBox"> |
|||
<el-image |
|||
:src="item.image" |
|||
fit="contain"></el-image> |
|||
</div> |
|||
</div> |
|||
<div class="text"> |
|||
<div class="discount-text"> |
|||
<span>任选{{productData.rules[0].number}}件{{productData.rules[0].price}}元</span> |
|||
</div> |
|||
<h4 class="h4">{{item.productName}}</h4> |
|||
<div class="priceBox"> |
|||
<span>¥{{item.price}}</span> |
|||
</div> |
|||
<button class="btn-cart" @click="addCart(item.id)">加入购物车</button> |
|||
</div> |
|||
</div> |
|||
</li> |
|||
</ul> |
|||
</div> |
|||
<button v-show="componentContent.showMore" class="btn-more" @click="jumpPice(productData)">查看全部 <span class="icon iconfont icon-arrow-right"></span></button> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {commonMixin} from '../mixin' |
|||
export default { |
|||
mixins: [commonMixin], |
|||
data () { |
|||
return { |
|||
swiperOption: { |
|||
slidesPerView: 4, // 显示数量 |
|||
spaceBetween: 13, // 间隔 |
|||
autoplay: false, // 可选选项,自动滑动 |
|||
loop: true, |
|||
pagination: { |
|||
el: '.price-pagination' |
|||
}, |
|||
navigation: { |
|||
nextEl: '.swiper-button-next', |
|||
prevEl: '.swiper-button-prev' |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.product-list{ |
|||
padding: 20px 0; |
|||
background-color: #fff; |
|||
.picListWarp{ |
|||
width: 1380px; |
|||
max-width: 100%; |
|||
margin: 0 auto; |
|||
position: relative; |
|||
} |
|||
.picList{ |
|||
width: 1200px; |
|||
max-width: 100%; |
|||
margin: 0 auto; |
|||
.swiper-button-prev,.swiper-button-next{ |
|||
width: 50px; |
|||
height: 50px; |
|||
position: absolute; |
|||
cursor:pointer; |
|||
top: 140px; |
|||
background-repeat: no-repeat; |
|||
&:after{ |
|||
content: ''; |
|||
} |
|||
} |
|||
.swiper-button-prev{ |
|||
left: 0; |
|||
background: url('../../../static/images/btn-prev.png'); |
|||
} |
|||
.swiper-button-next{ |
|||
right: 0; |
|||
background: url('../../../static/images/btn-next.png'); |
|||
} |
|||
.a-link{ |
|||
cursor: pointer; |
|||
&:hover{ |
|||
box-shadow: 3px 4px 20px 0px rgba(186, 186, 186, 0.5); |
|||
} |
|||
.itemImgBox { |
|||
height: auto; |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: center; |
|||
.imgBox { |
|||
padding-bottom: 100%; |
|||
background-color: #cacaca; |
|||
position: relative; |
|||
.el-image { |
|||
width: 100%; |
|||
height: 100%; |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
} |
|||
} |
|||
} |
|||
.text{ |
|||
padding:25px 10px 17px; |
|||
text-align: center; |
|||
position: relative; |
|||
//height: 180px; |
|||
.discount-text{ |
|||
background: url("../../../static/images/price/bg-discount.png") no-repeat; |
|||
width: 100%; |
|||
height: 47px; |
|||
font-size: 14px; |
|||
color: #fff; |
|||
line-height: 60px; |
|||
text-align: center; |
|||
position: absolute; |
|||
top: -47px; |
|||
left: 0; |
|||
} |
|||
.h4{ |
|||
font-size: 18px; |
|||
line-height: 24px; |
|||
overflow: hidden; |
|||
text-overflow:ellipsis; |
|||
white-space: nowrap; |
|||
color: #333333; |
|||
//max-height: 48px; |
|||
} |
|||
.p{ |
|||
color: #999; |
|||
font-size: 16px; |
|||
overflow: hidden; |
|||
text-overflow:ellipsis; |
|||
white-space: nowrap; |
|||
padding-top: 18px; |
|||
position: relative; |
|||
margin-top: 8px; |
|||
&:after{ |
|||
position: absolute; |
|||
top: 0; |
|||
left: 50%; |
|||
margin-left: -80px; |
|||
width: 160px; |
|||
height: 2px; |
|||
background: #F0F0F0; |
|||
content: ''; |
|||
} |
|||
} |
|||
.priceBox { |
|||
padding-top: 11px; |
|||
line-height: 33px; |
|||
span { |
|||
font-size: 25px; |
|||
color: #C83732; |
|||
padding-right: 12px; |
|||
} |
|||
span.discount { |
|||
font-size: 18px; |
|||
color: #ccc; |
|||
text-decoration: line-through; |
|||
} |
|||
} |
|||
.btn-cart{ |
|||
margin-top: 5px; |
|||
width: 270px; |
|||
height: 40px; |
|||
background-color: #333; |
|||
font-size: 18px; |
|||
color: #FFEBC4; |
|||
} |
|||
} |
|||
} |
|||
ul{ |
|||
margin: -15px 0 0 -15px; |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
li{ |
|||
flex: 0 0 50%; |
|||
padding: 15px 0 0 15px; |
|||
width: 0; |
|||
} |
|||
} |
|||
.imgTextNum2 { |
|||
li { |
|||
flex: 0 0 50%; |
|||
} |
|||
} |
|||
.imgTextNum3 { |
|||
li { |
|||
flex: 0 0 33.33%; |
|||
} |
|||
} |
|||
.imgTextNum4 { |
|||
li { |
|||
flex: 0 0 25%; |
|||
} |
|||
} |
|||
.imgTextNum5 { |
|||
li { |
|||
flex: 0 0 20%; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.btn-more { |
|||
width: 130px; |
|||
height: 41px; |
|||
border: 2px solid #C5AA7B; |
|||
color: #C5AA7B; |
|||
font-size: 18px; |
|||
background-color: transparent; |
|||
margin: 20px auto 0; |
|||
display: block; |
|||
} |
|||
</style> |
@ -0,0 +1,564 @@ |
|||
<template> |
|||
<div class="hom-pro-list"> |
|||
<div class="title"> |
|||
<!-- #ifdef MP-WEIXIN --> |
|||
<img |
|||
class="title-img" |
|||
src="../../../static/images/product/img-title.png" |
|||
alt="商品推荐" |
|||
mode="widthFix" |
|||
/> |
|||
<!-- #endif --> |
|||
<!-- #ifdef H5 || APP-PLUS --> |
|||
<image |
|||
class="title-img" |
|||
src="../../../static/images/product/img-title.png" |
|||
alt="商品推荐" |
|||
mode="widthFix" |
|||
/> |
|||
<!-- #endif --> |
|||
</div> |
|||
<div |
|||
v-if="componentContent.arrangeType == '横向滑动' && productData.length > 2" |
|||
class="product-list" |
|||
> |
|||
<swiper |
|||
ref="mySwiper" |
|||
class="swiper product-list-box" |
|||
:circular="true" |
|||
:indicator-dots="false" |
|||
:autoplay="true" |
|||
:display-multiple-items="2" |
|||
@change="swiperChange" |
|||
> |
|||
<swiper-item |
|||
class="product-list-item-warp" |
|||
v-for="(item,index) in productData" |
|||
:key="index" |
|||
> |
|||
<div class="product-list-item" v-if="JSON.stringify(item)!=='{}'" @click="jumpProductDetail(item)"> |
|||
<div class="product-list-img"> |
|||
<img |
|||
class="img pic-img default-img" |
|||
:src="item.image" |
|||
> |
|||
</div> |
|||
<div class="product-list-info"> |
|||
<label class="product-name">{{ item.productName }}</label> |
|||
<div class="flex"> |
|||
<div |
|||
class="shop-box" |
|||
v-if="typeId == 1" |
|||
@click.stop="jumpStore(item)" |
|||
> |
|||
<label class="shop-name">{{ item.shopName }}</label> |
|||
<div class="shop-logo"> |
|||
<img :src="item.shopLogo"> |
|||
</div> |
|||
</div> |
|||
<label class="buy-count">已售{{ item.number ? item.number : 0 }}件</label> |
|||
</div> |
|||
<div class="price-warp"> |
|||
<!-- #ifdef MP-WEIXIN --> |
|||
<img |
|||
class="iconImg" |
|||
v-if="item.activityType == 1" |
|||
src="../../../static/images/groupBuyIcon.png" |
|||
> |
|||
<img |
|||
class="iconImg" |
|||
v-if="item.activityType == 2" |
|||
src="../../../static/images/spikeIcon.png" |
|||
> |
|||
<img |
|||
class="iconImg" |
|||
v-if="item.activityType == 4" |
|||
src="../../../static/images/spikeIcon.png" |
|||
> |
|||
<img |
|||
class="iconImg" |
|||
v-if="item.activityType == 3" |
|||
src="../../../static/images/discountListIcon.png" |
|||
> |
|||
<img |
|||
class="iconImg" |
|||
v-if="item.activityType == 5" |
|||
src="../../../static/images/discountListIcon.png" |
|||
> |
|||
<img |
|||
class="iconImg" |
|||
v-if="item.activityType == 9" |
|||
src="../../../static/images/memberCenterIcon.png" |
|||
> |
|||
<img |
|||
class="iconImg" |
|||
v-if="item.activityType == 8" |
|||
src="https://zk-cereshop.oss-cn-shenzhen.aliyuncs.com/zkthink/2022-02-15/d0d8d96f28904167b271de4ae924d1a8_sceneMarketing.png" |
|||
> |
|||
<!-- #endif --> |
|||
<!-- #ifdef H5 || APP-PLUS --> |
|||
<image |
|||
class="iconImg" |
|||
v-if="item.activityType == 1" |
|||
src="../../../static/images/groupBuyIcon.png" |
|||
> |
|||
<image |
|||
class="iconImg" |
|||
v-if="item.activityType == 2" |
|||
src="../../../static/images/spikeIcon.png" |
|||
> |
|||
<image |
|||
class="iconImg" |
|||
v-if="item.activityType == 4" |
|||
src="../../../static/images/spikeIcon.png" |
|||
> |
|||
<image |
|||
class="iconImg" |
|||
v-if="item.activityType == 3" |
|||
src="../../../static/images/discountListIcon.png" |
|||
> |
|||
<image |
|||
class="iconImg" |
|||
v-if="item.activityType == 5" |
|||
src="../../../static/images/discountListIcon.png" |
|||
> |
|||
<image |
|||
class="iconImg" |
|||
v-if="item.activityType == 9" |
|||
src="../../../static/images/memberCenterIcon.png" |
|||
> |
|||
<image |
|||
class="iconImg" |
|||
v-if="item.activityType == 8" |
|||
src="https://zk-cereshop.oss-cn-shenzhen.aliyuncs.com/zkthink/2022-02-15/d0d8d96f28904167b271de4ae924d1a8_sceneMarketing.png" |
|||
> |
|||
<!-- #endif --> |
|||
<div class="price"> |
|||
¥ {{ item.price }} |
|||
</div> |
|||
<div class="original-price"> |
|||
¥ {{ item.originalPrice }} |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<!-- 自定义骨架屏 --> |
|||
<div |
|||
class="product-list-item ske-loading" |
|||
v-else |
|||
> |
|||
<div class="product-list-img child-loading"> |
|||
|
|||
</div> |
|||
<div class="product-list-info"> |
|||
<label class="product-name child-loading"></label> |
|||
<div class="price-warp child-loading" style="padding: 5px 0"> |
|||
</div> |
|||
<div class="price-warp child-loading" style="padding: 5px 0"> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</swiper-item> |
|||
</swiper> |
|||
<view |
|||
class="swiper-dots" |
|||
v-if="productData && productData.length > 2" |
|||
> |
|||
<text |
|||
class="dot" |
|||
:class="index - swiperCurrent <= 1 && index - swiperCurrent >=0 && 'dot-active'" |
|||
v-for="(dot, index) in productData.length" |
|||
:key="index" |
|||
></text> |
|||
</view> |
|||
</div> |
|||
<div |
|||
v-else |
|||
class="product-list" |
|||
> |
|||
<div class="product-list-box"> |
|||
<div |
|||
class="product-list-item-warp" |
|||
v-for="(item,index) in productData" |
|||
:key="index" |
|||
> |
|||
<div |
|||
@click="jumpProductDetail(item)" |
|||
class="product-list-item" |
|||
v-if="JSON.stringify(item)!=='{}'" |
|||
> |
|||
<div class="product-list-img"> |
|||
<img |
|||
class="img pic-img default-img" |
|||
:src="item.image" |
|||
> |
|||
</div> |
|||
<div class="product-list-info"> |
|||
<label class="product-name">{{ item.productName }}</label> |
|||
<div class="flex"> |
|||
<div |
|||
class="shop-box" |
|||
v-if="typeId == 1" |
|||
@click.stop="jumpStore(item)" |
|||
> |
|||
<label class="shop-name">{{ item.shopName }}</label> |
|||
<div class="shop-logo"> |
|||
<img :src="item.shopLogo"> |
|||
</div> |
|||
</div> |
|||
<label class="buy-count">已售{{ item.number ? item.number : 0 }}件</label> |
|||
</div> |
|||
<div class="price-warp"> |
|||
<!-- #ifdef MP-WEIXIN --> |
|||
<img |
|||
class="iconImg" |
|||
v-if="item.activityType == 1" |
|||
src="../../../static/images/groupBuyIcon.png" |
|||
/> |
|||
<img |
|||
class="iconImg" |
|||
v-if="item.activityType == 2" |
|||
src="../../../static/images/spikeIcon.png" |
|||
/> |
|||
<img |
|||
class="iconImg" |
|||
v-if="item.activityType == 4" |
|||
src="../../../static/images/spikeIcon.png" |
|||
/> |
|||
<img |
|||
class="iconImg" |
|||
v-if="item.activityType == 3" |
|||
src="../../../static/images/discountListIcon.png" |
|||
/> |
|||
<img |
|||
class="iconImg" |
|||
v-if="item.activityType == 5" |
|||
src="../../../static/images/discountListIcon.png" |
|||
/> |
|||
<img |
|||
class="iconImg" |
|||
v-if="item.activityType == 9" |
|||
src="../../../static/images/memberCenterIcon.png" |
|||
/> |
|||
<img |
|||
class="iconImg" |
|||
v-if="item.activityType == 8" |
|||
src="https://zk-cereshop.oss-cn-shenzhen.aliyuncs.com/zkthink/2022-02-15/d0d8d96f28904167b271de4ae924d1a8_sceneMarketing.png" |
|||
/> |
|||
<!-- #endif --> |
|||
<!-- #ifdef H5 || APP-PLUS --> |
|||
<image |
|||
class="iconImg" |
|||
v-if="item.activityType == 1" |
|||
src="../../../static/images/groupBuyIcon.png" |
|||
/> |
|||
<image |
|||
class="iconImg" |
|||
v-if="item.activityType == 2" |
|||
src="../../../static/images/spikeIcon.png" |
|||
/> |
|||
<image |
|||
class="iconImg" |
|||
v-if="item.activityType == 4" |
|||
src="../../../static/images/spikeIcon.png" |
|||
/> |
|||
<image |
|||
class="iconImg" |
|||
v-if="item.activityType == 3" |
|||
src="../../../static/images/discountListIcon.png" |
|||
/> |
|||
<image |
|||
class="iconImg" |
|||
v-if="item.activityType == 5" |
|||
src="../../../static/images/discountListIcon.png" |
|||
/> |
|||
<image |
|||
class="iconImg" |
|||
v-if="item.activityType == 9" |
|||
src="../../../static/images/memberCenterIcon.png" |
|||
/> |
|||
<image |
|||
class="iconImg" |
|||
v-if="item.activityType == 8" |
|||
src="https://zk-cereshop.oss-cn-shenzhen.aliyuncs.com/zkthink/2022-02-15/d0d8d96f28904167b271de4ae924d1a8_sceneMarketing.png" |
|||
/> |
|||
<!-- #endif --> |
|||
<div class="price"> |
|||
¥ {{ item.price }} |
|||
</div> |
|||
<div class="original-price"> |
|||
¥ {{ item.originalPrice }} |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<!-- 自定义骨架屏 --> |
|||
<div |
|||
class="product-list-item ske-loading" |
|||
v-else |
|||
> |
|||
<div class="product-list-img child-loading"> |
|||
|
|||
</div> |
|||
<div class="product-list-info"> |
|||
<label class="product-name child-loading"></label> |
|||
<div class="price-warp child-loading" style="padding: 5px 0"> |
|||
</div> |
|||
<div class="price-warp child-loading" style="padding: 5px 0"> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<button |
|||
v-show="componentContent.showMore" |
|||
class="btn-more" |
|||
@click="jumpProList(componentContent.productData)" |
|||
>查看全部 <span class="icon iconfont icon-arrow-right"></span></button> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { commonMixin } from '../mixin' |
|||
|
|||
export default { |
|||
mixins: [commonMixin], |
|||
data() { |
|||
return { |
|||
swiperCurrent: 0, |
|||
} |
|||
}, |
|||
methods: { |
|||
swiperChange(e) { |
|||
this.swiperCurrent = e.detail.current; |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style |
|||
lang="scss" |
|||
scoped |
|||
> |
|||
.hom-pro-list { |
|||
padding: 20rpx 13rpx; |
|||
|
|||
.title { |
|||
text-align: center; |
|||
margin-bottom: 20rpx; |
|||
|
|||
.title-img { |
|||
width: 211rpx; |
|||
} |
|||
} |
|||
|
|||
/**多行多列**/ |
|||
.product-list { |
|||
position: relative; |
|||
|
|||
&-box { |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
flex-direction: row; |
|||
|
|||
&.swiper { |
|||
height: 620rpx; |
|||
} |
|||
} |
|||
|
|||
&.product-swiper .product-list-box { |
|||
padding-left: 0; |
|||
} |
|||
|
|||
&-item-warp { |
|||
margin: 0 0 20rpx 0; |
|||
} |
|||
|
|||
&-item { |
|||
width: 348rpx; |
|||
padding: 0 7rpx; |
|||
box-sizing: content-box; |
|||
} |
|||
|
|||
&-img { |
|||
width: 348rpx; |
|||
height: 348rpx; |
|||
background-color: #f5f5f5; |
|||
border-radius: 10rpx 10rpx 0 0; |
|||
|
|||
.img { |
|||
width: 100%; |
|||
height: 100%; |
|||
object-fit: contain; |
|||
} |
|||
} |
|||
|
|||
&-info { |
|||
background-color: #FFFFFF; |
|||
//box-shadow: 0px 0px 15px 0px rgba(52, 52, 52, 0.15); |
|||
border-radius: 0 0 10rpx 10rpx; |
|||
padding: 20rpx; |
|||
|
|||
label { |
|||
font-weight: normal; |
|||
} |
|||
|
|||
.product-name { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
display: block; |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
white-space: nowrap; |
|||
margin-bottom: 18rpx; |
|||
line-height: 40rpx; |
|||
} |
|||
|
|||
.flex { |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
|
|||
.shop-box { |
|||
background-color: #333333; |
|||
border-radius: 0rpx 20rpx 20rpx 0rpx; |
|||
line-height: 40rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
height: 40rpx; |
|||
margin-right: 10rpx; |
|||
|
|||
.shop-name { |
|||
font-size: 20rpx; |
|||
color: #FFEBC4; |
|||
padding: 0 8rpx 0 12rpx; |
|||
} |
|||
|
|||
.shop-logo { |
|||
border: 2rpx solid #707070; |
|||
border-radius: 50%; |
|||
overflow: hidden; |
|||
float: right; |
|||
|
|||
img { |
|||
width: 34rpx; |
|||
height: 34rpx; |
|||
display: block; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.buy-count { |
|||
color: #C5AA7B; |
|||
font-size: 20rpx; |
|||
border: 2rpx solid #E4E5E6; |
|||
line-height: 40rpx; |
|||
padding: 0 5rpx; |
|||
} |
|||
|
|||
.price-warp { |
|||
display: flex; |
|||
align-items: baseline; |
|||
line-height: 56rpx; |
|||
|
|||
.iconImg { |
|||
width: 58rpx; |
|||
height: 36rpx; |
|||
margin-right: 10rpx; |
|||
} |
|||
|
|||
.price { |
|||
color: #C83732; |
|||
font-size: 40rpx; |
|||
margin-right: 20rpx; |
|||
} |
|||
|
|||
.original-price { |
|||
font-size: 24rpx; |
|||
color: #ccc; |
|||
text-decoration: line-through; |
|||
} |
|||
} |
|||
} |
|||
|
|||
//::v-deep .swiper-pagination-bullet{ |
|||
// display: none; |
|||
//} |
|||
} |
|||
} |
|||
|
|||
//::v-deep .uni-swiper-dots{ |
|||
// display: flex; |
|||
// justify-content: center; |
|||
// padding: 10rpx 0; |
|||
// .uni-swiper-dot{ |
|||
// width: 10rpx; |
|||
// height: 10rpx; |
|||
// background: #333333; |
|||
// opacity: 0.3; |
|||
// border-radius: 5rpx; |
|||
// margin: 0 5rpx; |
|||
// &-active{ |
|||
// width: 20rpx; |
|||
// height: 10rpx; |
|||
// opacity: 1; |
|||
// } |
|||
// } |
|||
//} |
|||
.swiper-dots { |
|||
display: flex; |
|||
position: absolute; |
|||
left: 50%; |
|||
transform: translateX(-50%); |
|||
bottom: 15rpx; |
|||
z-index: 66; |
|||
|
|||
.dot { |
|||
width: 10rpx; |
|||
height: 10rpx; |
|||
background: #333333; |
|||
opacity: 0.3; |
|||
border-radius: 5rpx; |
|||
margin: 0 10rpx; |
|||
} |
|||
|
|||
.dot-active { |
|||
width: 20rpx; |
|||
opacity: 1; |
|||
} |
|||
} |
|||
|
|||
//.pagination{ |
|||
// display: flex; |
|||
// justify-content: center; |
|||
// padding: 20rpx 0; |
|||
// ::v-deep .swiper-pagination-bullet{ |
|||
// width: 10rpx; |
|||
// height: 10rpx; |
|||
// background: #333333; |
|||
// opacity: 0.3; |
|||
// border-radius: 5rpx; |
|||
// margin: 0 5rpx; |
|||
// } |
|||
// ::v-deep .swiper-pagination-bullet-active{ |
|||
// width: 20rpx; |
|||
// height: 10rpx; |
|||
// opacity: 1; |
|||
// } |
|||
//} |
|||
|
|||
.btn-more { |
|||
width: 170rpx; |
|||
height: 54rpx; |
|||
line-height: 54rpx; |
|||
border: 2rpx solid #C5AA7B; |
|||
color: #C5AA7B; |
|||
font-size: 24rpx; |
|||
background-color: transparent; |
|||
margin: 20rpx auto 0; |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
|
|||
</style> |
@ -0,0 +1,96 @@ |
|||
// import { directive, Swiper, SwiperSlide } from 'vue-awesome-swiper'
|
|||
// import 'swiper/css/swiper.css'
|
|||
import {funMixin} from '../../config/mixin' |
|||
import api from '../../config/api' |
|||
|
|||
export const commonMixin = { |
|||
name: 'productList', |
|||
mixins: [funMixin], |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
typeId: { |
|||
type: Number, |
|||
default: 1 |
|||
}, |
|||
shopId: { |
|||
type: Number, |
|||
default: 0 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
}, |
|||
// components: {
|
|||
// Swiper,
|
|||
// SwiperSlide
|
|||
// },
|
|||
// directives: {
|
|||
// swiper: directive
|
|||
// },
|
|||
data () { |
|||
return { |
|||
productData: [] |
|||
} |
|||
}, |
|||
watch: { |
|||
'componentContent': { |
|||
handler(newVal, oldVal) { |
|||
this.getData() |
|||
}, |
|||
deep: true |
|||
} |
|||
}, |
|||
created() { |
|||
this.getData(true) |
|||
}, |
|||
computed: { |
|||
swiper() { |
|||
if(this.$refs.mySwiper){ |
|||
return this.$refs.mySwiper.$swiper |
|||
} |
|||
} |
|||
}, |
|||
methods: { |
|||
getData(isFirst) { |
|||
const _ = this |
|||
this.productData = [{},{},{},{},{},{},{},{}] |
|||
if (_.componentContent.productData.sourceType === '1') { |
|||
if(_.componentContent.productData.productIdList && _.componentContent.productData.productIdList.length>0){ |
|||
_.sendReq({ |
|||
url: `${api.getProducts}?page=1&pageSize=99&ids=${_.componentContent.productData.productIdList}`, |
|||
method: 'GET' |
|||
}, (proRes) => { |
|||
_.productData = proRes.data.list |
|||
_.productData = _.productData.filter(item=>JSON.stringify(item) !== '{}') |
|||
if(isFirst){ |
|||
_.componentContent.productData.imgTextData = _.productData |
|||
} |
|||
}) |
|||
} else { |
|||
_.productData = [] |
|||
} |
|||
} else if(_.componentContent.productData.sourceType === '2'){ |
|||
if(_.componentContent.productData.categoryId) { |
|||
_.sendReq({ |
|||
url: `${api.getProducts}?page=1&pageSize=99&classifyId=${_.componentContent.productData.categoryId}`, |
|||
method: 'GET' |
|||
}, (proRes) => { |
|||
_.productData = proRes.data.list |
|||
_.productData = _.productData.filter(item=>JSON.stringify(item) !== '{}') |
|||
if(isFirst){ |
|||
_.componentContent.productData.imgTextData = _.productData |
|||
} |
|||
// _.swiper.update()
|
|||
}) |
|||
} else { |
|||
_.productData = { |
|||
products:[] |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
} |
|||
} |
@ -0,0 +1,226 @@ |
|||
<template> |
|||
<div class="product-list" :class="'terminal'+terminal"> |
|||
<div class="picListWarp" v-if="componentContent.arrangeType == '横向滑动'"> |
|||
<div class="picList" v-if="productData && productData.length>0"> |
|||
<div class="swiper-button-prev"></div> |
|||
<div class="swiper-button-next"></div> |
|||
<swiper ref="swiper" class="products-swiper" :options="swiperOption"> |
|||
<swiper-slide class="products-swiper-slide item" v-for="(item,index) in productData" :key="index"> |
|||
<div class="a-link" @click="jumpProductDetail(item)"> |
|||
<div class="itemImgBox"> |
|||
<div class="imgBox"> |
|||
<el-image |
|||
:src="item.image" |
|||
fit="contain"></el-image> |
|||
</div> |
|||
</div> |
|||
<div class="text"> |
|||
<h4 class="h4">{{item.productName}}</h4> |
|||
<div class="priceBox"> |
|||
<span>¥{{item.price}}</span> |
|||
<span class="discount" v-if="item.originalPrice">¥{{item.originalPrice}}</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</swiper-slide> |
|||
</swiper> |
|||
</div> |
|||
</div> |
|||
<div v-else class="picList" > |
|||
<ul class="clearfix" :class="'imgTextNum' + componentContent.productNum"> |
|||
<li class="item" v-for="(item,index) in productData.slice(0, componentContent.productRowNum * componentContent.productNum)" :key="index"> |
|||
<div class="a-link" @click="jumpProductDetail(item)"> |
|||
<div class="itemImgBox"> |
|||
<div class="imgBox"> |
|||
<el-image |
|||
:src="item.image" |
|||
fit="contain"></el-image> |
|||
</div> |
|||
</div> |
|||
<div class="text"> |
|||
<h4 class="h4">{{item.productName}}</h4> |
|||
<div class="priceBox"> |
|||
<span>¥{{item.price}}</span> |
|||
<span class="discount" v-if="item.originalPrice">¥{{item.originalPrice}}</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</li> |
|||
</ul> |
|||
</div> |
|||
<button v-show="componentContent.showMore" class="btn-more" @click="jumpProList(componentContent.productData)">查看全部 <span class="icon iconfont icon-arrow-right"></span></button> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {commonMixin} from '../mixin' |
|||
export default { |
|||
mixins: [commonMixin], |
|||
data () { |
|||
return { |
|||
swiperOption: { |
|||
slidesPerView: 4, // 显示数量 |
|||
spaceBetween: 13, // 间隔 |
|||
autoplay: false, // 可选选项,自动滑动 |
|||
loop: true, |
|||
pagination: { |
|||
el: '.product-pagination' |
|||
}, |
|||
navigation: { |
|||
nextEl: '.swiper-button-next', |
|||
prevEl: '.swiper-button-prev' |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.product-list{ |
|||
padding: 20px 0; |
|||
background-color: #fff; |
|||
.picListWarp{ |
|||
width: 1380px; |
|||
max-width: 100%; |
|||
margin: 0 auto; |
|||
position: relative; |
|||
} |
|||
.picList{ |
|||
width: 1200px; |
|||
max-width: 100%; |
|||
margin: 0 auto; |
|||
.swiper-button-prev,.swiper-button-next{ |
|||
width: 50px; |
|||
height: 50px; |
|||
position: absolute; |
|||
cursor:pointer; |
|||
top: 140px; |
|||
background-repeat: no-repeat; |
|||
&:after{ |
|||
content: ''; |
|||
} |
|||
} |
|||
.swiper-button-prev{ |
|||
left: 0; |
|||
background: url('../../../static/images/btn-prev.png'); |
|||
} |
|||
.swiper-button-next{ |
|||
right: 0; |
|||
background: url('../../../static/images/btn-next.png'); |
|||
} |
|||
.a-link{ |
|||
cursor: pointer; |
|||
&:hover{ |
|||
box-shadow: 3px 4px 20px 0px rgba(186, 186, 186, 0.5); |
|||
} |
|||
.itemImgBox { |
|||
height: auto; |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: center; |
|||
.imgBox { |
|||
padding-bottom: 100%; |
|||
background-color: #cacaca; |
|||
position: relative; |
|||
.el-image { |
|||
width: 100%; |
|||
height: 100%; |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
} |
|||
} |
|||
} |
|||
.text{ |
|||
padding:25px 20px 17px; |
|||
text-align: center; |
|||
//height: 180px; |
|||
.h4{ |
|||
font-size: 18px; |
|||
line-height: 24px; |
|||
overflow: hidden; |
|||
text-overflow:ellipsis; |
|||
white-space: nowrap; |
|||
color: #333333; |
|||
//max-height: 48px; |
|||
} |
|||
.p{ |
|||
color: #999; |
|||
font-size: 16px; |
|||
overflow: hidden; |
|||
text-overflow:ellipsis; |
|||
white-space: nowrap; |
|||
padding-top: 18px; |
|||
position: relative; |
|||
margin-top: 8px; |
|||
&:after{ |
|||
position: absolute; |
|||
top: 0; |
|||
left: 50%; |
|||
margin-left: -80px; |
|||
width: 160px; |
|||
height: 2px; |
|||
background: #F0F0F0; |
|||
content: ''; |
|||
} |
|||
} |
|||
.priceBox { |
|||
padding-top: 11px; |
|||
line-height: 33px; |
|||
span { |
|||
font-size: 25px; |
|||
color: #C83732; |
|||
padding-right: 12px; |
|||
} |
|||
span.discount { |
|||
font-size: 18px; |
|||
color: #ccc; |
|||
text-decoration: line-through; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
ul{ |
|||
margin: -15px 0 0 -15px; |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
li{ |
|||
flex: 0 0 50%; |
|||
padding: 15px 0 0 15px; |
|||
width: 0; |
|||
} |
|||
} |
|||
.imgTextNum2 { |
|||
li { |
|||
flex: 0 0 50%; |
|||
} |
|||
} |
|||
.imgTextNum3 { |
|||
li { |
|||
flex: 0 0 33.33%; |
|||
} |
|||
} |
|||
.imgTextNum4 { |
|||
li { |
|||
flex: 0 0 25%; |
|||
} |
|||
} |
|||
.imgTextNum5 { |
|||
li { |
|||
flex: 0 0 20%; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.btn-more { |
|||
width: 130px; |
|||
height: 41px; |
|||
border: 2px solid #C5AA7B; |
|||
color: #C5AA7B; |
|||
font-size: 18px; |
|||
background-color: transparent; |
|||
margin: 20px auto 0; |
|||
display: block; |
|||
} |
|||
</style> |
@ -0,0 +1,157 @@ |
|||
<template> |
|||
<div class="shop" :class="'terminal' + terminal"> |
|||
<swiper class="swiper" :indicator-dots="false" :autoplay="true" @change="swiperChange"> |
|||
<swiper-item class="shop-item" v-for="(item,index) in imgList" :key="index"> |
|||
<div class="shop-item-warp"> |
|||
<img class="img" :src="item.img" mode="widthFix"> |
|||
<div class="a-link" @click="jumpLink(item.linkObj)"> |
|||
进店逛逛<i class="iconfont icon-arrow-right"></i> |
|||
</div> |
|||
</div> |
|||
</swiper-item> |
|||
</swiper> |
|||
<view class="swiper-dots" v-if="imgList && imgList.length"> |
|||
<text class="dot" :class="index === swiperCurrent && 'dot-active'" v-for="(dot, index) in imgList.length" |
|||
:key="index"></text> |
|||
</view> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
// import { directive, Swiper, SwiperSlide } from 'vue-awesome-swiper' |
|||
// import 'swiper/css/swiper.css' |
|||
import {funMixin} from '../config/mixin' |
|||
export default { |
|||
name: 'shop', |
|||
mixins: [funMixin], |
|||
data () { |
|||
return { |
|||
swiperCurrent: 0, |
|||
} |
|||
}, |
|||
methods:{ |
|||
swiperChange(e) { |
|||
this.swiperCurrent = e.detail.current; |
|||
} |
|||
}, |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
}, |
|||
// components: { |
|||
// Swiper, |
|||
// SwiperSlide |
|||
// }, |
|||
// directives: { |
|||
// swiper: directive |
|||
// }, |
|||
computed: { |
|||
imgList: function () { |
|||
console.log(this.componentContent) |
|||
return this.componentContent.imgTextData.filter(function (item) { |
|||
return item.img |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.shop{ |
|||
position: relative; |
|||
.swiper{ |
|||
height: 460upx; |
|||
} |
|||
&-item{ |
|||
&-warp{ |
|||
position: relative; |
|||
padding: 0 20upx; |
|||
.img{ |
|||
width: 100%; |
|||
height: 420upx; |
|||
} |
|||
.a-link{ |
|||
width: 220upx; |
|||
height: 80upx; |
|||
line-height: 80upx; |
|||
background: linear-gradient(225deg, #585858 0%, #333333 100%); |
|||
box-shadow: 0px 20upx 40upx rgba(0, 0, 0, 0.3); |
|||
display: block; |
|||
color: #fff; |
|||
font-size: 28upx; |
|||
text-align: center; |
|||
position: absolute; |
|||
right: 0; |
|||
bottom: 30upx; |
|||
.icon{ |
|||
margin-left: 20upx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
//.pagination{ |
|||
// display: flex; |
|||
// justify-content: center; |
|||
// padding:20upx 0; |
|||
// ::v-deep .swiper-pagination-bullet{ |
|||
// width: 12upx; |
|||
// height: 12upx; |
|||
// background: #333333; |
|||
// border-radius: 50%; |
|||
// opacity: 0.2; |
|||
// margin: 0 10upx; |
|||
// } |
|||
// ::v-deep .swiper-pagination-bullet-active{ |
|||
// width: 24upx; |
|||
// height: 12upx; |
|||
// background: #333333; |
|||
// opacity: 1; |
|||
// border-radius: 8upx; |
|||
// } |
|||
//} |
|||
//::v-deep .uni-swiper-dots{ |
|||
// display: flex; |
|||
// justify-content: center; |
|||
// padding: 0upx 0; |
|||
// .uni-swiper-dot{ |
|||
// width: 10upx; |
|||
// height: 10upx; |
|||
// background: #333333; |
|||
// opacity: 0.3; |
|||
// border-radius: 5upx; |
|||
// margin: 0 5upx; |
|||
// &-active{ |
|||
// width: 20upx; |
|||
// height: 10upx; |
|||
// opacity: 1; |
|||
// } |
|||
// } |
|||
//} |
|||
.swiper-dots { |
|||
display: flex; |
|||
position: absolute; |
|||
left: 50%; |
|||
transform: translateX(-50%); |
|||
bottom: 15rpx; |
|||
z-index: 66; |
|||
.dot { |
|||
width: 10upx; |
|||
height: 10upx; |
|||
background: #333333; |
|||
opacity: 0.3; |
|||
border-radius: 5upx; |
|||
margin: 0 10upx; |
|||
} |
|||
|
|||
.dot-active { |
|||
width: 20upx; |
|||
opacity: 1; |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,168 @@ |
|||
<template> |
|||
<div class="spike"> |
|||
<div class="spike-card" v-if="productData.products && productData.products.length>0"> |
|||
<div class="spike-card-top"> |
|||
<h2 class="spike-card-top-title"> |
|||
<!-- #ifdef MP-WEIXIN --> |
|||
<img class="title-img" src="../../../static/images/spike/img-title.png" alt="秒杀专区" mode="widthFix"/> |
|||
<!-- #endif --> |
|||
<!-- #ifdef H5 || APP-PLUS --> |
|||
<image class="title-img" src="../../../static/images/spike/img-title.png" alt="秒杀专区" mode="widthFix"/> |
|||
<!-- #endif --> |
|||
</h2> |
|||
<div class="spike-card-top-time" v-if="state===2"> |
|||
活动已结束 |
|||
</div> |
|||
<div class="spike-card-top-time" v-if="state !==2 && count.length"> |
|||
距离{{count[0]}}还有 <div class="span">{{count[1]}}:{{count[2]}}:{{count[3]}}</div> |
|||
</div> |
|||
<a class="btn-more" @click="jumpSeckills(productData)">更多<i class="iconfont icon-arrow-right"></i></a> |
|||
</div> |
|||
<div class="spike-card-list"> |
|||
<div class="spike-card-item" v-for='item in productData.products.slice(0,4)' :key='item.productId' @click="jumpProductDetail(item)"> |
|||
<div class="spike-card-item-img"> |
|||
<img :src="item.image" alt=""> |
|||
</div> |
|||
<div class="spike-card-item-info"> |
|||
<h3 class="name"> |
|||
{{item.productName}} |
|||
</h3> |
|||
<div class="stock"> |
|||
还剩{{item.stockNumber}}件 |
|||
</div> |
|||
<div class="price-warp"> |
|||
<div class="price"> |
|||
¥ {{item.price}} |
|||
</div> |
|||
<!-- <div class="original-price"> |
|||
¥ {{item.originalPrice}} |
|||
</div> --> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {commonMixin} from '../mixin' |
|||
export default { |
|||
mixins: [commonMixin] |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.spike{ |
|||
background: #F8F8F8; |
|||
padding: 20upx; |
|||
&-card{ |
|||
height: 430upx; |
|||
background: #FFFFFF; |
|||
border-radius: 20upx; |
|||
&-top{ |
|||
position: relative; |
|||
padding: 32upx 0 22upx; |
|||
display: flex; |
|||
&-title{ |
|||
padding: 9upx 20upx 9upx 30upx; |
|||
.title-img{ |
|||
width: 204upx; |
|||
display: block; |
|||
} |
|||
} |
|||
&-time{ |
|||
padding: 0 18upx; |
|||
height: 50upx; |
|||
background: linear-gradient(90deg, #C83732 0%, #E25C44 100%); |
|||
box-shadow: 0px 6upx 12upx rgba(233, 0, 0, 0.3); |
|||
opacity: 1; |
|||
border-radius: 26upx; |
|||
font-size: 24upx; |
|||
line-height: 50upx; |
|||
color: #fff; |
|||
text-align: center; |
|||
.span{ |
|||
display: inline; |
|||
} |
|||
} |
|||
.btn-more{ |
|||
position: absolute; |
|||
right: 8upx; |
|||
top: 40upx; |
|||
line-height: 33upx; |
|||
padding-right: 25upx; |
|||
font-size: 24upx; |
|||
color: #333; |
|||
.iconfont{ |
|||
content: ''; |
|||
font-size: 26upx; |
|||
position: absolute; |
|||
right: 0; |
|||
top: 0; |
|||
} |
|||
} |
|||
} |
|||
&-list{} |
|||
&-item{ |
|||
width: 50%; |
|||
border-top: 1px solid #F3F4F5; |
|||
border-left: 1px solid #F3F4F5; |
|||
float: left; |
|||
align-items: center; |
|||
box-sizing: border-box; |
|||
&:nth-child(2n+1){ |
|||
border-left: 0px; |
|||
} |
|||
&-img{ |
|||
width: 162upx; |
|||
height: 162upx; |
|||
margin-right: 10upx; |
|||
float: left; |
|||
img { |
|||
width: 100%; |
|||
height: 100%; |
|||
object-fit: contain; |
|||
} |
|||
} |
|||
&-info{ |
|||
height: 100%; |
|||
margin-left: 172upx; |
|||
width: 168upx; |
|||
.name{ |
|||
font-size: 24upx; |
|||
line-height: 40upx; |
|||
color: #333333; |
|||
overflow: hidden; |
|||
text-overflow:ellipsis; |
|||
white-space: nowrap; |
|||
} |
|||
.stock{ |
|||
padding: 0 8upx; |
|||
height: 40upx; |
|||
border: 2upx solid #E4E5E6; |
|||
line-height: 40upx; |
|||
margin: 10upx 0; |
|||
display: inline-block; |
|||
font-size: 20upx; |
|||
color: #C5AA7B; |
|||
} |
|||
.price{ |
|||
font-size: 32upx; |
|||
font-weight: bold; |
|||
line-height: 44upx; |
|||
color: #C83732; |
|||
padding-right: 10upx; |
|||
display: inline-block; |
|||
} |
|||
.original-price{ |
|||
font-size: 20upx; |
|||
line-height: 28upx; |
|||
color: #CCCCCC; |
|||
display: inline-block; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,137 @@ |
|||
import api from '../../config/api' |
|||
import {funMixin} from '../../config/mixin' |
|||
|
|||
export const commonMixin = { |
|||
name: 'spikeList', |
|||
mixins: [funMixin], |
|||
data () { |
|||
return { |
|||
productData: { |
|||
products: [] |
|||
}, |
|||
count: [], |
|||
state: 0, |
|||
timer: null |
|||
} |
|||
}, |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
typeId: { |
|||
type: Number, |
|||
default: 1 |
|||
}, |
|||
shopId: { |
|||
type: Number, |
|||
default: 0 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
}, |
|||
watch: { |
|||
'componentContent': { |
|||
handler(newVal, oldVal) { |
|||
this.getData() |
|||
}, |
|||
deep: true |
|||
} |
|||
}, |
|||
created() { |
|||
this.getData() |
|||
}, |
|||
methods: { |
|||
getData() { |
|||
const _ = this |
|||
if(_.componentContent.shopSeckillId){ |
|||
if(this.typeId === 1){ |
|||
const params = { |
|||
method: 'GET', |
|||
url: `${api.getPlatformSeckills}?ids=${_.componentContent.shopSeckillId}`, |
|||
} |
|||
this.sendReq(params, (res) => { |
|||
if(res.data.length> 0){ |
|||
_.productData = res.data[0] |
|||
_.productData.products.map(function(value){ |
|||
value.sliderVal = (value.stockNumber/value.total*100).toFixed(2) |
|||
return value; |
|||
}); |
|||
// 只有进行中和未开始活动, 用倒计时
|
|||
this.timer = setInterval(()=>{ |
|||
_.getTime(_.productData) |
|||
}, 1000) |
|||
} |
|||
}) |
|||
} |
|||
if(this.typeId === 3){ |
|||
const params = { |
|||
method: 'GET', |
|||
url: `${api.getSeckills}?shopId=${_.shopId}&ids=${_.componentContent.shopSeckillId}`, |
|||
} |
|||
this.sendReq(params, (res) => { |
|||
if(res.data.length> 0){ |
|||
_.productData = res.data[0] |
|||
_.productData.products.map(function(value){ |
|||
value.sliderVal = (value.stockNumber/value.total*100).toFixed(2) |
|||
return value; |
|||
}); |
|||
// 只有进行中和未开始活动, 用倒计时
|
|||
if(_.productData.state !==2) { |
|||
this.timer = setInterval(()=>{ |
|||
_.getTime(_.productData) |
|||
}, 1000) |
|||
} |
|||
} else { |
|||
_.productData = { |
|||
products:[] |
|||
} |
|||
} |
|||
}) |
|||
} |
|||
} else { |
|||
_.productData = { |
|||
products:[] |
|||
} |
|||
} |
|||
}, |
|||
getTime(info) { |
|||
const date = new Date().getTime() |
|||
let startTime = '' |
|||
let endTime = '' |
|||
if(this.typeId === 1){ |
|||
startTime = new Date(info.startTime.replace(/-/g,'/')).getTime() |
|||
endTime = new Date(info.endTime.replace(/-/g,'/')).getTime() |
|||
} else { |
|||
startTime = new Date(info.effectiveStart.replace(/-/g,'/')).getTime() |
|||
endTime = new Date(info.effectiveEnd.replace(/-/g,'/')).getTime() |
|||
} |
|||
if(date > endTime){ |
|||
this.state = 2 |
|||
} else if(startTime > date) { |
|||
this.state = 0 |
|||
this.countDown(startTime-date) // 未开始
|
|||
} else { |
|||
this.state = 1 |
|||
this.countDown(endTime-date) // 进行中
|
|||
} |
|||
|
|||
}, |
|||
|
|||
countDown(time) { |
|||
const fn = (v) => v < 10 ? `0${v}` : v |
|||
const t = parseInt(time / 1000) |
|||
const text = this.state == 0 ? '开始' : '结束' |
|||
const hour = parseInt(t / 3600) |
|||
const min = parseInt((t % 3600) / 60) |
|||
const s = t % 60 |
|||
// console.log(min, '分',t)
|
|||
this.count = [text, fn(hour), fn(min), fn(s)] |
|||
// console.log(text, fn(hour), fn(min), fn(s))
|
|||
} |
|||
}, |
|||
beforeDestroy() { |
|||
clearInterval(this.timer) |
|||
} |
|||
} |
@ -0,0 +1,211 @@ |
|||
<template> |
|||
<div class="spikeList" :class="'terminal'+terminal"> |
|||
<div class="warp" v-if="componentContent.shopSeckillId && productData"> |
|||
<div> |
|||
<div class="spikeCard"> |
|||
<div class="listLeft"> |
|||
<img src="../../../static/images/spike/bg-spike.png"> |
|||
<div class="bgBox"> |
|||
<div class="title"><img src="../../../static/images/spike/tit-spike.png" alt="秒杀专区"></div> |
|||
<div class="text">整点秒杀,数量有限</div> |
|||
<div class="sessions">{{productData.seckillName}} {{isStart && '倒计时'}}</div> |
|||
<div class="time-text">距离{{count[0]}}还有</div> |
|||
<div class="timeBox"> |
|||
<span>{{count[1]}}</span><i>:</i><span>{{count[2]}}</span><i>:</i><span>{{count[3]}}</span> |
|||
</div> |
|||
<button class="btn-more" @click="jumpSeckills(productData)">查看全部 <span class="icon iconfont icon-arrow-right"></span></button> |
|||
</div> |
|||
</div> |
|||
<div class="listRight"> |
|||
<div class="listItem" v-for='it in productData.products' :key='it.productId' @click="jumpProductDetail(it)"> |
|||
<div class="imgBox"> |
|||
<img :src="it.image" alt=""> |
|||
</div> |
|||
<div class="itemInfo"> |
|||
<h3>{{it.productName}}</h3> |
|||
<div class="begrenzt"> |
|||
<span class="people">还剩{{it.stockNumber}}件</span> |
|||
<div class="progress" :style="{'width':it.sliderVal + '%'}"></div> |
|||
</div> |
|||
<div class="originalPrice">¥{{it.originalPrice}}</div> |
|||
<dl class="discountPrice"> |
|||
<dt> |
|||
<img src="../../../static/images/spike/flag-spike.png" alt="秒杀价"> |
|||
</dt> |
|||
<dd> |
|||
<span>¥</span><b>{{it.price}}</b> |
|||
</dd> |
|||
</dl> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {commonMixin} from '../mixin' |
|||
export default { |
|||
mixins: [commonMixin] |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.spikeList{ |
|||
min-height: 100px; |
|||
&.terminal4{ |
|||
background-color: #F3F4F5; |
|||
.warp{ |
|||
width: 1200px; |
|||
} |
|||
.spikeCard { |
|||
display: flex; |
|||
width: 100%; |
|||
.listLeft { |
|||
width: 487px; |
|||
height: 758px; |
|||
text-align: center; |
|||
position: relative; |
|||
.bgBox { |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
.title{ |
|||
padding-top: 140px; |
|||
} |
|||
.text{ |
|||
color: #8E8D8C; |
|||
font-size: 30px; |
|||
line-height: 40px; |
|||
margin: 15px 0 100px 0; |
|||
} |
|||
.sessions{ |
|||
color: #FFEBC4; |
|||
font-size: 30px; |
|||
line-height: 40px; |
|||
} |
|||
.time-text{ |
|||
padding-top: 60px; |
|||
color: #FFEBC4; |
|||
font-size: 18px; |
|||
} |
|||
.timeBox { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
margin:10px 0 50px; |
|||
span { |
|||
display: block; |
|||
width: 60px; |
|||
height: 60px; |
|||
background: rgba(51,51,51,0.8); |
|||
color: #FFFFFF; |
|||
font-size: 30px; |
|||
line-height: 60px; |
|||
} |
|||
i { |
|||
font-size: 30px; |
|||
color: #fff; |
|||
font-style: normal; |
|||
font-weight: bold; |
|||
padding: 0 13px; |
|||
} |
|||
} |
|||
.btn-more { |
|||
width: 130px; |
|||
height: 41px; |
|||
border: 2px solid #FFEBC4; |
|||
color: #FFEBC4; |
|||
font-size: 18px; |
|||
background-color: transparent; |
|||
} |
|||
} |
|||
} |
|||
.listRight { |
|||
padding: 40px 0 0 8px; |
|||
.listItem { |
|||
float:left; |
|||
width: 220px; |
|||
height: 335px; |
|||
margin:0 0 15px 15px; |
|||
background-color: #fff; |
|||
.imgBox { |
|||
width: 220px; |
|||
height: 220px; |
|||
img { |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
} |
|||
.itemInfo { |
|||
position: relative; |
|||
padding: 10px; |
|||
text-align: center; |
|||
h3{ |
|||
font-size: 14px; |
|||
color: #333; |
|||
line-height: 18px; |
|||
overflow: hidden; |
|||
text-overflow:ellipsis; |
|||
white-space: nowrap; |
|||
} |
|||
.begrenzt{ |
|||
position: absolute; |
|||
left: 5px; |
|||
top: -35px; |
|||
width: 210px; |
|||
height: 30px; |
|||
border: 1px solid #C83732; |
|||
background-color: #C83732; |
|||
text-align: center; |
|||
.people{ |
|||
position: relative; |
|||
z-index: 2; |
|||
font-size: 12px; |
|||
color: #FFBAB8; |
|||
line-height: 30px; |
|||
} |
|||
.progress{ |
|||
position: absolute; |
|||
right: 0; |
|||
top: 0; |
|||
background-color: #fff; |
|||
height: 28px; |
|||
} |
|||
} |
|||
.discountPrice { |
|||
display: inline-block; |
|||
width: 130px; |
|||
dt{ |
|||
float: left; |
|||
} |
|||
dd{ |
|||
border: 1px solid #F3F4F5; |
|||
color: #C83732; |
|||
line-height: 30px; |
|||
font-weight: bold; |
|||
span { |
|||
font-size: 18px; |
|||
} |
|||
b { |
|||
font-size: 18px; |
|||
} |
|||
} |
|||
} |
|||
.originalPrice { |
|||
font-size: 14px; |
|||
line-height: 19px; |
|||
padding: 10px 0 6px; |
|||
color: #ccc; |
|||
text-decoration: line-through; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,79 @@ |
|||
<template> |
|||
<div class="text warp" :class="['text-'+componentContent.textPos,{'show-more':componentContent.showMore},'terminal' + terminal]" :style="{backgroundColor:componentContent.bgColor}"> |
|||
<div class="line-warp" :class="{'borderBot':componentContent.showLine}"> |
|||
<h3 class="h3" :style="{fontSize:componentContent.fontSizeNum+'px',fontWeight:componentContent.textFontW,color:componentContent.titColor}">{{componentContent.title}}</h3> |
|||
<p class="p" :style="{fontSize:componentContent.describeSizeNum+'px',fontWeight:componentContent.describeFontW,color:componentContent.describeColor}">{{componentContent.describe}}</p> |
|||
<div class="btn-more" v-show="componentContent.showMore" :class="'style'+componentContent.styleValue" @click="jumpLink(item.linkObj)"><span>查看更多</span><i class="iconfont icon-arrow-right"></i></div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'textComponent', |
|||
data () { |
|||
return { |
|||
} |
|||
}, |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.text{ |
|||
padding: 0 20upx; |
|||
position: relative; |
|||
.line-warp{ |
|||
padding: 10upx 0; |
|||
} |
|||
.borderBot{ |
|||
border-bottom: 1upx solid #cccc; |
|||
} |
|||
.h3{ |
|||
line-height: 1.5; |
|||
} |
|||
.p{ |
|||
line-height: 1.5; |
|||
margin-top: 5upx; |
|||
} |
|||
.style1{ |
|||
|
|||
} |
|||
.style2{ |
|||
.iconfont{ |
|||
display: none; |
|||
} |
|||
} |
|||
.style3{ |
|||
span{ |
|||
display: none; |
|||
} |
|||
} |
|||
&.text-left{ |
|||
text-align: left; |
|||
&.show-more{ |
|||
position: relative; |
|||
padding-right: 20upx; |
|||
.btn-more{ |
|||
position: absolute; |
|||
right: 0; |
|||
top: 10upx; |
|||
} |
|||
} |
|||
} |
|||
&.text-center{ |
|||
text-align: center; |
|||
} |
|||
&.text-right{ |
|||
text-align: right; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,120 @@ |
|||
<template> |
|||
<div class="videoBox warp" :class="'terminal' + terminal"> |
|||
<div class="videoLeftBox"> |
|||
<h3>{{componentContent.title}}</h3> |
|||
<div v-html="componentContent.mainBody"></div> |
|||
</div> |
|||
<div class="videoRightBox" v-if="componentContent.coverImg && isPlay"> |
|||
<video class="myVideo" id="myVideo" :src="componentContent.videoUrl" enable-danmu danmu-btn controls></video> |
|||
</div> |
|||
<div class="videoCoverBox" v-if="componentContent.coverImg && !isPlay" @click="handlePlayVideo"> |
|||
<image :src="componentContent.coverImg" ></image> |
|||
</div> |
|||
<div class="videoRightBox" v-if="!componentContent.coverImg"> |
|||
<video class="myVideo" id="myVideo" :src="componentContent.videoUrl" enable-danmu danmu-btn controls></video> |
|||
</div> |
|||
<div class="clear"></div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'videoBox', |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
}, |
|||
created(){ |
|||
console.log('componentContent',this.componentContent) |
|||
}, |
|||
mounted() { |
|||
this.videoContext = uni.createVideoContext('myVideo',this) |
|||
}, |
|||
data () { |
|||
return { |
|||
isPlay:false, |
|||
videoContext:null |
|||
} |
|||
}, |
|||
methods:{ |
|||
handlePlayVideo(){ |
|||
this.isPlay = true |
|||
setTimeout(()=>{ |
|||
this.videoContext.play() |
|||
},500) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.videoBox { |
|||
padding: 20upx 0; |
|||
display: flex; |
|||
justify-content: flex-start; |
|||
align-items: center; |
|||
.videoLeftBox { |
|||
width: 50%; |
|||
padding-right: 10%; |
|||
h3 { |
|||
font-size: 28upx; |
|||
color: #333333; |
|||
margin-bottom: 30upx; |
|||
} |
|||
p { |
|||
color: #333333; |
|||
font-size: 14upx; |
|||
line-height: 30upx; |
|||
} |
|||
} |
|||
.videoRightBox { |
|||
width: 50%; |
|||
video { |
|||
width: 100%; |
|||
} |
|||
} |
|||
.clear { |
|||
clear: both; |
|||
} |
|||
} |
|||
.terminal1,.terminal2,.terminal3{ |
|||
&.videoBox{ |
|||
display: block; |
|||
.videoLeftBox{ |
|||
width: 100%; |
|||
text-align: center; |
|||
margin-bottom: 20upx; |
|||
} |
|||
.videoRightBox { |
|||
width: 100%; |
|||
} |
|||
} |
|||
} |
|||
.videoCoverBox{ |
|||
aspect-ratio: 16/9; |
|||
position: relative; |
|||
&:before{ |
|||
content: ''; |
|||
width: 0rpx; |
|||
height: 0rpx; |
|||
border-left:80rpx solid #fff; |
|||
border-right:50rpx solid transparent; |
|||
border-top:50rpx solid transparent; |
|||
border-bottom:50rpx solid transparent; |
|||
position: absolute; |
|||
top: 50%; |
|||
left: 50%; |
|||
transform: translate(-30%,-50%); |
|||
z-index: 99; |
|||
} |
|||
image{ |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,319 @@ |
|||
<template> |
|||
<div class="vip"> |
|||
<div class="vip-card"> |
|||
<div class="vip-title"> |
|||
<!-- #ifdef MP-WEIXIN --> |
|||
<img class="title-img" src="../../../static/images/vip/img-title.png" alt="会员专区" mode="widthFix"/> |
|||
<!-- #endif --> |
|||
<!-- #ifdef H5 || APP-PLUS --> |
|||
<image class="title-img" src="../../../static/images/vip/img-title.png" alt="会员专区" mode="widthFix"/> |
|||
<!-- #endif --> |
|||
<a v-show="componentContent.showMore" class="btn-more a-link" @click="jumpVip">更多<i class="iconfont icon-arrow-right"></i></a> |
|||
</div> |
|||
<div> |
|||
<div v-if="productData.length > 2"> |
|||
<swiper class="swiper vip-list" :circular="true" :indicator-dots="false" :autoplay="true" @change="swiperChange"> |
|||
<swiper-item class="vip-item-warp" v-for="(itemJ,indexJ) in listTemp" :key="indexJ"> |
|||
<div class="vip-item" v-for="(item,index) in itemJ" :key="index" @click="jumpProductDetail(item)"> |
|||
<div class="vip-item-img"> |
|||
<image class="img default-img" :src="item.image"></image> |
|||
</div> |
|||
<div class="vip-item-info"> |
|||
<h3 class="name"> |
|||
{{item.productName}} |
|||
</h3> |
|||
<div class="stock"> |
|||
还剩{{item.stockNumber}}件 |
|||
</div> |
|||
<div class="original-price"> |
|||
¥ {{item.originalPrice}} |
|||
</div> |
|||
<div class="price-warp"> |
|||
<div class="flag"> |
|||
<!-- #ifdef MP-WEIXIN --> |
|||
<img src="../../../static/images/vip/flag-vip.png" alt="会员价" class="flagImg"/> |
|||
<!-- #endif --> |
|||
<!-- #ifdef H5 || APP-PLUS --> |
|||
<image class="flagImg" src="../../../static/images/vip/flag-vip.png" alt="会员专区" mode="widthFix"/> |
|||
<!-- #endif --> |
|||
</div> |
|||
<div class="price"> |
|||
¥ {{item.price}} |
|||
</div> |
|||
</div> |
|||
<div class="btn-buy"> |
|||
<span>去购买</span> |
|||
<div class="progress"> |
|||
<i></i> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</swiper-item> |
|||
</swiper> |
|||
<view class="swiper-dots" v-if="listTemp && listTemp.length > 1"> |
|||
<text class="dot" :class="swiperCurrent === index && 'dot-active'" v-for="(dot, index) in listTemp.length" |
|||
:key="index"></text> |
|||
</view> |
|||
</div> |
|||
<div class="swiper vip-list" v-else> |
|||
<div class="vip-item-warp" v-for="(itemJ,indexJ) in listTemp" :key="indexJ"> |
|||
<div class="vip-item" v-for="(item,index) in itemJ" :key="index" @click="jumpProductDetail(item)"> |
|||
<div class="vip-item-img"> |
|||
<img class="img default-img" :src="item.image"> |
|||
</div> |
|||
<div class="vip-item-info"> |
|||
<h3 class="name"> |
|||
{{item.productName}} |
|||
</h3> |
|||
<div class="stock"> |
|||
还剩{{item.stockNumber}}件 |
|||
</div> |
|||
<div class="original-price"> |
|||
¥ {{item.originalPrice}} |
|||
</div> |
|||
<div class="price-warp"> |
|||
<div class="flag"> |
|||
<!-- #ifdef MP-WEIXIN --> |
|||
<img src="../../../static/images/vip/flag-vip.png" alt="会员价" class="flagImg"/> |
|||
<!-- #endif --> |
|||
<!-- #ifdef H5 || APP-PLUS --> |
|||
<image class="flagImg" src="../../../static/images/vip/flag-vip.png" alt="会员专区" mode="widthFix"/> |
|||
<!-- #endif --> |
|||
</div> |
|||
<div class="price"> |
|||
¥ {{item.price}} |
|||
</div> |
|||
</div> |
|||
<div class="btn-buy"> |
|||
<span>去购买</span> |
|||
<div class="progress"> |
|||
<i></i> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<!-- <div class="pagination vip-pagination"></div>--> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {commonMixin} from '../mixin' |
|||
export default { |
|||
mixins: [commonMixin], |
|||
data () { |
|||
return { |
|||
swiperCurrent: 0, |
|||
} |
|||
}, |
|||
computed: { |
|||
listTemp: function () { |
|||
var list = this.productData; |
|||
var arrTemp = []; |
|||
var index = -1; |
|||
var count = 2; // 每组多少条 |
|||
for (var i = 0; i < list.length; i++) { |
|||
if (i % count==0) { |
|||
arrTemp.push([]); |
|||
index ++ |
|||
} |
|||
arrTemp[index].push(list[i]); |
|||
} |
|||
return arrTemp; |
|||
} |
|||
}, |
|||
methods:{ |
|||
swiperChange(e) { |
|||
this.swiperCurrent = e.detail.current; |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.vip{ |
|||
&-card{ |
|||
background: #333333; |
|||
padding: 0 20upx 20upx; |
|||
position: relative; |
|||
} |
|||
&-title{ |
|||
padding: 42upx 0 28upx 30upx; |
|||
position: relative; |
|||
.title-img{ |
|||
display: block; |
|||
width: 197upx; |
|||
} |
|||
.btn-more{ |
|||
position: absolute; |
|||
right: 8upx; |
|||
top: 40upx; |
|||
line-height: 33upx; |
|||
padding-right: 25upx; |
|||
font-size: 24upx; |
|||
color: #FFEBC4; |
|||
.iconfont{ |
|||
content: ''; |
|||
font-size: 26upx; |
|||
position: absolute; |
|||
right: 0; |
|||
top: 0; |
|||
} |
|||
} |
|||
} |
|||
&-list{ |
|||
height: 562upx; |
|||
} |
|||
&-item{ |
|||
display: flex; |
|||
background-color: #fff; |
|||
margin-top: 20upx; |
|||
&:first-child{ |
|||
margin-top: 0upx; |
|||
} |
|||
&-img{ |
|||
width: 260upx; |
|||
height: 260upx; |
|||
margin-right: 20upx; |
|||
background-color: #ececec; |
|||
.img { |
|||
width: 100%; |
|||
height: 100%; |
|||
object-fit: contain; |
|||
display: block; |
|||
} |
|||
} |
|||
&-info{ |
|||
flex: 1; |
|||
position: relative; |
|||
.name{ |
|||
font-size: 28upx; |
|||
//height: 75rpx; |
|||
line-height: 40upx; |
|||
color: #333333; |
|||
margin: 30upx 0 10upx; |
|||
overflow:hidden; |
|||
text-overflow:ellipsis; |
|||
display:-webkit-box; |
|||
-webkit-box-orient:vertical; |
|||
-webkit-line-clamp:1; |
|||
} |
|||
// #ifdef H5 || APP-PLUS |
|||
.name{ |
|||
height: 40rpx; |
|||
} |
|||
// #endif |
|||
.stock{ |
|||
color: #C5AA7B; |
|||
font-size: 20upx; |
|||
border: 2upx solid #E4E5E6; |
|||
line-height: 40upx; |
|||
padding: 0 5upx; |
|||
display: inline-block; |
|||
margin-bottom: 30upx; |
|||
} |
|||
.original-price{ |
|||
font-size: 24upx; |
|||
line-height: 34upx; |
|||
color: #CCCCCC; |
|||
text-decoration: line-through; |
|||
} |
|||
.flag{ |
|||
float: left; |
|||
padding: 12upx 10upx 0 0; |
|||
.flagImg { |
|||
width: 58upx; |
|||
height: 36upx; |
|||
display: block; |
|||
} |
|||
} |
|||
.price{ |
|||
font-size: 40upx; |
|||
font-weight: bold; |
|||
line-height: 56upx; |
|||
color: #C83732; |
|||
} |
|||
.btn-buy{ |
|||
position: absolute; |
|||
right: 20upx; |
|||
bottom: 20upx; |
|||
width: 160upx; |
|||
height: 84upx; |
|||
background: linear-gradient(90deg, #C83732 0%, #E25C44 100%); |
|||
box-shadow: 0px 6upx 12upx rgba(233, 0, 0, 0.3); |
|||
border-radius: 10upx; |
|||
text-align: center; |
|||
padding: 16upx 20upx 0; |
|||
span{ |
|||
font-size: 24upx; |
|||
line-height: 34upx; |
|||
color: #FFFFFF; |
|||
margin-bottom: 10upx; |
|||
display: block; |
|||
} |
|||
.progress{ |
|||
height: 8upx; |
|||
background: rgba(255,255,255,0.5); |
|||
border-radius: 4upx; |
|||
position: relative; |
|||
i{ |
|||
position: absolute; |
|||
left: 0; |
|||
top: 0; |
|||
width: 50%; |
|||
height: 8upx; |
|||
background-color: #fff; |
|||
border-radius: 4upx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.vip-item-info { |
|||
.price-warp { |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
} |
|||
.swiper-dots { |
|||
display: flex; |
|||
position: absolute; |
|||
left: 50%; |
|||
transform: translateX(-50%); |
|||
bottom: 15upx; |
|||
z-index: 66; |
|||
.dot { |
|||
width: 24upx; |
|||
height: 4upx; |
|||
background: #fff; |
|||
opacity: 0.5; |
|||
border-radius: 2upx; |
|||
margin: 0 10upx; |
|||
} |
|||
|
|||
.dot-active { |
|||
opacity: 1; |
|||
} |
|||
} |
|||
//.pagination{ |
|||
// display: flex; |
|||
// justify-content: center; |
|||
// padding-top:20upx; |
|||
// ::v-deep .swiper-pagination-bullet{ |
|||
// width: 24upx; |
|||
// height: 4upx; |
|||
// background: #fff; |
|||
// opacity: 0.5; |
|||
// border-radius: 2upx; |
|||
// margin: 0 5upx; |
|||
// } |
|||
// ::v-deep .swiper-pagination-bullet-active{ |
|||
// opacity: 1; |
|||
// } |
|||
//} |
|||
} |
|||
</style> |
@ -0,0 +1,60 @@ |
|||
// import { directive, Swiper, SwiperSlide } from 'vue-awesome-swiper'
|
|||
// import 'swiper/css/swiper.css'
|
|||
import api from '../../config/api' |
|||
import {funMixin} from '../../config/mixin' |
|||
|
|||
export const commonMixin = { |
|||
name: 'productList', |
|||
mixins: [funMixin], |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
typeId: { |
|||
type: Number, |
|||
default: 1 |
|||
}, |
|||
shopId: { |
|||
type: Number, |
|||
default: 0 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
}, |
|||
// components: {
|
|||
// Swiper,
|
|||
// SwiperSlide
|
|||
// },
|
|||
// directives: {
|
|||
// swiper: directive
|
|||
// },
|
|||
data () { |
|||
return { |
|||
productData: [] |
|||
} |
|||
}, |
|||
watch: { |
|||
'componentContent': { |
|||
handler(newVal, oldVal) { |
|||
this.getData() |
|||
}, |
|||
deep: true |
|||
} |
|||
}, |
|||
created() { |
|||
this.getData() |
|||
}, |
|||
methods: { |
|||
getData() { |
|||
const _ = this |
|||
_.sendReq({ |
|||
url: `${api.getMemberProducts}?page=1&pageSize=20`, |
|||
method: 'GET' |
|||
}, (proRes) => { |
|||
_.productData = proRes.data.list |
|||
}) |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,241 @@ |
|||
<template> |
|||
<div class="product-list" :class="'terminal'+terminal"> |
|||
<div class="picListWarp" v-if="componentContent.arrangeType == '横向滑动'"> |
|||
<div class="picList" v-if="productData && productData.length>0"> |
|||
<div class="vip-button-prev"></div> |
|||
<div class="vip-button-next"></div> |
|||
<swiper class="products-swiper" :options="swiperOption"> |
|||
<swiper-slide class="products-swiper-slide item" v-for="(item,index) in productData" :key="index"> |
|||
<div class="a-link" @click="jumpProductDetail(item)"> |
|||
<div class="itemImgBox"> |
|||
<div class="imgBox"> |
|||
<el-image |
|||
:src="item.image" |
|||
fit="contain"></el-image> |
|||
</div> |
|||
</div> |
|||
<div class="text"> |
|||
<h4 class="h4">{{item.productName}}</h4> |
|||
<div class="priceBox"> |
|||
<dl> |
|||
<dt><img src="../../../static/images/vip/flag-vip.png" alt="会员价"></dt> |
|||
<dd> |
|||
¥{{item.price}} |
|||
</dd> |
|||
</dl> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</swiper-slide> |
|||
</swiper> |
|||
</div> |
|||
</div> |
|||
<div v-else class="picList" > |
|||
<ul class="clearfix" :class="'imgTextNum' + componentContent.productNum"> |
|||
<li class="item" v-for="(item,index) in productData.slice(0, componentContent.productRowNum * componentContent.productNum)" :key="index"> |
|||
<div class="a-link" @click="jumpProductDetail(item)"> |
|||
<div class="itemImgBox"> |
|||
<div class="imgBox"> |
|||
<el-image |
|||
:src="item.image" |
|||
fit="contain"></el-image> |
|||
</div> |
|||
</div> |
|||
<div class="text"> |
|||
<h4 class="h4">{{item.productName}}</h4> |
|||
<div class="priceBox"> |
|||
<dl> |
|||
<dt><img src="../../../static/images/vip/flag-vip.png" alt="会员价"></dt> |
|||
<dd> |
|||
¥{{item.price}} |
|||
</dd> |
|||
</dl> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</li> |
|||
</ul> |
|||
</div> |
|||
<button v-show="componentContent.showMore" class="btn-more" @click="jumpVip">查看全部 <span class="icon iconfont icon-arrow-right"></span></button> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {commonMixin} from '../mixin' |
|||
export default { |
|||
mixins: [commonMixin], |
|||
data () { |
|||
return { |
|||
swiperOption: { |
|||
slidesPerView: 4, // 显示数量 |
|||
spaceBetween: 13, // 间隔 |
|||
autoplay: false, // 可选选项,自动滑动 |
|||
loop: true, |
|||
pagination: { |
|||
el: '.vip-pagination' |
|||
}, |
|||
navigation: { |
|||
nextEl: '.vip-button-next', |
|||
prevEl: '.vip-button-prev' |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.product-list{ |
|||
padding: 20px 0; |
|||
background-color: #fff; |
|||
.picListWarp{ |
|||
width: 1380px; |
|||
max-width: 100%; |
|||
margin: 0 auto; |
|||
position: relative; |
|||
} |
|||
.picList{ |
|||
width: 1200px; |
|||
max-width: 100%; |
|||
margin: 0 auto; |
|||
.vip-button-prev,.vip-button-next{ |
|||
width: 50px; |
|||
height: 50px; |
|||
position: absolute; |
|||
cursor:pointer; |
|||
top: 140px; |
|||
background-repeat: no-repeat; |
|||
&:after{ |
|||
content: ''; |
|||
} |
|||
} |
|||
.vip-button-prev{ |
|||
left: 0; |
|||
background: url('../../../static/images/btn-prev.png'); |
|||
} |
|||
.vip-button-next{ |
|||
right: 0; |
|||
background: url('../../../static/images/btn-next.png'); |
|||
} |
|||
.a-link{ |
|||
cursor: pointer; |
|||
&:hover{ |
|||
box-shadow: 3px 4px 20px 0px rgba(186, 186, 186, 0.5); |
|||
} |
|||
.itemImgBox { |
|||
height: auto; |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: center; |
|||
.imgBox { |
|||
padding-bottom: 100%; |
|||
background-color: #cacaca; |
|||
position: relative; |
|||
.el-image { |
|||
width: 100%; |
|||
height: 100%; |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
} |
|||
} |
|||
} |
|||
.text{ |
|||
padding:25px 20px 17px; |
|||
text-align: center; |
|||
//height: 180px; |
|||
.h4{ |
|||
font-size: 18px; |
|||
line-height: 24px; |
|||
overflow: hidden; |
|||
text-overflow:ellipsis; |
|||
white-space: nowrap; |
|||
color: #333333; |
|||
margin-bottom: 15px; |
|||
//max-height: 48px; |
|||
} |
|||
.p{ |
|||
color: #999; |
|||
font-size: 16px; |
|||
overflow: hidden; |
|||
text-overflow:ellipsis; |
|||
white-space: nowrap; |
|||
padding-top: 18px; |
|||
position: relative; |
|||
margin-top: 8px; |
|||
&:after{ |
|||
position: absolute; |
|||
top: 0; |
|||
left: 50%; |
|||
margin-left: -80px; |
|||
width: 160px; |
|||
height: 2px; |
|||
background: #F0F0F0; |
|||
content: ''; |
|||
} |
|||
} |
|||
.priceBox { |
|||
dl { |
|||
display: inline-block; |
|||
min-width: 130px; |
|||
dt{ |
|||
float: left; |
|||
img{ |
|||
display: block; |
|||
} |
|||
} |
|||
dd{ |
|||
border: 1px solid #F3F4F5; |
|||
font-size: 25px; |
|||
line-height: 34px; |
|||
color: #C83732; |
|||
margin-left: 57px; |
|||
padding: 0 10px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
ul{ |
|||
margin: -15px 0 0 -15px; |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
li{ |
|||
flex: 0 0 50%; |
|||
padding: 15px 0 0 15px; |
|||
width: 0; |
|||
} |
|||
} |
|||
.imgTextNum2 { |
|||
li { |
|||
flex: 0 0 50%; |
|||
} |
|||
} |
|||
.imgTextNum3 { |
|||
li { |
|||
flex: 0 0 33.33%; |
|||
} |
|||
} |
|||
.imgTextNum4 { |
|||
li { |
|||
flex: 0 0 25%; |
|||
} |
|||
} |
|||
.imgTextNum5 { |
|||
li { |
|||
flex: 0 0 20%; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.btn-more { |
|||
width: 130px; |
|||
height: 41px; |
|||
border: 2px solid #C5AA7B; |
|||
color: #C5AA7B; |
|||
font-size: 18px; |
|||
background-color: transparent; |
|||
margin: 20px auto 0; |
|||
display: block; |
|||
} |
|||
</style> |
@ -0,0 +1,226 @@ |
|||
<template> |
|||
<div class="layout hom-layout"> |
|||
<div class="list-group-item" |
|||
v-for="(item,index) in componentsData" |
|||
:key="index"> |
|||
<!-- <component :is="componentMap[terminal-1].get(item.type)" :componentContent="item.componentContent" :terminal="terminal" :typeId="typeId" :shopId="shopId"></component>--> |
|||
<com-banner v-if="item.type==='banner'" |
|||
:componentContent="item.componentContent" |
|||
:terminal="terminal" |
|||
:typeId="typeId" |
|||
:shopId="shopId"></com-banner> |
|||
<com-text v-if="item.type==='text'" |
|||
:componentContent="item.componentContent" |
|||
:terminal="terminal" |
|||
:typeId="typeId" |
|||
:shopId="shopId"></com-text> |
|||
<com-image-text v-if="item.type==='imageText'" |
|||
:componentContent="item.componentContent" |
|||
:terminal="terminal" |
|||
:typeId="typeId" |
|||
:shopId="shopId"></com-image-text> |
|||
<com-brand-list v-if="item.type==='brandList'" |
|||
:componentContent="item.componentContent" |
|||
:terminal="terminal" |
|||
:typeId="typeId" |
|||
:shopId="shopId"></com-brand-list> |
|||
<com-category-list v-if="item.type==='categoryList'" |
|||
:componentContent="item.componentContent" |
|||
:terminal="terminal" |
|||
:typeId="typeId" |
|||
:shopId="shopId"></com-category-list> |
|||
<com-image-text-list v-if="item.type==='imageTextList'" |
|||
:componentContent="item.componentContent" |
|||
:terminal="terminal" |
|||
:typeId="typeId" |
|||
:shopId="shopId"></com-image-text-list> |
|||
<com-assist-div v-if="item.type==='assistDiv'" |
|||
:componentContent="item.componentContent" |
|||
:terminal="terminal" |
|||
:typeId="typeId" |
|||
:shopId="shopId"></com-assist-div> |
|||
<com-image-text-nav v-if="item.type==='imageTextNav'" |
|||
:componentContent="item.componentContent" |
|||
:terminal="terminal" |
|||
:typeId="typeId" |
|||
:shopId="shopId"></com-image-text-nav> |
|||
<com-product v-if="item.type==='productList'" |
|||
ref="productPage" |
|||
:componentContent="item.componentContent" |
|||
:terminal="terminal" |
|||
:typeId="typeId" |
|||
:shopId="shopId"></com-product> |
|||
<com-video-box v-if="item.type==='videoBox'" |
|||
:componentContent="item.componentContent" |
|||
:terminal="terminal" |
|||
:typeId="typeId" |
|||
:shopId="shopId"></com-video-box> |
|||
<com-coupon v-if="item.type==='coupon'" |
|||
:componentContent="item.componentContent" |
|||
:terminal="terminal" |
|||
:typeId="typeId" |
|||
:shopId="shopId"></com-coupon> |
|||
<com-custom v-if="item.type==='custom'" |
|||
:componentContent="item.componentContent" |
|||
:terminal="terminal" |
|||
:typeId="typeId" |
|||
:shopId="shopId"></com-custom> |
|||
<com-notice v-if="item.type==='notice'" |
|||
:componentContent="item.componentContent" |
|||
:terminal="terminal" |
|||
:typeId="typeId" |
|||
:shopId="shopId"></com-notice> |
|||
<com-vip v-if="item.type==='vip'" |
|||
:componentContent="item.componentContent" |
|||
:terminal="terminal" |
|||
:typeId="typeId" |
|||
:shopId="shopId"></com-vip> |
|||
<com-group v-if="item.type==='groupList'" |
|||
:componentContent="item.componentContent" |
|||
:terminal="terminal" |
|||
:typeId="typeId" |
|||
:shopId="shopId"></com-group> |
|||
<com-discount v-if="item.type==='discountList'" |
|||
:componentContent="item.componentContent" |
|||
:terminal="terminal" |
|||
:typeId="typeId" |
|||
:shopId="shopId"></com-discount> |
|||
<com-spike v-if="item.type==='spikeList'" |
|||
:componentContent="item.componentContent" |
|||
:terminal="terminal" |
|||
:typeId="typeId" |
|||
:shopId="shopId"></com-spike> |
|||
<com-price v-if="item.type==='priceList'" |
|||
:componentContent="item.componentContent" |
|||
:terminal="terminal" |
|||
:typeId="typeId" |
|||
:shopId="shopId"></com-price> |
|||
<com-new-product v-if="item.type==='newProduct'" |
|||
:componentContent="item.componentContent" |
|||
:terminal="terminal" |
|||
:typeId="typeId" |
|||
:shopId="shopId"></com-new-product> |
|||
<com-shop v-if="item.type==='shop'" |
|||
:componentContent="item.componentContent" |
|||
:terminal="terminal" |
|||
:typeId="typeId" |
|||
:shopId="shopId"></com-shop> |
|||
<com-live v-if="item.type==='live'" |
|||
:componentContent="item.componentContent" |
|||
:terminal="terminal" |
|||
:typeId="typeId" |
|||
:shopId="shopId"></com-live> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
// import comComponentMap from './componentMap' |
|||
|
|||
import comBanner from '@/components/canvasShow/basics/banner' |
|||
import comText from '@/components/canvasShow/basics/text' |
|||
import comImageText from '@/components/canvasShow/basics/imageText' |
|||
import comBrandList from '@/components/canvasShow/basics/brandList' |
|||
import comCategoryList from '@/components/canvasShow/basics/categoryList' |
|||
import comImageTextList from '@/components/canvasShow/basics/imageTextList' |
|||
import comAssistDiv from '@/components/canvasShow/basics/assistDiv' |
|||
import comImageTextNav from '@/components/canvasShow/basics/imageTextNav' |
|||
import comProduct from '@/components/canvasShow/basics/product/app/index' |
|||
import comVideoBox from '@/components/canvasShow/basics/video' |
|||
import comCoupon from '@/components/canvasShow/basics/coupon/app' |
|||
import comCustom from '@/components/canvasShow/basics/custom' |
|||
import comNotice from '@/components/canvasShow/basics/notice' |
|||
import comVip from '@/components/canvasShow/basics/vip/app' |
|||
import comGroup from '@/components/canvasShow/basics/group/app/index' |
|||
import comDiscount from '@/components/canvasShow/basics/discount/app' |
|||
import comSpike from '@/components/canvasShow/basics/spike/app' |
|||
import comPrice from '@/components/canvasShow/basics/price/app' |
|||
import comNewProduct from '@/components/canvasShow/basics/newProduct/app' |
|||
import comShop from '@/components/canvasShow/basics/shop' |
|||
import comLive from '@/components/canvasShow/basics/live/app' |
|||
import {sendReqMixin} from './config/mixin' |
|||
|
|||
export default { |
|||
name: 'canvasPage', |
|||
mixins: [sendReqMixin], |
|||
data() { |
|||
return { |
|||
// terminal: 4, // 画布设备 1 小程序,2 H5,3 App 4 电脑 |
|||
// typeId: 3, // 画布类型 1 平台画布,2 自定义页面,3 商家店铺装修 |
|||
// shopId: 0, // 店铺id |
|||
// componentsData: [], |
|||
// componentMap: componentMap |
|||
} |
|||
}, |
|||
components: { |
|||
comBanner, |
|||
comText, |
|||
comImageText, |
|||
comBrandList, |
|||
comCategoryList, |
|||
comImageTextList, |
|||
comAssistDiv, |
|||
comImageTextNav, |
|||
comProduct, |
|||
comVideoBox, |
|||
comCoupon, |
|||
comCustom, |
|||
comGroup, |
|||
comDiscount, |
|||
comSpike, |
|||
comPrice, |
|||
comNotice, |
|||
comVip, |
|||
comNewProduct, |
|||
comShop, |
|||
comLive |
|||
}, |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
typeId: { |
|||
type: Number, |
|||
default: 1 |
|||
}, |
|||
shopId: { |
|||
type: Number, |
|||
default: 0 |
|||
}, |
|||
componentsData: { |
|||
type: Array, |
|||
default: ()=>[] |
|||
} |
|||
}, |
|||
methods: { |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" |
|||
scoped> |
|||
.hom-layout { |
|||
background-color: #ffffff; |
|||
width: 100%; |
|||
overflow: hidden; |
|||
} |
|||
</style> |
|||
|
|||
<style lang="scss"> |
|||
.warp { |
|||
width: 710upx; |
|||
margin: 0 auto; |
|||
max-width: 100%; |
|||
|
|||
&.terminal4 { |
|||
width: 1200px; |
|||
max-width: 100%; |
|||
} |
|||
} |
|||
|
|||
.flex-box { |
|||
display: flex; |
|||
} |
|||
</style> |
@ -0,0 +1,32 @@ |
|||
// 导入api接口模块
|
|||
|
|||
// 获取当前环境变量 true => 生产环境 false => 开发环境
|
|||
// const BASEURL = process.env.VUE_APP_DOMAIN_PREFIX
|
|||
const BASEURL = (process.env.NODE_ENV === 'production') ? 'https://ceres.zkthink.com/api' : 'https://ceres.zkthink.com/api' |
|||
// const BASEURL = (process.env.NODE_ENV === 'production') ? 'http://127.0.0.1:9007' : 'http://127.0.0.1:9007'
|
|||
|
|||
|
|||
export const api = { |
|||
// 画布模块
|
|||
fileUpload: BASEURL + '/file/upload', // 文件上传
|
|||
getClassify: BASEURL + '/canvas/getClassify', // 查询分类层级
|
|||
getProducts: BASEURL + '/canvas/getProducts', // 选择商品查询
|
|||
saveCanvas: BASEURL + '/canvas/saveCanvas', // 保存画布
|
|||
getCanvas: BASEURL + '/canvas/getCanvas', // 读取画布
|
|||
getShops: BASEURL + '/canvas/getShops', // 选择店铺查询
|
|||
getCoupons: BASEURL + '/canvas/getCoupons', // 优惠券查询
|
|||
getShopCoupons: BASEURL + '/canvas/getShopCoupons', // 优惠券查询
|
|||
takeCoupon: BASEURL + '/coupon/takeCoupon', // 领取优惠券
|
|||
selectCanvasCustomList: BASEURL + '/canvas/selectCanvasCustomList', // 自定义页面查询
|
|||
getPlatformSeckills: `${BASEURL}/canvas/getPlatformSeckills`, // 平台秒杀活动
|
|||
getSeckills: `${BASEURL}/renovation/getSeckills`, // 商家秒杀活动
|
|||
getMinDiscount: `${BASEURL}/canvas/getMinDiscount`, // 平台限时折扣
|
|||
getDiscounts: `${BASEURL}/renovation/getDiscounts`, // 商家限时折扣
|
|||
getAdminGroupWorks: `${BASEURL}/canvas/getGroupWorks`, // 平台拼团专区
|
|||
getGroupWorks: `${BASEURL}/renovation/getGroupWorks`, // 商家拼团专区
|
|||
getPriceProducts: `${BASEURL}/canvas/getPriceProducts`, // 商家定价捆绑
|
|||
getPrices: `${BASEURL}/canvas/getPrices`, // 商家定价捆绑
|
|||
getMemberProducts: `${BASEURL}/canvas/getMemberProducts`, // 查询会员商品数据
|
|||
getNotices: `${BASEURL}/canvas/getNotices`, // 平台获取公告数据
|
|||
} |
|||
export default api |
@ -0,0 +1,12 @@ |
|||
// 画布配置
|
|||
// import Cookies from 'js-cookie'
|
|||
|
|||
const config = { |
|||
// terminal: 4, // 画布设备 1 小程序,2 H5,3 App 4 电脑
|
|||
typeId: 0, // 页面类型 0 C端 1 平台画布,2 自定义页面,3 商家店铺装修
|
|||
getToken: function(){ |
|||
return uni.getStorageSync('storage_key').token |
|||
} |
|||
} |
|||
|
|||
export default config |
@ -0,0 +1,204 @@ |
|||
// import router from '@/router'
|
|||
import api from '../api' |
|||
import {sendReq} from './sendReqMixin' |
|||
import { mapMutations } from 'vuex' |
|||
import canvasConfig from '../config' |
|||
/* |
|||
* 公共方法的 mixin |
|||
*/ |
|||
export const tool = { |
|||
mixins: [sendReq], |
|||
props: { |
|||
isNoData: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
comType: { |
|||
type: String, |
|||
default: '' |
|||
} |
|||
}, |
|||
mounted() { |
|||
// console.log('加载了组件')
|
|||
}, |
|||
methods: { |
|||
...mapMutations({ |
|||
setCurrentPro: 'SET_CURRENTPRO' |
|||
}), |
|||
// 判断url
|
|||
jumpLink (linkObj) { |
|||
var link = '' |
|||
console.log(linkObj.data) |
|||
if(linkObj && linkObj.typeText && linkObj.data){ |
|||
switch (linkObj.typeText) { |
|||
case '类别': |
|||
this.jumpCategory(linkObj.data) |
|||
break |
|||
case '店辅': |
|||
this.jumpStore(linkObj.data) |
|||
break |
|||
case '商品': |
|||
this.jumpProductDetail(linkObj.data) |
|||
break |
|||
case '自定义': |
|||
// router.push("/category");
|
|||
case '公告': |
|||
this.jumpNoticeDetail(linkObj.data) |
|||
break |
|||
} |
|||
} else if(linkObj.selsectValue==='/index'){ |
|||
uni.navigateTo({ |
|||
url: `/pages/index/index` |
|||
}) |
|||
} |
|||
return link |
|||
}, |
|||
// 跳转到类别主页
|
|||
jumpCategory(item){ |
|||
uni.navigateTo({ |
|||
url: `/pages_category_page1/goodsModule/goodsList?category3Id=${item.id}` |
|||
}) |
|||
}, |
|||
// 跳转到产品列表
|
|||
jumpProList(item){ |
|||
if(item.sourceType === '1'){ |
|||
uni.navigateTo({ |
|||
url: `/pages_category_page1/goodsModule/canvasGoods?sourceType=${item.sourceType}&ids=${item.productIdList}` |
|||
}) |
|||
} else if(item.sourceType === '2'){ |
|||
uni.navigateTo({ |
|||
url: `/pages_category_page1/goodsModule/canvasGoods?sourceType=${item.sourceType}&classifyId=${item.categoryId}` |
|||
}) |
|||
} |
|||
}, |
|||
// 跳转到店铺主页
|
|||
jumpStore(item){ |
|||
uni.navigateTo({ |
|||
url: `/pages_category_page1/store/index?storeId=${item.shopId}` |
|||
}) |
|||
}, |
|||
// 跳转到商品详情
|
|||
jumpProductDetail(item){ |
|||
uni.navigateTo({ |
|||
url: '/pages_category_page1/goodsModule/goodsDetails?shopId=' + item.shopId + '&productId=' + item.productId + '&skuId=' + item |
|||
.skuId |
|||
}) |
|||
}, |
|||
// 跳转到秒杀专区
|
|||
jumpSeckills(item){ |
|||
if(item.shopId){ |
|||
uni.navigateTo({ |
|||
url: '/pages_category_page1/discount/spikeList?shopId=' + item.shopId + '&shopSeckillId=' + item.shopSeckillId |
|||
}) |
|||
} else { |
|||
uni.navigateTo({ |
|||
url: '/pages_category_page1/discount/spikeList' |
|||
}) |
|||
} |
|||
}, |
|||
// 跳转到拼团专区
|
|||
jumpGroupWorks(item){ |
|||
if(item.shopId){ |
|||
uni.navigateTo({ |
|||
url: '/pages_category_page1/discount/groupBuy?shopId=' + item.shopId + '&shopGroupWorkId=' + item.shopGroupWorkId |
|||
}) |
|||
} else { |
|||
uni.navigateTo({ |
|||
url: '/pages_category_page1/discount/groupBuy?' |
|||
}) |
|||
} |
|||
}, |
|||
// 跳转到折扣专区
|
|||
jumpDiscount(item){ |
|||
if(item.shopId){ |
|||
if (item.shopDiscountId) { |
|||
uni.navigateTo({ |
|||
url: '/pages_category_page1/discount/discount?shopId=' + item.shopId + '&shopDiscountId=' + item.shopDiscountId |
|||
}) |
|||
} else { |
|||
uni.showToast({ |
|||
title: '暂无活动', |
|||
icon: "none" |
|||
}); |
|||
} |
|||
} else { |
|||
if (item.discountId) { |
|||
uni.navigateTo({ |
|||
url: '/pages_category_page1/discount/platformDiscount?discountId=' + item.discountId |
|||
}) |
|||
} else { |
|||
uni.showToast({ |
|||
title: '暂无活动', |
|||
icon: "none" |
|||
}); |
|||
} |
|||
} |
|||
}, |
|||
// 跳转到会员专区
|
|||
jumpVip(){ |
|||
uni.navigateTo({ |
|||
url: '/pages_category_page1/memberCenter/activityList', |
|||
success: res => {},fail: () => {},complete: () => {} |
|||
}) |
|||
}, |
|||
// 跳转组合支付
|
|||
jumpCombination(item){ |
|||
if (item.priceId) { |
|||
uni.navigateTo({ |
|||
url: '/pages_category_page1/goodsModule/combination?priceId=' + item.priceId |
|||
}) |
|||
} else { |
|||
uni.showToast({ |
|||
title: '暂无活动', |
|||
icon: "none" |
|||
}); |
|||
} |
|||
}, |
|||
// 跳转到公告详情
|
|||
jumpNoticeDetail(item){ |
|||
uni.navigateTo({ |
|||
url: '/pages_category_page2/userModule/messageDetail?noticeId=' + item.noticeId |
|||
}) |
|||
}, |
|||
// 跳转到直播列表
|
|||
jumpLive(){ |
|||
uni.navigateTo({ |
|||
url: '/pages_category_page2/livePage/index' |
|||
}) |
|||
}, |
|||
// 领取优惠券
|
|||
// receiveCoupon(item) {
|
|||
// var key = canvasConfig.getToken()
|
|||
// if (key) {
|
|||
// var paramsData = {}
|
|||
// if(this.typeId === 1){
|
|||
// paramsData.couponId = item.couponId
|
|||
// } else if(this.typeId === 3) {
|
|||
// paramsData.shopCouponId = item.shopCouponId
|
|||
// paramsData.shopId = this.shopId
|
|||
// }
|
|||
// let params = {
|
|||
// url: api.takeCoupon,
|
|||
// method: 'POST',
|
|||
// data: paramsData
|
|||
// }
|
|||
// this.sendReq(params, (res) => {
|
|||
// this.$message({
|
|||
// message: '领取成功!',
|
|||
// type: 'success'
|
|||
// })
|
|||
// this.getData()
|
|||
// })
|
|||
// } else {
|
|||
// this.$message({
|
|||
// message: '请先登录'
|
|||
// })
|
|||
// this.$router.push({path: '/login'})
|
|||
// }
|
|||
// },
|
|||
// 加入购物车
|
|||
addCart(id){ |
|||
console.log(id) |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,9 @@ |
|||
/* |
|||
* 用于组件复用 |
|||
* 参考链接 https://cn.vuejs.org/v2/guide/mixins.html#全局混合
|
|||
* 混合 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混合对象可以包含任意组件选项。以组件使用混合对象时,所有混合对象的选项将被混入该组件本身的选项。 |
|||
*/ |
|||
import { tool } from './funMixin.js' |
|||
import { sendReq } from './sendReqMixin.js' |
|||
export const funMixin = { ...tool } |
|||
export const sendReqMixin = { ...sendReq } |
@ -0,0 +1,37 @@ |
|||
/* |
|||
* 发送请求 mixin |
|||
*/ |
|||
import request from './server' |
|||
|
|||
/* eslint-disable */ |
|||
export const sendReq = { |
|||
data () { |
|||
return { |
|||
// 加载中
|
|||
loading: false, |
|||
} |
|||
}, |
|||
methods: { |
|||
/* |
|||
* 发送请求 |
|||
*/ |
|||
sendReq (params, callback) { |
|||
let self = this |
|||
request({ |
|||
method: params.method || 'POST', |
|||
url: params.url, |
|||
data: params.data || {}, |
|||
withCredentials : true, |
|||
headers: { |
|||
'Content-type': params.contentType || 'application/json;charset=utf-8' |
|||
} |
|||
}).then((res) => { |
|||
if (res && res.data) { |
|||
callback && callback(res.data) |
|||
} |
|||
}, (error) => { |
|||
console.log(error) |
|||
}) |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,135 @@ |
|||
// 引入axios
|
|||
// import router from './../../router'
|
|||
import Vue from 'vue' |
|||
// import promise from 'es6-promise'
|
|||
import axios from 'axios' |
|||
import canvasConfig from '../config' |
|||
// import Cookies from 'js-cookie'
|
|||
// import localStorage from '../storage/localStorage'
|
|||
// promise.polyfill()
|
|||
|
|||
const service = axios.create({ |
|||
headers: { |
|||
'X-Requested-With': 'XMLHttpRequest' |
|||
}, |
|||
withCredentials: true, |
|||
timeout: 20000 // 请求超时 20s
|
|||
}) |
|||
|
|||
// 请求拦截器
|
|||
service.interceptors.request.use(config => { |
|||
// 是否为当前的请求加上请求头 token
|
|||
const token = canvasConfig.getToken() |
|||
if (token) { |
|||
if(canvasConfig.typeId === 1){ |
|||
config.headers['Authorization-admin'] = token |
|||
} else if(canvasConfig.typeId === 3){ |
|||
config.headers['Authorization-business'] = token |
|||
} else { |
|||
config.headers['Authorization'] = token |
|||
} |
|||
} |
|||
return config |
|||
}, error => { |
|||
return Promise.reject(error) |
|||
}) |
|||
|
|||
// 响应拦截器
|
|||
service.interceptors.response.use( |
|||
(response) => { |
|||
console.log(response) |
|||
if (response.data.code && response.data.code !=='200' && response.data.message) { |
|||
Vue.prototype.$message.error(response.data.message) |
|||
} |
|||
return response |
|||
}, |
|||
err => { |
|||
console.log(err) |
|||
// 失败响应
|
|||
if (err && err.response) { |
|||
switch (err.response.status) { |
|||
case 400: |
|||
err.message = '请求无效,请检查参数是否正确!' |
|||
break |
|||
|
|||
case 401: |
|||
err.message = '未经授权,访问被拒!' |
|||
break |
|||
|
|||
case 403: |
|||
err.message = '拒绝访问!' |
|||
break |
|||
|
|||
case 404: |
|||
err.message = `地址不存在!` |
|||
break |
|||
|
|||
case 408: |
|||
err.message = '请求超时!' |
|||
break |
|||
|
|||
case 500: |
|||
err.message = '系统错误!' |
|||
break |
|||
|
|||
case 501: |
|||
err.message = '该方法未实现!' |
|||
break |
|||
|
|||
case 502: |
|||
err.message = '网关出错!' |
|||
break |
|||
|
|||
case 503: |
|||
err.message = '服务不可用!' |
|||
break |
|||
|
|||
case 504: |
|||
err.message = '网关请求超时' |
|||
break |
|||
|
|||
case 505: |
|||
err.message = 'HTTP版本不受支持' |
|||
break |
|||
|
|||
default: |
|||
} |
|||
if (err.response.data.error) { |
|||
err.message = err.response.data.error |
|||
} |
|||
Vue.prototype.$message.closeAll() |
|||
Vue.prototype.$message.error(err.message) |
|||
// router.push({name: 'error', params: {message: err.message, status: err.response.status}})
|
|||
} |
|||
} |
|||
) |
|||
|
|||
//真机获取
|
|||
service.defaults.adapter = function (config) { |
|||
return new Promise((resolve, reject) => { |
|||
console.log(config) |
|||
var settle = require('axios/lib/core/settle'); |
|||
var buildURL = require('axios/lib/helpers/buildURL'); |
|||
uni.request({ |
|||
method: config.method.toUpperCase(), |
|||
url: buildURL(config.url, config.params, config.paramsSerializer), |
|||
header: config.headers, |
|||
data: config.data, |
|||
dataType: config.dataType, |
|||
responseType: config.responseType, |
|||
sslVerify: config.sslVerify, |
|||
complete:function complete(response){ |
|||
response = { |
|||
data: response.data, |
|||
status: response.statusCode, |
|||
errMsg: response.errMsg, |
|||
header: response.header, |
|||
config: config |
|||
}; |
|||
|
|||
settle(resolve, reject, response); |
|||
} |
|||
}) |
|||
}) |
|||
} |
|||
export default service |
After Width: 50 | Height: 50 | Size: 849 B |
After Width: 95 | Height: 95 | Size: 4.6 KiB |
After Width: 50 | Height: 50 | Size: 861 B |
After Width: 95 | Height: 95 | Size: 4.6 KiB |
After Width: 335 | Height: 292 | Size: 8.2 KiB |
After Width: 335 | Height: 292 | Size: 7.2 KiB |
After Width: 20 | Height: 122 | Size: 1.3 KiB |
After Width: 71 | Height: 71 | Size: 2.3 KiB |
After Width: 71 | Height: 71 | Size: 2.7 KiB |
After Width: 71 | Height: 71 | Size: 2.2 KiB |
After Width: 71 | Height: 71 | Size: 2.6 KiB |
After Width: 176 | Height: 83 | Size: 4.1 KiB |
After Width: 1200 | Height: 250 | Size: 46 KiB |
After Width: 57 | Height: 36 | Size: 1.9 KiB |
After Width: 100 | Height: 40 | Size: 3.2 KiB |
After Width: 203 | Height: 32 | Size: 7.4 KiB |
After Width: 58 | Height: 36 | Size: 1.4 KiB |
After Width: 57 | Height: 36 | Size: 2.0 KiB |
After Width: 189 | Height: 33 | Size: 6.2 KiB |
After Width: 58 | Height: 36 | Size: 1.5 KiB |
After Width: 36 | Height: 32 | Size: 720 B |
After Width: 446 | Height: 446 | Size: 9.1 KiB |
After Width: 20 | Height: 20 | Size: 381 B |
After Width: 211 | Height: 32 | Size: 4.7 KiB |
After Width: 58 | Height: 36 | Size: 1.3 KiB |
After Width: 710 | Height: 454 | Size: 20 KiB |
After Width: 54 | Height: 54 | Size: 1.3 KiB |
After Width: 15 | Height: 16 | Size: 737 B |
After Width: 30 | Height: 31 | Size: 1.2 KiB |
After Width: 290 | Height: 47 | Size: 9.7 KiB |