635 lines
14 KiB
Vue
635 lines
14 KiB
Vue
<template>
|
|
<view class="activity-page">
|
|
<!-- Banner -->
|
|
<view class="banner-wrapper">
|
|
<image class="banner-img" :src="banner" mode="widthFix" />
|
|
</view>
|
|
|
|
<!-- 分类 Tabs -->
|
|
<view class="category-sticky" v-if="category.list.length > 1">
|
|
<scroll-view scroll-x class="category-scroll" :show-scrollbar="false">
|
|
<view class="category-tabs">
|
|
<view v-for="item in category.list" :key="item.value" class="tab-item"
|
|
:class="{ active: category.value === item.value }" @click="onNavChange(item.value)">
|
|
{{ item.label }}
|
|
</view>
|
|
</view>
|
|
</scroll-view>
|
|
</view>
|
|
|
|
<!-- 商品列表 -->
|
|
<view class="goods-list" :class="{ 'empty-list': !listData.list.length }">
|
|
<view class="goods-card" v-for="(item, index) in listData.list" :key="item.itemid"
|
|
@click="handleGoodsTransfer(item)">
|
|
<view class="cover img-box">
|
|
<image class="goods-img" :src="item.itempic" mode="aspectFill" lazy-load v-if="item.itempic" />
|
|
<image class="goods-img" src="http://img.bc.fqapps.com/fudai13cae4ae6ef16739ed3b100a2ec39e97.gif"
|
|
mode="aspectFill" v-else />
|
|
<view class="sale-tag">
|
|
<text class="fire-icon">🔥</text>
|
|
<text>日销量 {{ getMoneyStr(item.itemsale2) }}</text>
|
|
</view>
|
|
</view>
|
|
<view class="detail">
|
|
<view class="title">
|
|
<image v-if="item.shoptype === 'B'" class="shop-icon tm"
|
|
src="http://img-haodanku-com.cdn.fudaiapp.com/FvU9Lg74-WgBzWQphv98-9KgYF6d" />
|
|
<image v-else-if="item.shoptype === 'C'" class="shop-icon tb"
|
|
src="http://img-haodanku-com.cdn.fudaiapp.com/FnCy1eY4W5khYdTw_iIDhKuwGLmu" />
|
|
<text class="title-text">{{ item.itemshorttitle || item.itemtitle }}</text>
|
|
</view>
|
|
<view class="center">
|
|
<text>{{ item.itemdesc }}</text>
|
|
</view>
|
|
<view class="price">
|
|
<view class="end-price">
|
|
券后价<text class="price-strong">¥{{ Number(item.itemendprice) }}</text>
|
|
</view>
|
|
<view class="origin">
|
|
<text class="del-price">¥{{ Number(item.itemprice) }}</text>
|
|
</view>
|
|
</view>
|
|
<view class="tags" v-if="item.couponmoney != '0'">
|
|
<view class="ticket">
|
|
<text class="name">券</text><text class="value">¥{{ item.couponmoney }}</text>
|
|
</view>
|
|
</view>
|
|
<view class="btn-block">
|
|
<view class="btn-order" @click.stop="handleGoodsTransfer(item)">
|
|
<text>立即购买</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 加载提示 -->
|
|
<view class="list-loading" v-if="loading && !listData.list.length">数据正在赶来的路上...</view>
|
|
<view class="list-finished" v-if="listData.finished && listData.list.length">-优惠到底啦-</view>
|
|
</view>
|
|
|
|
<!-- 分享按钮 -->
|
|
<view class="share-btn" :class="{ hide: isScrollToDown }" @click="handleShare">
|
|
<view class="share-icon">
|
|
<svg viewBox="0 0 18 19.11" class="svg-share">
|
|
<path class="cls-1"
|
|
d="M17.5,8A2.5,2.5,0,1,0,15,5.5,2.5,2.5,0,0,0,17.5,8Z" transform="translate(-3 -2)" />
|
|
<path class="cls-1"
|
|
d="M6.5,14.5A2.5,2.5,0,1,0,4,12,2.5,2.5,0,0,0,6.5,14.5Z" transform="translate(-3 -2)" />
|
|
<path class="cls-2" d="M15,6.79,8.67,10.62" transform="translate(-3 -2)" />
|
|
<path class="cls-2" d="M8.67,13.28,13.27,16" transform="translate(-3 -2)" />
|
|
<path class="cls-1"
|
|
d="M15.77,15.11a2.5,2.5,0,1,1-2.5,2.5A2.5,2.5,0,0,1,15.77,15.11Z" transform="translate(-3 -2)" />
|
|
</svg>
|
|
</view>
|
|
<text>分享好友</text>
|
|
</view>
|
|
|
|
<!-- 回到顶部 -->
|
|
<view class="back-top-btn" :class="{ hide: scrollTop < 600 }" @click="backTop"></view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import http from '@/request/request.js';
|
|
const API_BASE = 'https://v2.api.haodanku.com';
|
|
const CUSTOM_PARAMS = {
|
|
apikey: '5417B681C5EA'
|
|
};
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
banner: '',
|
|
loading: false,
|
|
scrollTop: 0,
|
|
lastScrollTop: 0,
|
|
isScrollToDown: false,
|
|
category: {
|
|
value: '0',
|
|
list: [],
|
|
goodsLists: []
|
|
},
|
|
listData: {
|
|
list: [],
|
|
loading: false,
|
|
finished: false
|
|
}
|
|
}
|
|
},
|
|
onLoad(options) {
|
|
const stamp = Date.now() - Date.now() % (60 * 1000 * 30);
|
|
this.banner = 'https://img.bc.haodanku.com/cms/1635994050?t=' + stamp;
|
|
this.getListData();
|
|
},
|
|
onPageScroll(e) {
|
|
const st = e.scrollTop;
|
|
this.isScrollToDown = st > this.lastScrollTop;
|
|
this.lastScrollTop = st;
|
|
this.scrollTop = st;
|
|
},
|
|
onPullDownRefresh() {
|
|
this.reGetListData().finally(() => {
|
|
uni.stopPullDownRefresh();
|
|
});
|
|
},
|
|
methods: {
|
|
getListDataParams() {
|
|
return { ...CUSTOM_PARAMS };
|
|
},
|
|
getTransferParams() {
|
|
const rid = this.$store.getters.relationId;
|
|
return {
|
|
pid: 'mm_284380119_1881450385_111415850448',
|
|
tb_name: 'michuan2018',
|
|
relation_id: rid || '-1',
|
|
...CUSTOM_PARAMS
|
|
};
|
|
},
|
|
|
|
async getListData() {
|
|
const listData = this.listData;
|
|
if (this.loading || listData.loading || listData.finished) return;
|
|
listData.loading = true;
|
|
this.loading = true;
|
|
|
|
const params = {
|
|
id: 125,
|
|
...this.getListDataParams()
|
|
};
|
|
|
|
http.get(`${API_BASE}/get_index_activity_items`, params)
|
|
.then(res => {
|
|
const body = res.body || {};
|
|
const block = body.data ? (body.data.block || []) : (body.block || []);
|
|
this.category.list = block.map((item, index) => ({
|
|
label: item.name,
|
|
value: String(index)
|
|
}));
|
|
this.category.goodsLists = block.map(item => item.item || []);
|
|
const list = this.category.goodsLists[0] || [];
|
|
this.listData.list = list;
|
|
this.listData.finished = true;
|
|
})
|
|
.catch(() => {
|
|
this.listData.list = [];
|
|
this.listData.finished = true;
|
|
})
|
|
.finally(() => {
|
|
setTimeout(() => {
|
|
this.listData.loading = false;
|
|
this.loading = false;
|
|
}, 200);
|
|
});
|
|
},
|
|
|
|
reGetListData() {
|
|
this.listData.list = [];
|
|
this.listData.finished = false;
|
|
return this.getListData();
|
|
},
|
|
|
|
onNavChange(value) {
|
|
this.category.value = value;
|
|
this.listData.list = this.category.goodsLists[value] || [];
|
|
},
|
|
|
|
backTop() {
|
|
uni.pageScrollTo({
|
|
scrollTop: 0,
|
|
duration: 300
|
|
});
|
|
},
|
|
|
|
handleShare() {
|
|
let shareUrl;
|
|
// #ifdef H5
|
|
shareUrl = window.location.href;
|
|
// #endif
|
|
// #ifndef H5
|
|
shareUrl = 'https://your-domain.com/pages/activity/activity';
|
|
// #endif
|
|
|
|
uni.setClipboardData({
|
|
data: shareUrl,
|
|
success: () => {
|
|
uni.showToast({
|
|
title: '复制成功,分享给身边好友吧~',
|
|
icon: 'none'
|
|
});
|
|
}
|
|
});
|
|
},
|
|
|
|
async handleGoodsTransfer(item) {
|
|
const param = {
|
|
itemid: item.itemid,
|
|
title: item.itemshorttitle || item.itemtitle,
|
|
get_taoword: 1,
|
|
...this.getTransferParams()
|
|
};
|
|
|
|
this.loading = true;
|
|
|
|
try {
|
|
let isWechatEnv;
|
|
// #ifdef H5
|
|
isWechatEnv = /micromessenger/i.test(navigator.userAgent);
|
|
// #endif
|
|
// #ifndef H5
|
|
isWechatEnv = false;
|
|
// #endif
|
|
|
|
if (!isWechatEnv) {
|
|
// 非微信环境:弹窗确认后跳转
|
|
http.post(`${API_BASE}/ratesurl`, param, {
|
|
header: { 'Content-Type': 'application/x-www-form-urlencoded' }
|
|
}).then(res => {
|
|
const body = res.body || {};
|
|
const data = body.data || body;
|
|
const jumpUrl = data.coupon_click_url || data.item_url;
|
|
if (jumpUrl) {
|
|
uni.showModal({
|
|
title: '提示',
|
|
content: '是否跳转到下单页面?',
|
|
success: (modalRes) => {
|
|
if (modalRes.confirm) {
|
|
// #ifdef H5
|
|
window.location.href = jumpUrl;
|
|
// #endif
|
|
// #ifdef APP-PLUS
|
|
plus.runtime.openURL(jumpUrl);
|
|
// #endif
|
|
// #ifndef H5 || APP-PLUS
|
|
uni.setClipboardData({
|
|
data: jumpUrl,
|
|
success: () => {
|
|
uni.showToast({
|
|
title: '链接已复制,请在浏览器中打开',
|
|
icon: 'none',
|
|
duration: 3000
|
|
});
|
|
}
|
|
});
|
|
// #endif
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}).catch(() => {
|
|
uni.showToast({ title: '转链失败', icon: 'none' });
|
|
});
|
|
} else {
|
|
// 微信环境:获取淘口令并复制
|
|
http.post(`${API_BASE}/ratesurl`, param, {
|
|
header: { 'Content-Type': 'application/x-www-form-urlencoded' }
|
|
}).then(res => {
|
|
const body = res.body || {};
|
|
const data = body.data || body;
|
|
const taoword = data.taoword;
|
|
if (taoword) {
|
|
const taocode = '0' + taoword + '/';
|
|
uni.setClipboardData({
|
|
data: taocode,
|
|
success: () => {
|
|
uni.showToast({
|
|
title: '复制口令成功,请打开淘宝领取',
|
|
icon: 'none',
|
|
duration: 2000
|
|
});
|
|
}
|
|
});
|
|
} else {
|
|
uni.showToast({ title: '转链失败', icon: 'none' });
|
|
}
|
|
}).catch(() => {
|
|
uni.showToast({ title: '转链失败', icon: 'none' });
|
|
});
|
|
}
|
|
} catch (e) {
|
|
uni.showToast({
|
|
title: '转链失败',
|
|
icon: 'none'
|
|
});
|
|
} finally {
|
|
setTimeout(() => {
|
|
this.loading = false;
|
|
}, 200);
|
|
}
|
|
},
|
|
|
|
getMoneyStr(num) {
|
|
const n = Number(num);
|
|
const w = 10000;
|
|
if (n < w) return String(n);
|
|
return (n / w).toFixed(2) + '万';
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.activity-page {
|
|
background: #f5f5f5;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
.banner-wrapper {
|
|
width: 100%;
|
|
}
|
|
|
|
.banner-img {
|
|
width: 100%;
|
|
display: block;
|
|
}
|
|
|
|
.category-sticky {
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 100;
|
|
background: #fff;
|
|
}
|
|
|
|
.category-scroll {
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.category-tabs {
|
|
display: flex;
|
|
padding: 0 20rpx;
|
|
border-bottom: 1rpx solid #eee;
|
|
}
|
|
|
|
.tab-item {
|
|
display: inline-block;
|
|
padding: 24rpx 30rpx;
|
|
font-size: 28rpx;
|
|
color: #666;
|
|
position: relative;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.tab-item.active {
|
|
color: #ff416c;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.tab-item.active::after {
|
|
content: '';
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
width: 40rpx;
|
|
height: 4rpx;
|
|
background: #ff416c;
|
|
border-radius: 2rpx;
|
|
}
|
|
|
|
.goods-list {
|
|
padding: 20rpx;
|
|
}
|
|
|
|
.goods-list.empty-list {
|
|
min-height: 400rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.goods-card {
|
|
background: #fff;
|
|
border-radius: 16rpx;
|
|
margin-bottom: 20rpx;
|
|
overflow: hidden;
|
|
display: flex;
|
|
padding: 20rpx;
|
|
}
|
|
|
|
.cover {
|
|
position: relative;
|
|
width: 240rpx;
|
|
height: 240rpx;
|
|
flex-shrink: 0;
|
|
border-radius: 12rpx;
|
|
overflow: hidden;
|
|
background: #f9f9f9;
|
|
}
|
|
|
|
.goods-img {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.sale-tag {
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
background: linear-gradient(to right, rgba(255, 65, 108, 0.9), rgba(255, 75, 43, 0.9));
|
|
color: #fff;
|
|
font-size: 20rpx;
|
|
padding: 6rpx 12rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.fire-icon {
|
|
margin-right: 4rpx;
|
|
}
|
|
|
|
.detail {
|
|
flex: 1;
|
|
margin-left: 20rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.title {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
font-size: 28rpx;
|
|
color: #333;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.shop-icon {
|
|
width: 36rpx;
|
|
height: 36rpx;
|
|
margin-right: 8rpx;
|
|
flex-shrink: 0;
|
|
margin-top: 2rpx;
|
|
}
|
|
|
|
.title-text {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 2;
|
|
-webkit-box-orient: vertical;
|
|
}
|
|
|
|
.center {
|
|
font-size: 24rpx;
|
|
color: #999;
|
|
margin-top: 8rpx;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 1;
|
|
-webkit-box-orient: vertical;
|
|
}
|
|
|
|
.price {
|
|
display: flex;
|
|
align-items: baseline;
|
|
margin-top: 8rpx;
|
|
}
|
|
|
|
.end-price {
|
|
font-size: 24rpx;
|
|
color: #ff416c;
|
|
}
|
|
|
|
.price-strong {
|
|
font-size: 36rpx;
|
|
font-weight: bold;
|
|
margin-left: 4rpx;
|
|
}
|
|
|
|
.origin {
|
|
margin-left: 12rpx;
|
|
}
|
|
|
|
.del-price {
|
|
font-size: 24rpx;
|
|
color: #999;
|
|
text-decoration: line-through;
|
|
}
|
|
|
|
.tags {
|
|
margin-top: 8rpx;
|
|
}
|
|
|
|
.ticket {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
border: 1rpx solid #ff416c;
|
|
border-radius: 8rpx;
|
|
overflow: hidden;
|
|
font-size: 22rpx;
|
|
}
|
|
|
|
.ticket .name {
|
|
background: linear-gradient(to right, #ff715a, #ff416c);
|
|
color: #fff;
|
|
padding: 2rpx 10rpx;
|
|
}
|
|
|
|
.ticket .value {
|
|
color: #ff416c;
|
|
padding: 2rpx 10rpx;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.btn-block {
|
|
margin-top: 12rpx;
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
.btn-order {
|
|
background: linear-gradient(to right, #ff715a, #ff416c);
|
|
color: #fff;
|
|
font-size: 26rpx;
|
|
padding: 12rpx 32rpx;
|
|
border-radius: 30rpx;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.list-loading,
|
|
.list-finished {
|
|
text-align: center;
|
|
padding: 30rpx;
|
|
font-size: 24rpx;
|
|
color: #999;
|
|
}
|
|
|
|
.share-btn {
|
|
position: fixed;
|
|
right: 30rpx;
|
|
bottom: 160rpx;
|
|
z-index: 200;
|
|
background: rgba(255, 65, 108, 0.9);
|
|
color: #fff;
|
|
border-radius: 40rpx;
|
|
padding: 16rpx 24rpx;
|
|
font-size: 24rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
box-shadow: 0 4rpx 16rpx rgba(255, 65, 108, 0.3);
|
|
transition: transform 0.3s, opacity 0.3s;
|
|
}
|
|
|
|
.share-btn.hide {
|
|
transform: translateX(120%);
|
|
opacity: 0;
|
|
}
|
|
|
|
.share-icon {
|
|
width: 32rpx;
|
|
height: 32rpx;
|
|
margin-right: 8rpx;
|
|
}
|
|
|
|
.svg-share {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.svg-share .cls-1 {
|
|
fill: none;
|
|
stroke: #fff;
|
|
stroke-linecap: round;
|
|
stroke-linejoin: round;
|
|
stroke-width: 1.5px;
|
|
}
|
|
|
|
.svg-share .cls-2 {
|
|
fill: none;
|
|
stroke: #fff;
|
|
stroke-linecap: round;
|
|
stroke-linejoin: round;
|
|
stroke-width: 1.5px;
|
|
}
|
|
|
|
.back-top-btn {
|
|
position: fixed;
|
|
right: 30rpx;
|
|
bottom: 80rpx;
|
|
z-index: 200;
|
|
width: 80rpx;
|
|
height: 80rpx;
|
|
background: rgba(0, 0, 0, 0.5);
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
transition: transform 0.3s, opacity 0.3s;
|
|
}
|
|
|
|
.back-top-btn::before {
|
|
content: '';
|
|
width: 0;
|
|
height: 0;
|
|
border-left: 16rpx solid transparent;
|
|
border-right: 16rpx solid transparent;
|
|
border-bottom: 20rpx solid #fff;
|
|
}
|
|
|
|
.back-top-btn.hide {
|
|
transform: translateY(200%);
|
|
opacity: 0;
|
|
}
|
|
</style>
|