shop_app/pages/index/index.vue

1630 lines
45 KiB
Vue
Raw Normal View History

2025-05-08 09:16:37 +08:00
<template>
<view class="whole">
<view class="home">
<!-- 搜索框 -->
<view class="tou">
<view style="background: #fff;padding: 0 0 2rpx 0;box-sizing: border-box;">
<view class="searchBox flex1">
<view class="box" @click="toSearch">
<up-icon name="search" size="18" color="#656565"></up-icon>
<text>&nbsp;请输入搜索关键词</text>
</view>
</view>
<template v-if="loading1">
<view style="display: flex;align-items: center;height: 60rpx;justify-content: space-between;padding: 0 20rpx;">
<view style="display: flex;">
<view class="skeleton" style="width: 120rpx;height: 40rpx;margin-right: 20rpx;"></view>
<view class="skeleton" style="width: 120rpx;height: 40rpx;margin-right: 20rpx;"></view>
<view class="skeleton" style="width: 120rpx;height: 40rpx;margin-right: 20rpx;"></view>
</view>
<view class="skeleton" style="width: 120rpx;height: 40rpx;margin-left: 20rpx;"></view>
</view>
</template>
<view v-if="home_page_rule === 0 && !loading1" class="home-top table">
<view class="bbox">
<view class="adbox" id="adbox">
<view @click="onClickTab(0)" class="li" :class="active === 0 ? 'border' : ''">首页</view>
<view v-for="(item, index) in adList" :key="index" :class="active === index + 1 ? 'border' : ''" @click="onClickAd(item.link, item.top_bar_title, item.id, index)" class="li">
{{item.top_bar_title}}
</view>
</view>
</view>
<view class="assort flex" @click="openTabs()" v-if="showArrow">
<up-icon v-if="showDown" name="arrow-up" color="#BFBFBF"></up-icon>
<up-icon v-else name="arrow-down" color="#BFBFBF"></up-icon>
</view>
</view>
</view>
</view>
<!-- 工厂好货-团购商品 -->
<view v-if="active == 0">
<view class="skeleton" v-if="loading2" style="width: 100%;height: 285rpx;"></view>
<view class="home-top" v-else>
2025-06-14 10:01:48 +08:00
<swiper v-if="swiperList.length !== 0" :style="{'height': swiperH + 'px'}" class="home-top-swiper" :autoplay="true" :interval="5000" :duration="500" :indicator-dots="true" :circular="true">
2025-05-08 09:16:37 +08:00
<swiper-item v-for="(item, index) in swiperList" :key="index">
2025-06-14 10:01:48 +08:00
<image class="item_img" mode="widthFix" :src="item.pic_url + '?x-oss-process=image/format,webp'"
:webp="true" @click="onSwiperItem(item.link, item.id)" @load="computeHeight">
2025-05-08 09:16:37 +08:00
</image>
</swiper-item>
</swiper>
</view>
<view class="shop" v-if="home_page_rule === 0">
<view v-if="loading3" style="display: flex;padding: 28rpx 20rpx;justify-content:space-around">
<view v-for="i in 5" :key="i"
style="display: flex;align-items: center;justify-content: center;flex-direction: column;">
<view class="skeleton" style="width: 50px;height: 50px;margin-bottom: 7px;border-radius: 50%;"></view>
<view class="skeleton" style="width: 90rpx;height: 30rpx;"></view>
</view>
</view>
<view class="shop-group" v-if="groupList.length !== 0 && !loading3" :class="banner_icon == 1 ? 'per20' : ''">
<view class="shop-group-item" v-for="(item, index) in groupList" :key="index" @click="toRemmend(item.link, item.top_bar_title, item.id)">
<image :src="item.pic_url + '?x-oss-process=image/format,webp'" :webp="true" class="img" mode="aspectFill"></image>
<view class="tit">{{item.top_bar_title}}</view>
</view>
</view>
<view v-if="loading4" style="display: flex;padding: 16rpx 0;flex-wrap: wrap;">
<view v-for="i in 4" :key="i" style="width: 50%;height: 97px;padding: 5px;box-sizing: border-box;">
<view class="skeleton" style="width: 100%;height: 100%;"></view>
</view>
</view>
<view class="salebox" v-if="rankList.length !== 0 && !loading4">
<template v-for="(item, index) in rankList" :key="index">
<view class="row" :class="banner_rank == 0 ? 'per100' : banner_rank == 1 ? '' : 'per33'" @click="hanleRank(item.link, item.id)">
<image :src="item.pic_url + '?x-oss-process=image/format,webp'" :webp="true" mode="widthFix" class="img"></image>
</view>
</template>
</view>
<!-- 日期推荐位 -->
<view style="padding: 0 16rpx;" v-if="loading5">
<view class="skeleton" style="width: 100%;height: 75px;"></view>
<view style="display: flex;padding: 20rpx 16rpx;flex-wrap: wrap;justify-content:space-between">
<view v-for="i in 6" :key="i"
style="display: flex;align-items: center;justify-content: center;width: 30%;flex-direction: column;margin-bottom: 20rpx;">
<view class="skeleton" style="width: 200rpx;height: 200rpx;margin-bottom: 10rpx;"></view>
<view class="skeleton" style="width: 100rpx;height: 30rpx;"></view>
</view>
</view>
</view>
<view class="dateRecom" v-if="dateList.length !== 0 && !loading5">
<scroll-view :scroll-x="true" class="dateBox" :scroll-left="scrollLeft" :scroll-with-animation="true">
<view class="box" v-for="(it, index) in dateList" :key="index" :class="index === curIndex ? 'active' : ''" @click="changeDateTab(index)">
<view class="date">{{ it.day }}</view>
<text class="text">{{ it.desc }}</text>
</view>
</scroll-view>
<view class="shop-recommend-item">
<view class="shop-recommend-item-goods">
<template v-for="(goods, inx) in dateList[curIndex].items" :key="goods.id">
<view @click="toGoods(goods)" class="goods">
<view class="goods-img">
<image v-if="goods.pivot" :src="goods.pivot.image + '?x-oss-process=image/format,webp'" :webp="true" mode="aspectFill" class="img"></image>
<image v-else :src="goods.face_img + '?x-oss-process=image/format,webp'" mode="aspectFill" :webp="true" class="img"></image>
<view class="out" v-if="goods.sold_status === 2">
<img src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2024/01/16/Cr6cRRhhqYNhScigxIyumyV9hXXMI3vKvsE1jgt0.png" class="out_img" />
</view>
<view class="out" v-else-if="goods.sold_status === 0">
<img src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2024/08/21/QBhUheeYWSJ3OGM27fkAufJAlFSA8GBhWjpY5oNy.png" class="out_img" />
</view>
<view class="out" v-else-if="goods.total_stock === 0">
<img src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2024/08/21/pMTv6QiZZEpSqkJmk7hMcbEzIuNzMyp7YVBbe42H.png" class="out_img" />
</view>
</view>
<view class="goods-info">
<view class="goods-info-name">
<text class="name">{{goods.pivot && goods.pivot.title || goods.title}}</text>
</view>
<view class="goods-info-price">
<view class="goods-info-price-left">
<text class="icon"></text>
<text class="price">
<template v-if="goods.pivot && goods.pivot.path_type === 1">
<text v-if="goods.pivot.max_price === goods.pivot.min_price">{{goods.pivot.min_price}}</text>
<text v-else>{{goods.pivot.min_price * 1}}~{{goods.pivot.max_price}}</text>
</template>
<template v-else>
<text v-if="goods.max_price === goods.min_price">{{goods.min_price}}</text>
<text v-else>{{goods.min_price * 1}}~{{goods.max_price}}</text>
</template>
</text>
</view>
</view>
</view>
</view>
</template>
</view>
</view>
</view>
<!-- 首页推荐位 -->
<view class="shop-recommend" v-if="recommendList.length !== 0">
<!-- 普通推荐位 -->
<template v-for="(item, index) in recommendList" :key="item.id">
<view class="shop-recommend-item" v-if="item.shop_goods.length !== 0">
<view class="shop-recommend-item-title" v-if="item.type === 1">
<text class="title">{{item.title}}</text>
<text v-if="item.show_more === 1" @click="toMoreGroup(item)">更多</text>
</view>
<view class="shop-recommend-item-img" v-else-if="item.type === 2" @click="toMoreGroup(item)">
<image :src="item.image + '?x-oss-process=image/format,webp'" :webp="true" mode="widthFix" class="img" v-if="item.shop_goods.length"></image>
</view>
<view class="shop-recommend-item-goods" :class="item.show_type == 2 ? 'two' : ''">
<template v-for="(goods, inx) in item.shop_goods" :key="goods.id">
<view v-if="item.show_type === 1" @click="toGoods(goods)" class="goods per100">
<view class="face_img">
<image v-if="goods.pivot" :src="goods.pivot.image + '?x-oss-process=image/format,webp'" :webp="true" mode="aspectFill" class="img"></image>
<image v-else :src="goods.face_img + '?x-oss-process=image/format,webp'" mode="aspectFill" :webp="true" class="img"></image>
<!-- sold_status 0未销售1销售中2已结束 -->
<view class="out" v-if="goods.sold_status === 2">
<img src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2024/01/16/Cr6cRRhhqYNhScigxIyumyV9hXXMI3vKvsE1jgt0.png" class="out_img" />
</view>
<view class="out" v-else-if="goods.sold_status === 0">
<img src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2024/08/21/QBhUheeYWSJ3OGM27fkAufJAlFSA8GBhWjpY5oNy.png" class="out_img" />
</view>
<view class="out" v-else-if="goods.total_stock === 0">
<img src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2024/08/21/pMTv6QiZZEpSqkJmk7hMcbEzIuNzMyp7YVBbe42H.png" class="out_img" />
</view>
</view>
<view class="infotext">
<text class="tit">{{goods.pivot && goods.pivot.title || goods.title}}</text>
<view class="qiang">
<view class="priceB">
<text></text>
<block v-if="goods.group_goods.length === 1">
<text v-if="goods.group_goods[0].specs_type === 0">{{goods.group_goods[0].price}}</text>
<text v-else>
<text v-if="goods.group_goods[0].max_price === goods.group_goods[0].min_price">{{goods.group_goods[0].min_price}}</text>
<text v-else>{{goods.group_goods[0].min_price * 1}}~{{goods.group_goods[0].max_price}}</text>
</text>
</block>
<text class="price" v-else>
<template v-if="goods.pivot && goods.pivot.path_type === 1">
<text v-if="goods.pivot.max_price === goods.pivot.min_price">{{goods.pivot.min_price}}</text>
<text v-else>{{goods.pivot.min_price * 1}}~{{goods.pivot.max_price}}</text>
</template>
<template v-else>
<text v-if="goods.max_price === goods.min_price">{{goods.min_price}}</text>
<text v-else>{{goods.min_price * 1}}~{{goods.max_price}}</text>
</template>
</text>
</view>
<view class="txt">抢购</view>
</view>
</view>
</view>
<view v-else @click="toGoods(goods)" class="goods">
<view class="goods-img">
<image v-if="goods.pivot" :src="goods.pivot.image + '?x-oss-process=image/format,webp'" :webp="true" mode="aspectFill" class="img"></image>
<image v-else :src="goods.face_img + '?x-oss-process=image/format,webp'" mode="aspectFill" :webp="true" class="img"></image>
<view class="out" v-if="goods.sold_status === 2">
<img src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2024/01/16/Cr6cRRhhqYNhScigxIyumyV9hXXMI3vKvsE1jgt0.png" class="out_img" />
</view>
<view class="out" v-else-if="goods.sold_status === 0">
<img src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2024/08/21/QBhUheeYWSJ3OGM27fkAufJAlFSA8GBhWjpY5oNy.png" class="out_img" />
</view>
<view class="out" v-else-if="goods.total_stock === 0">
<img src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2024/08/21/pMTv6QiZZEpSqkJmk7hMcbEzIuNzMyp7YVBbe42H.png" class="out_img" />
</view>
</view>
<view class="goods-info">
<view class="goods-info-name">
<text class="name">{{goods.pivot && goods.pivot.title || goods.title}}</text>
</view>
<view class="goods-info-price">
<view class="goods-info-price-left">
<text class="icon"></text>
<block v-if="goods.group_goods.length === 1">
<text v-if="goods.group_goods[0].specs_type === 0">{{goods.group_goods[0].price}}</text>
<text v-else>
<text v-if="goods.group_goods[0].max_price === goods.group_goods[0].min_price">{{goods.group_goods[0].min_price}}</text>
<text v-else>{{goods.group_goods[0].min_price * 1}}~{{goods.group_goods[0].max_price}}</text>
</text>
</block>
<text class="price" v-else>
<template v-if="goods.pivot && goods.pivot.path_type === 1">
<text v-if="goods.pivot.max_price === goods.pivot.min_price">{{goods.pivot.min_price}}</text>
<text v-else>{{goods.pivot.min_price * 1}}~{{goods.pivot.max_price}}</text>
</template>
<template v-else>
<text v-if="goods.max_price === goods.min_price">{{goods.min_price}}</text>
<text v-else>{{goods.min_price * 1}}~{{goods.max_price}}</text>
</template>
</text>
</view>
</view>
</view>
</view>
</template>
</view>
<text v-if="item.show_more === 1 && (item.shop_group_id || item.shop_group_id === 0)" class="viewMore" @click="toMoreGroup(item)">查看更多</text>
</view>
</template>
</view>
</view>
<portrait v-if="home_page_rule === 1" :group-list="remmendList" @getnum="getNum" :vip-on="vip_on" />
<view class="zonghe" v-if="showZongHe" id="goods">
<scroll-view :scroll-x="true" class="titBox" :class="showDown ? 'z98' : ''" :scroll-with-animation="true">
<view class="row" @click="changeSort(sort1, '')">
<view class="tit">臻品推荐</view>
<view class="desc" :class="sortType == sort1 ? 'on' : ''">严选好货</view>
</view>
<view class="row" @click="changeSort('startTime', '')">
<view class="tit">本月上新</view>
<view class="desc" :class="sortType == 'startTime' ? 'on' : ''">新品发布</view>
</view>
<view class="row" v-for="it in classifyList" :key="it.id" @click="changeSort(it.id, 'group')">
<view class="tit">{{it.name}}</view>
<view class="desc" v-if="it.describe" :class="sortType == it.id ? 'on' : ''">{{it.describe}}</view>
</view>
</scroll-view>
<view class="content">
<template v-for="i in 2" :key="i">
<view class="left">
<template v-for="(item, index) in zongheList" :key="item.id">
<view class="row" @click="toPage(item.id)" v-if="index % 2 == i - 1">
<view class="face_img">
<image :src="item.face_img" mode="widthFix" class="img"></image>
<view class="out flex" v-if="item.sold_status === 2">
<image src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2024/01/16/Cr6cRRhhqYNhScigxIyumyV9hXXMI3vKvsE1jgt0.png" class="out_img" mode="widthFix"></image>
</view>
<view class="out flex" v-else-if="item.sold_status === 0">
<image src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2024/08/21/QBhUheeYWSJ3OGM27fkAufJAlFSA8GBhWjpY5oNy.png" class="out_img" mode="widthFix"></image>
</view>
<view class="out flex" v-else-if="item.total_stock === 0">
<image src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2024/08/21/pMTv6QiZZEpSqkJmk7hMcbEzIuNzMyp7YVBbe42H.png" class="out_img" mode="widthFix"></image>
</view>
</view>
<view class="padd">
<view class="desc">{{item.characteristic}}</view>
<view class="tit">{{item.title}}</view>
<view class="price">
<text v-if="parseFloat(item.min_price) == parseFloat(item.max_price)">{{item.min_price}}</text>
<text v-else>{{item.min_price * 1}}~{{item.max_price}}</text>
</view>
</view>
</view>
</template>
</view>
</template>
</view>
<view class="noMore" v-if="zongheList.length && page >= lastPage && !loading1"> 没有更多了 </view>
<view v-if="loading1" class="loadbox">
<up-loading-icon text="加载中..." textSize="18"></up-loading-icon>
</view>
</view>
</view>
<!-- 品牌特卖-小店商品 -->
<view v-else-if="barType == 'brand'">
<brand-buy></brand-buy>
</view>
<!-- 团购分组推荐位 -->
<view v-else-if="barType == 'recom'">
<group-classify :groupId="groupId" @handleShareInfo="handleShareInfo"></group-classify>
</view>
<!-- 所有团购 -->
<view v-else-if="barType == 'all'">
<all-group></all-group>
</view>
<!-- 视频 -->
<view v-else-if="barType == 'video'">
<video-list></video-list>
</view>
</view>
<!-- 返回顶部 -->
<view @click="backTop" v-if="showTop" class="topBox flex">
<up-icon name="arrow-upward" color="#000" size="24" />
</view>
<!-- 新人优惠券 -->
<new-vip :show-van="showVan" @close="showVan = false" :coupon-info="couponInfo"></new-vip>
<!-- 赠送会员 -->
<gifts-vip :show-gifts="showGifts" @close="showGifts = false" :info="giftsInfo"></gifts-vip>
<tabbar :chooseIndex="0" :num="cartNum" :msgNum="msgNum" />
<up-popup :show="showDown" mode="top" @close="showDown = false" :zIndex="98">
<view class="itemBox">
<view @click="onClickTab(0)" class="row flex" :class="active === 0 ? 'active' : ''">首页</view>
<view class="row flex" v-for="(item, index) in adList" :key="index" :class="active === index + 1 ? 'active' : ''" @click="onClickAd(item.link, item.top_bar_title, item.id, index)">{{item.top_bar_title}}</view>
</view>
</up-popup>
</view>
</template>
<script>
import { ref, reactive, toRefs } from 'vue'
import Portrait from '@/components/homeList/Portrait.vue'
import { get, post } from '@/api/request.js'
import tabbar from '@/components/tabbar/index.vue'
import brandBuy from '@/components/homeList/index.vue'
import groupClassify from '@/components/homeList/groupClassify.vue'
import allGroup from '@/components/homeList/allGroup.vue'
import videoList from '@/components/homeList/videoList.vue'
2025-06-14 10:01:48 +08:00
import { getShopInfo, showToast, uvRecord, whetherLogin, getOldDay, userBind } from '@/components/common.js'
2025-05-08 09:16:37 +08:00
import newVip from '@/components/newVip/index.vue'
import giftsVip from '@/components/giftsVip/index.vue'
import { Style } from '@/utils/list.js'
import { func } from '../../uni_modules/uview-plus/libs/function/test'
export default {
components: { Portrait, tabbar, brandBuy, groupClassify, allGroup, newVip, giftsVip, videoList },
setup() {
const data = reactive({
showTop: false,
active: 0,
home_page_rule: 0,
swiperList: [],
vip_on: 0,
cartNum: 0,
adList: [],
showVan: false,
couponInfo: [],
showGifts: false,
giftsInfo: {},
from: 0,
s: 0,
u: 0,
company_id: '',
has_multi_group: true,
msgNum: 0,
Color: '',
bgColor: '',
Theme: '',
groupId: 0,
barType: '',
groupShareImg: '',
groupShareTit: '',
banner_icon: 0,
banner_rank: 0,
showArrow: false,
showDown: false,
lastPage: 0,
page: 1,
zongheList: [],
classifyList: [],
showZongHe: false,
sortType: '',
sortVal: '',
loading6: false,
priceColor: '',
sort1: '',
isReachBottom: true,
sort3: '',
loading1: true,
loading2: true,
loading3: true,
loading4: true,
loading5: true,
scrollRight: 0,
scrollLeft: 0,
curIndex: 0,
today: '',
2025-06-14 10:01:48 +08:00
dateList: [],
swiperH: 150
2025-05-08 09:16:37 +08:00
})
const groupList = ref([]) // 分组
const remmendList = ref([])
const rankList = ref([]) // 分组
const recommendList = ref([]) // 推荐位
const backTop = () => {
uni.pageScrollTo({
scrollTop: 0,
duration: 300
})
}
const onClickTab = (e) => {
data.showDown = false
data.active = e
data.barType = ''
}
const onClickAd = (url, title, id, index) => {
data.showDown = false
if (url && id) {
if(url.indexOf('type=category') !== -1) { // 自定义分类推荐位
uni.navigateTo({ url: '/pages/lotRecom/index?' + url.split('?')[1] })
} else if(url.indexOf('type=shop_group') !== -1) { // 团购分组推荐位
data.groupId = url.split('&id=')[1].split('&')[0]
data.active = index + 1
data.barType = 'recom'
} else if(url.indexOf('presale/index') !== -1) { // 新品预告
uni.navigateTo({ url: url + '?title=' + title })
} else if(url.indexOf('type=brand') !== -1) { // 品牌特卖
data.barType = 'brand'
data.active = index + 1
} else if(url.indexOf('classify/all') !== -1) { // 所有团购
data.barType = 'all'
data.active = index + 1
} else if(url.indexOf('groups/videolist') !== -1) { // 视频
data.barType = 'video'
data.active = index + 1
} else {
uni.navigateTo({ url: url }) // 其他
}
// uvRecord(id)
}
}
// 获取店铺信息
async function getStoreInfo() {
let res = await getShopInfo()
data.has_multi_group = res.has_multi_group
data.home_page_rule = res.home_page_rule
data.vip_on = res.vip_on
data.Color = Style[res.show_style_type].color
data.bgColor = Style[res.show_style_type].bgColor
data.priceColor = Style[res.show_style_type].priceColor
data.Theme = res.show_style_type
data.banner_icon = res.banner_icon
data.banner_rank = res.banner_rank
}
// 轮播图,首页推荐位
const getList = async () => {
await get('/api/app/index', { shop_id: 1, from: 1 }).then((res) => {
data.swiperList = res.data.banners
data.loading2 = false
recommendList.value = res.data.showcases
remmendList.value = res.data.groups
remmendList.value.unshift({
id: '',
name: '全部商品'
})
})
}
const getSubsetList = async () => {
await get('/api/app/banner', { channel: 4 }).then((res) => {
groupList.value = res.data
data.loading3 = false
})
}
// 轮播图跳转
function onSwiperItem(url, id) {
if (url) {
if(url.indexOf('type=category') !== -1) {
uni.navigateTo({ url: '/pages/lotRecom/index?' + url.split('?')[1] })
}else if(url.indexOf('type=shop_group') !== -1) {
uni.navigateTo({ url: '/pages/subset/index?' + url.split('?')[1] })
} else {
uni.navigateTo({ url: url })
}
// uvRecord(id)
}
}
// 搜索
function toSearch() {
uni.navigateTo({
url: '/pages/search/index'
})
}
function openTabs() {
data.showDown = !data.showDown
}
// 记录访客
const recordVisitor = () => {
get('/api/app/user/visitor', {
from: 0
}).then(() => {
})
}
async function getNum() {
await get('/api/v1/carts/num').then((res) => {
data.cartNum = Number(res.data.num)
uni.setStorageSync('cartNum', res.data.num)
})
}
// 获取广告列表
const getAdList = async() => {
await get('/api/app/banner', {channel: 2}).then((res) => {
data.adList = res.data
if(data.shareAdId) {
res.data.forEach((it, index) => {
if(it.id == data.shareAdId) {
onClickAd(it.link, it.top_bar_title, it.id, index)
}
})
}
data.loading1 = false
})
}
// 排行榜单
const getRankList = async() => {
await get('/api/app/banner', {channel: 3}).then((res) => {
rankList.value = res.data
data.loading4 = false
})
}
async function getTypeDateList() {
await get('/api/app/showcase/type/date').then((res) => {
res.forEach((item, index) => {
if(item.day === data.today) {
data.curIndex = index
}
})
data.dateList = res
data.loading5 = false
wx.getSystemInfo({
success(res) {
let width = res.screenWidth
data.scrollRight = res.screenWidth
data.scrollLeft = data.dateList.length * 85 - width
}
})
})
}
function changeDateTab(index) {
data.curIndex = index
data.scrollLeft = index < 3 ? 0 : data.scrollRight
}
const isShowArrow = () => {
uni.getSystemInfo({
success(req) {
let width = req.screenWidth - 20
let query = uni.createSelectorQuery();
query.select('#adbox').boundingClientRect(ress => {
if (ress && ress.width > width) {
data.showArrow = true
} else {
data.showArrow = false
}
}).exec()
}
})
}
function judgeHasNewVip() {
let is_new = uni.getStorageSync('is_new')
if(is_new) {
uni.setStorageSync('is_new', false)
get('/api/v1/shopCoupon', { type: 30 }).then((res) => {
if(res.data.length !== 0) {
data.showVan = true
data.couponInfo = res.data
}
})
}
}
function getGiftsInfo() {
get('/api/v1/user/vip/getNoCheckList').then((res) => {
if(res.data.length != 0) {
data.showGifts = true
data.giftsInfo = res.data[0]
}
})
}
function handleShareInfo(e) {
if(e.split('&&')) {
data.groupShareImg = e.split('&&')[0]
data.groupShareTit = e.split('&&')[1]
}
}
function getZongHe() {
get('/api/app/comprehensive/showcase').then((ress) => {
data.showZongHe = ress.data ? true : false
if(ress.data) {
data.sortType = ress.data.sort_type
data.sort1 = ress.data.sort_type
data.sort3 = ress.data.group_sort_type
getAllGroup()
get('/api/app/group', {parent_id: 0}).then((res) => {
data.classifyList = res.data
})
}
})
}
async function getAllGroup(val = 1) {
data.loading6 = true
let params = {
page: data.page,
pageSize: 20,
sortType: data.sortType
}
await get('/api/app/groupGoods/all', params).then((res) => {
data.zongheList = val == 1 ? data.zongheList.concat(res.data) : res.data
data.lastPage = res.meta.last_page
data.loading6 = false
data.isReachBottom = false
setTimeout(() => {
data.isReachBottom = true
}, 500)
}).catch(() => {
data.loading6 = false
})
}
async function getShopGroup(val = 1) {
data.loading6 = true
let params = {
page: data.page,
pageSize: 20,
sortType: data.sort3,
shop_group_id: data.sortType
}
await get('/api/app/groupGoods/all', params).then((res) => {
data.zongheList = val == 1 ? data.zongheList.concat(res.data) : res.data
data.lastPage = res.meta.last_page
data.loading6 = false
data.isReachBottom = false
setTimeout(() => {
data.isReachBottom = true
}, 500)
}).catch(() => {
data.loading6 = false
})
}
const toPage = (id) => {
uni.navigateTo({ url: '/pages/groups/index?id=' + id })
}
async function changeSort(type, val) {
if(data.sortType != type) {
data.isReachBottom = false
data.sortType = type
data.sortVal = val
data.page = 1
uni.showLoading({
title: '加载中...',
mask: true
})
if(val == 'group') {
await getShopGroup(0)
uni.hideLoading()
uni.pageScrollTo({
selector: '#goods',
offsetTop: 0,
duration: 0
})
} else {
await getAllGroup(0)
uni.hideLoading()
uni.pageScrollTo({
selector: '#goods',
offsetTop: 0,
duration: 0
})
}
}
}
function toRemmend(url, title, id) {
if (url) {
if(url.indexOf('type=category') !== -1) {
uni.navigateTo({ url: '/pages/lotRecom/index?' + url.split('?')[1] })
}else if(url.indexOf('type=shop_group') !== -1) {
uni.navigateTo({ url: '/pages/subset/index?' + url.split('?')[1] })
} else if(url.indexOf('presale/index') !== -1) {
uni.navigateTo({ url: url + '?title=' + title })
} else if(url.indexOf('search-result') !== -1 && url.indexOf('groupId=') !== -1) {
let classId = url.split('groupId=')[1].split('&')[0]
uni.reLaunch({ url: '/pages/classify/new?classId=' + classId })
} else if(url.indexOf('classify/new') !== -1) {
uni.switchTab({ url: url })
} else {
uni.navigateTo({ url: url })
}
// uvRecord(id)
}
}
function hanleRank(link, id) {
if(link) {
if(link.indexOf('type=category') !== -1) {
uni.navigateTo({ url: '/pages/lotRecom/index?' + link.split('?')[1] })
} else if(link.indexOf('type=shop_group') !== -1) {
uni.navigateTo({ url: '/pages/subset/index?' + link.split('?')[1] })
} else {
uni.navigateTo({ url: link })
}
// uvRecord(id)
}
}
function toGoods(goods) {
if (goods.pivot && goods.pivot.path) {
if(goods.pivot.path.indexOf('http') !== -1) {
uni.navigateTo({ url: '/pages/index/link?advUrl=' + encodeURIComponent(goods.pivot.path) })
} else {
uni.navigateTo({ url: goods.pivot.path })
}
} else {
uni.navigateTo({
url: '/pages/groups/index?id=' + goods.id
})
}
}
function toMoreGroup(item) {
if(item.show_more && item.link) {
if(item.link.indexOf('type=category') !== -1) {
uni.navigateTo({ url: '/pages/lotRecom/index?' + item.link.split('?')[1] })
} else if(item.link.indexOf('type=shop_group') !== -1) {
uni.navigateTo({ url: '/pages/subset/index?' + item.link.split('?')[1] })
} else if(item.link.indexOf('classify/new') !== -1 || item.link.indexOf('classify/index') !== -1) {
uni.switchTab({ url: item.link })
} else {
uni.navigateTo({ url: item.link })
}
}
}
async function onNetworkStatusChange(res) {
if(res.isConnected) {
await getStoreInfo()
await getAdList()
await getList()
await getSubsetList()
await getRankList()
await getTypeDateList()
if(whetherLogin()) {
getNum()
// 判断是否有新人优惠券
judgeHasNewVip()
getGiftsInfo()
}
isShowArrow()
getZongHe()
}
}
2025-06-14 10:01:48 +08:00
function computeHeight(e) {
var winWid = wx.getSystemInfoSync().windowWidth
var imgh = e.detail.height
var imgw = e.detail.width
var swiperH = (winWid * imgh / imgw).toFixed(2)
data.swiperH = swiperH
}
2025-05-08 09:16:37 +08:00
return {
2025-06-14 10:01:48 +08:00
userBind,
2025-05-08 09:16:37 +08:00
getOldDay,
remmendList,
whetherLogin,
...toRefs(data),
getStoreInfo,
getList,
groupList,
rankList,
recommendList,
toSearch,
onSwiperItem,
recordVisitor,
getNum,
onClickTab,
backTop,
getAdList,
isShowArrow,
onClickAd,
judgeHasNewVip,
getSubsetList,
handleShareInfo,
getGiftsInfo,
openTabs,
getZongHe,
getAllGroup,
getShopGroup,
toPage,
changeSort,
toRemmend,
getTypeDateList,
changeDateTab,
hanleRank,
toMoreGroup,
getRankList,
getTypeDateList,
toGoods,
2025-06-14 10:01:48 +08:00
onNetworkStatusChange,
computeHeight
2025-05-08 09:16:37 +08:00
}
},
async onLoad(options) {
// await this.$onLaunched
this.Color = uni.getStorageSync('theme_color')
this.bgColor = Style[uni.getStorageSync('theme_index') * 1].bgColor
this.Theme = uni.getStorageSync('theme_index') * 1
uni.onNetworkStatusChange(this.onNetworkStatusChange)
let dayObj = getOldDay('y-m-d', 0)
this.today = Number(dayObj.split('-')[1]) + '/' + Number(dayObj.split('-')[2])
await this.getStoreInfo()
await this.getAdList()
await this.getList()
await this.getSubsetList()
await this.getRankList()
await this.getTypeDateList()
2025-06-14 10:01:48 +08:00
if(whetherLogin()) {
this.getNum()
// 判断是否有新人优惠券
this.judgeHasNewVip()
this.getGiftsInfo()
var parmas = {
from: 0,
s: 0,
u: 0,
scene: '',
company_id: ''
}
this.userBind(parmas)
}
2025-05-08 09:16:37 +08:00
this.isShowArrow()
this.getZongHe()
},
onPullDownRefresh() {
this.getStoreInfo()
this.getList()
this.getSubsetList()
setTimeout(() => {
uni.stopPullDownRefresh()
}, 1000)
},
onPageScroll(e) {
if (e.scrollTop > 300) {
this.showTop = true
} else {
this.showTop = false
}
},
async onShow() {
this.cartNum = Number(uni.getStorageSync('cartNum'))
setTimeout(() => {
this.msgNum = uni.getStorageSync('msgNum') || 0
}, 1500)
this.msgNum = uni.getStorageSync('msgNum') || 0
},
onUnload() {
uni.offNetworkStatusChange(this.onNetworkStatusChange)
},
onReachBottom() {
if(!this.isReachBottom) {
return
}
if (this.page < this.lastPage && this.showZongHe) {
this.page++
if(this.sortVal) {
this.getShopGroup()
} else {
this.getAllGroup()
}
}
}
}
</script>
<style lang="scss" scoped>
.flex{
display: flex;
align-items: center;
justify-content: center;
}
.flex1{
display: flex;
align-items: center;
justify-content: space-between;
}
.tou {
position: sticky;
top: 0;
width: 100%;
left: 0;
background: #fff;
z-index: 99;
.searchBox{
padding: 0 20rpx;
margin-bottom: 10rpx;
font-size: 28rpx;
color: #C7C7C7;
box-sizing: border-box;
.box{
display: flex;
align-items: center;
padding: 0 20rpx;
box-sizing: border-box;
background-color: #F7F8FA;
border-radius: 60rpx;
height: 60rpx;
width: 100%;
}
}
}
.topBox{
position: fixed;
bottom: 15%;
right: 5%;
background: #fff;
width: 80rpx;
height: 80rpx;
border-radius: 50%;
box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.2);
z-index: 101;
}
.border{
position: relative;
font-weight: 600;
&::after{
content: '';
position: absolute;
bottom: -10rpx;
left: 50%;
margin-left: -18rpx;
width: 36rpx;
height: 3px;
background: v-bind('Color');
}
}
.table{
display: flex;
align-items: center;
height: 60rpx;
padding-left: 20rpx;
box-sizing: border-box;
width: calc(100% - 20rpx);
position: relative;
overflow: hidden;
.bbox{
width: calc(100% - 30px);
height: 100%;
overflow-x: auto;
&.man{
width: 100%;
}
}
.adbox{
display: flex;
flex-wrap: nowrap;
white-space: nowrap;
width: fit-content;
height: 100%;
align-items: center;
}
.li {
font-size: 30rpx;
margin-right: 20rpx;
color: #000;
display: inline-block;
}
.assort{
width: 50px;
position: absolute;
padding-left: 10px;
box-sizing: border-box;
right: 0;
height: 100%;
top: 0;
background: linear-gradient(to right, rgba(255, 255, 255, 0.5), #fff 30%);
z-index: 1;
}
}
@keyframes fade {
from {
opacity: 1;
}
50% {
opacity: 0.5;
}
to {
opacity: 1;
}
}
.skeleton {
background: #e1e1e1;
animation: fade 2s infinite;
}
.whole{
2025-06-14 10:01:48 +08:00
background-color: #f5f5f5;
2025-05-08 09:16:37 +08:00
}
.home {
padding-bottom: calc(110rpx + env(safe-area-inset-bottom));
.home-top {
.home-top-swiper {
width: 100%;
.item_img {
width: 100%;
}
}
}
.home-img {
padding: 8rpx 0;
image {
width: 100%;
}
}
.home-text {
display: flex;
justify-content: space-between;
padding: 8rpx 30rpx;
background-color: #fff3f4;
font-size: 0;
.home-text-item {
height: 28rpx;
}
}
}
.noMore{
text-align: center;
font-size: 24rpx;
color: #999;
margin: auto;
padding: 0 0 60rpx;
width: 100%;
}
.loadbox {
padding: 30rpx 0;
text-align: center;
color: #666;
}
.itemBox{
display: flex;
flex-wrap: wrap;
padding-top: 156rpx;
.row{
color: #393939;
font-size: 24rpx;
background-color: #f2f2f2;
border: 1px solid #f2f2f2;
width: 22%;
height: 56rpx;
margin: 0 0 24rpx 2%;
border-radius: 56rpx;
&.active{
background-color: v-bind('bgColor');
border: 1px solid v-bind('Color');
color: v-bind('Color');
}
}
}
.zonghe{
font-size: 28rpx;
margin-top: 16rpx;
.titBox{
display: flex;
align-items: center;
padding: 0 14rpx;
box-sizing: border-box;
position: sticky;
top: 60rpx;
z-index: 100;
white-space: nowrap;
background-color: #fff;
height: 140rpx;
&.z98{
z-index: 98;
}
.row{
text-align: center;
display: inline-block;
height: 100%;
color: #000;
font-size: 30rpx;
padding: 24rpx 0;
box-sizing: border-box;
.tit{
padding: 0 24rpx;
}
.desc{
color: #898989;
font-size: 24rpx;
padding: 0 18rpx;
border-radius: 40rpx;
line-height: 40rpx;
margin-top: 10rpx;
display: inline-block;
&.on{
background-color: v-bind('Color');
color: #fff;
}
}
}
}
.content{
padding: 16rpx 1.5%;
box-sizing: border-box;
display: flex;
flex-wrap: wrap;
.left{
width: 50%;
padding: 0 1.5%;
box-sizing: border-box;
}
.row{
background-color: #fff;
border-radius: 10rpx;
width: 100%;
margin-bottom: 24rpx;
overflow: hidden;
.face_img{
position: relative;
.img{
width: 100%;
height: auto;
vertical-align: bottom;
}
.out{
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
.out_img{
width: 140rpx;
height: 140rpx;
}
}
}
.padd{
padding: 14rpx 24rpx 24rpx;
box-sizing: border-box;
}
.desc{
color: #BF9E6B;
margin-bottom: 10rpx;
font-size: 24rpx;
}
.tit{
overflow: hidden !important;
text-overflow: ellipsis !important;
display: -webkit-box !important;
-webkit-line-clamp: 2 !important;
-webkit-box-orient: vertical !important;
white-space: break-spaces !important;
margin-bottom: 10rpx;
}
.price{
font-size: 30rpx;
color: v-bind('priceColor');
}
}
}
}
.viewMore{
text-align: center;
display: block;
padding: 16rpx 0;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
font-size: 28rpx;
color: #000;
}
.shop-recommend-item-goods .goods-info {
height: auto !important;
}
.shop-recommend-item-goods .goods-info-price {
margin-top: 15rpx !important;
}
.shop-recommend-item-goods .goods-info-name .name{
white-space: normal !important;
height: 80rpx;
line-height: 40rpx;
}
.shop-recommend-item-goods .goods {
margin-bottom: 20rpx;
&.per100{
width: 100%;
margin-right: 0;
margin-bottom: 50rpx;
.face_img{
width: 100%;
height: 300rpx;
margin-bottom: 16rpx;
position: relative;
.img{
width: 100%;
height: 100%;
border-radius: 10rpx;
}
.out{
position: absolute;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
top: 0;
left: 0;
.out_img{
width: 180rpx;
height: 180rpx;
}
}
}
.infotext{
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
.tit{
font-size: 30rpx;
font-weight: bold;
color: #2C2C2C;
width: calc(100% - 300rpx);
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.qiang{
height: 28px;
border-radius: 28px;
box-sizing: border-box;
display: inline-flex;
align-items: center;
justify-content: space-between;
border: 1px solid v-bind('Color');
font-size: 12px;
.priceB{
height: 100%;
padding-left: 10px;
background-color: v-bind('bgColor');
color: v-bind('Color');
border-radius: 26px 0 0 26px;
line-height: 26px;
font-weight: bold;
}
.txt{
display: inline-block;
height: 26px;
padding: 0 10px 0 34px;
border-radius: 0 26px 26px 0;
color: #fff;
background-color: v-bind('Color');
line-height: 26px;
position: relative;
&::after{
position: absolute;
content: '';
left: 0;
top: 0;
width: 26px;
height: 26px;
background-color: v-bind('bgColor');
border-radius: 0 0 26px 0;
}
&::before{
position: absolute;
content: '';
left: 6px;
bottom: 0;
width: 0;
height: 0;
border-top: 4px solid transparent;
border-right: 4px solid transparent;
border-left: 4px solid transparent;
border-bottom: 4px solid v-bind('Color');
z-index: 2;
}
}
}
}
}
}
::v-deep .shop-recommend-item-goods .goods-info-name .name{
overflow: hidden !important;
text-overflow: ellipsis !important;
display: -webkit-box !important;
-webkit-line-clamp: 2 !important;
-webkit-box-orient: vertical !important;
white-space: break-spaces !important;
height: 76rpx;
}
::v-deep .shop-recommend-item-goods .goods-info-name{
overflow: inherit !important;
}
.shop-recommend-item-goods{
padding: 10rpx 24rpx;
}
.shop{
background-color: #fff;
&-group {
display: flex;
flex-wrap: wrap;
width: 100%;
padding: 14rpx 0;
&.per20{
padding: 14rpx 20rpx;
box-sizing: border-box;
.shop-group-item{
width: 20%;
}
.img{
width: 90rpx;
height: 90rpx;
}
.tit{
font-size: 26rpx;
}
}
&-item{
width: 25%;
text-align: center;
padding: 14rpx 0;
.img{
width: 100rpx;
height: 100rpx;
border-radius: 10rpx;
margin-bottom: 7rpx;
}
.tit{
font-size: 28rpx;
color: #2c2c2c;
}
}
}
}
.shop-recommend-item{
padding: 20rpx 0;
&-title{
display: flex;
align-items: center;
justify-content: space-between;
color: #555;
font-size: 24rpx;
padding: 30rpx;
.title{
color: v-bind('Color');
font-size: 32rpx;
font-weight: bold;
}
}
&-img{
.img{
width: 100%;
}
}
&-goods{
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
.goods{
display: flex;
flex-direction: column;
align-items: center;
box-sizing: border-box;
width: 31%;
margin-right: 3.5%;
&:nth-child(3n+3){
margin-right: 0;
}
&-img {
width: 100%;
height: 0;
padding-bottom: 100%;
position: relative;
.img{
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.out{
position: absolute;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
.out_img{
width: 110rpx;
height: 110rpx;
}
}
}
&-info{
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100%;
padding: 15rpx;
box-sizing: border-box;
height: 120rpx;
&-name{
display: flex;
align-items: center;
overflow: hidden;
.tag{
font-size: 24rpx;
color: #fff;
background-color: v-bind('Color');
padding: 0 8rpx;
border-radius: 5rpx;
margin-right: 10rpx;
height: 30rpx;
line-height: 30rpx;
}
.name{
font-size: 28rpx;
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
&-tag {
display: flex;
overflow: auto;
&-item {
font-size: 24rpx;
color: v-bind('Color');
background-color: #fff3f4;
padding: 0 15rpx;
margin-right: 5rpx;
border-radius: 15rpx;
flex-shrink: 0;
}
}
&-price {
display: flex;
justify-content: space-between;
align-items: flex-end;
font-size: 28rpx;
color: #999999;
&-left {
color: v-bind('priceColor');
align-items: center;
text-overflow: ellipsis;
overflow: hidden;
.price {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.icon {
font-size: 24rpx;
}
}
}
}
}
&.two{
.goods{
width: 48%;
margin-right: 4%;
&:nth-child(3n+3){
margin-right: 4%;
}
&:nth-child(2n+2){
margin-right: 0;
}
}
}
}
}
.salebox{
display: flex;
border-top: 16rpx solid #f5f5f5;
border-bottom: 16rpx solid #f5f5f5;
justify-content: space-between;
flex-wrap: wrap;
.row {
width: 50%;
&.per100{
width: 100%;
}
&.per33{
width: 33.33%;
}
.img{
width: 100%;
vertical-align: bottom;
display: block;
}
}
}
.dateRecom{
.dateBox{
display: flex;
align-items: center;
white-space: nowrap;
height: 140rpx;
border-bottom: 1px solid #f5f5f5;
.box{
font-size: 28rpx;
color: #333;
position: relative;
padding: 30rpx 0;
text-align: center;
display: inline-block;
width: 170rpx;
.date{
font-weight: bold;
margin-bottom: 8rpx;
line-height: 1;
font-family: '黑体';
font-size: 32rpx;
}
.text{
line-height: 1;
}
&:after{
content: "";
position: absolute;
display: block;
width: 80rpx;
height: 8rpx;
background-color: v-bind('Color');
bottom: 10rpx;
left: 50%;
margin-left: -40rpx;
border-radius: 6rpx;
opacity: 0;
transform: scaleX(0);
transition: all .3s cubic-bezier(.18,.89,.17,.88),opacity .2s ease;
}
&.active{
&:after{
opacity: 1;
transform: scaleX(1);
}
}
}
}
}
</style>