2813 lines
78 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view>
<up-popup :show="showDialog" :zIndex="200" closeable :round="20" mode="bottom" @close="closeDialog">
<div class="pageBox">
<div class="loadBox" v-if="loading">
<div style="height: 600rpx;" class="box"></div>
<div class="top_box">
<div class="desc box"></div>
<div class="desc box"></div>
</div>
<div class="text_box">
<div class="text box"></div>
<div class="text box"></div>
<div class="text box"></div>
<div class="text box"></div>
<div style="height: 150rpx;" class="box"></div>
<div class="text box"></div>
<div class="text box"></div>
<div class="text box"></div>
<div class="text box"></div>
<div class="text box"></div>
<div class="text box"></div>
<div class="text box"></div>
<div class="text box"></div>
<div class="text box"></div>
<div class="text box"></div>
<div class="text box"></div>
<div class="text box"></div>
<div class="text box"></div>
<div class="text box"></div>
</div>
</div>
<!-- 产品图 -->
<view class="banBox">
<swiper class="swiper" :autoplay="true" :interval="5000" :duration="500" :indicator-dots="true" :circular="true">
<swiper-item>
<image class="item_img" mode="aspectFill" :src="groupInfo.face_img + '?x-oss-process=image/format,webp'" :webp="true">
</image>
</swiper-item>
</swiper>
</view>
<!-- 团购描述 -->
<view class="description" v-if="groupInfo.description">
<text user-select>{{groupInfo.description}}</text>
</view>
<!-- 本团商品 -->
<view class="goods-info">
<template v-if="groupInfo.group_goods && groupInfo.group_goods.length">
<view class="vip_advert" v-if="vip_on == 1 && !is_vip" @tap="to_VipPage">
<img src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2025/05/26/bACLVRl4jIRw77jmz3Mg3Uz64sYk3sR3OR8Ms9l5.png" alt="" class='vip_advert_img'>
</view>
<view class="item" @click="jumpFloor" :class="vip_on == 1 && !is_vip ? '' : 'martop'">
<view class="left">
<text>本团</text>
<text>商品</text>
</view>
<view class="right" @click="jumpFloor">
<block v-for="(goods, index) in groupInfo.group_goods" :key="goods.id">
<view class="right-item">
<image :src="goods.face_img + '?x-oss-process=image/format,webp'" :webp="true" mode="aspectFill"></image>
<view class="right-text">
<view class="text">{{goods.title}}</view>
<view class="vip">
<view v-if="groupInfo.group_goods.length == 1" style="display: flex;white-space: nowrap;align-items: center;">
<!-- 仅显示普通价格:
开启会员功能&&会员价大于0时1、非会员&&不隐藏会员价&&多商品2、非会员&&隐藏会员价
未开启会员&&没有会员价
-->
<template v-if="vipOn && goods.vip_price > 0 && !is_vip && ((vip_price_show && goods.specs_type !== 0) || !vip_price_show)">
<div class="">
<text class="icon">¥</text>
<text v-if="goods.specs_type === 0">{{goods.price}}</text>
<text v-else>
<text v-if="goods.max_price === goods.min_price">{{goods.min_price}}</text>
<text v-else>{{goods.min_price}}<text class="st">起</text></text>
</text>
</div>
</template>
<template v-else-if="!vipOn || !goods.vip_price">
<div>
<text class="icon">¥</text>
<text v-if="goods.specs_type === 0">{{goods.price}}</text>
<text v-else>
<text v-if="goods.max_price === goods.min_price">{{goods.min_price}}</text>
<text v-else>{{goods.min_price}}<text class="st">起</text></text>
</text>
</div>
</template>
<!-- 仅显示会员价:
开启会员功能&&会员价大于0&&是会员&&多商品
-->
<template v-else-if="vipOn && goods.vip_price > 0 && is_vip && goods.specs_type !== 0">
<view class="vip-tag"><text>会员&nbsp;¥</text>{{goods.vip_price}}</view>
</template>
<!-- 显示会员价与普通价格:
开启会员功能&&会员价大于0&&((是会员&&单商品)|| (非会员&&显示会员价&&单商品))
-->
<template v-else-if="vipOn && goods.vip_price > 0 && ((is_vip && goods.specs_type === 0) || (!is_vip && vip_price_show && goods.specs_type === 0))">
<div class="black" style="margin-right: 10rpx;">
<text class="icon">¥</text>
<text v-if="goods.specs_type === 0">{{goods.price}}</text>
<text v-else>
<text v-if="goods.max_price === goods.min_price">{{goods.min_price}}</text>
<text v-else>{{goods.min_price}}<text class="st">起</text></text>
</text>
</div>
<view class="vip-tag"><text>会员&nbsp;¥</text>{{goods.vip_price}}</view>
</template>
<template v-else>
<div class="" style="display: inline-block;">
<text class="icon">¥</text>
<text v-if="goods.specs_type === 0">{{goods.price}}</text>
<text v-else>
<text v-if="goods.max_price === goods.min_price">{{goods.min_price}}</text>
<text v-else>{{goods.min_price}}<text class="st">起</text></text>
</text>
</div>
</template>
</view>
<view v-else style="display: flex;white-space: nowrap;align-items: center;">
<!-- 仅显示普通价格:
开启会员功能&&会员价大于0时1、非会员&&不隐藏会员价&&多商品2、非会员&&隐藏会员价
未开启会员&&没有会员价
-->
<template v-if="vipOn && goods.vip_price > 0 && !is_vip && ((vip_price_show && goods.specs_type !== 0) || !vip_price_show)">
<text class="icon">¥</text>
<text v-if="goods.specs_type === 0">{{goods.price}}</text>
<text v-else>
<text v-if="goods.max_price === goods.min_price">{{goods.min_price}}</text>
<text v-else>{{goods.min_price}}<text class="st">起</text></text>
</text>
</template>
<template v-else-if="!vipOn || !goods.vip_price">
<text class="icon">¥</text>
<text v-if="goods.specs_type===0">{{goods.price}}</text>
<text v-else>
<text v-if="goods.max_price === goods.min_price">{{goods.min_price}}</text>
<text v-else>{{goods.min_price}}<text class="st">起</text></text>
</text>
</template>
<!-- 仅显示会员价:
开启会员功能&&会员价大于0&&是会员&&多商品
-->
<template v-else-if="vipOn && goods.vip_price > 0 && is_vip && goods.specs_type !== 0">
<text>¥{{goods.vip_price}}</text>
</template>
<!-- 显示会员价与普通价格:
开启会员功能&&会员价大于0&&((是会员&&单商品)|| (非会员&&显示会员价&&单商品))
-->
<template v-else-if="vipOn && goods.vip_price > 0 && ((is_vip && goods.specs_type === 0) || (!is_vip && vip_price_show && goods.specs_type === 0))">
<div class="black" style="margin-right: 10rpx;">
<text class="icon">¥</text>
<text v-if="goods.specs_type === 0">{{goods.price}}</text>
<text v-else>
<text v-if="goods.max_price === goods.min_price">{{goods.min_price}}</text>
<text v-else>{{goods.min_price}}<text class="st">起</text></text>
</text>
</div>
<view class="vip-tag"><text>会员&nbsp;¥</text>{{goods.vip_price}}</view>
</template>
<template v-else>
<text class="icon">¥</text>
<text v-if="goods.specs_type === 0">{{goods.price}}</text>
<text v-else>
<text v-if="goods.max_price === goods.min_price">{{goods.min_price}}</text>
<text v-else>{{goods.min_price}}<text class="st">起</text></text>
</text>
</template>
</view>
</view>
</view>
</view>
</block>
</view>
</view>
</template>
<view class="rankBox flex4"
v-if="groupInfo.shop && groupInfo.shop.extendInfo && groupInfo.shop.extendInfo.top_of_shop_group_goods && groupInfo.top_on_shop_group && groupInfo.top_on_shop_group.shop_group"
@click="toPage('/pages/mine/other/ranking?id=' + groupInfo.top_on_shop_group.shop_group_id, 1)">
<view class="text flex">
<view class="icon" :style="{backgroundImage: 'url(' + sp2 + ')'}"></view>&nbsp;{{groupInfo.top_on_shop_group.shop_group.name}}热销榜&nbsp;&nbsp;&nbsp;<text>第{{groupInfo.top_on_shop_group.sort}}名</text>
</view>
<up-icon name="arrow-right" color="#999" />
</view>
<template v-if="groupInfo.status !== 3 && groupInfo.group_goods && groupInfo.group_goods.length">
<view class="time">
<view class="time-item" style="display: flex; align-items: center;">
<text class="title" style="padding: 0;">{{groupInfo.created_at}} 发布</text>
<text class="boder"></text>
<view class="text" v-if="endtime">
<up-count-down use-slot :time="endtime" @change="offTimeChange" @finish="offtimeFinish">
<text>距下架还剩</text>
<text v-if="offtimeData.days > 0">{{ offtimeData.days }}天</text>
<text>{{ offtimeData.hours }}时</text>
<text>{{ offtimeData.minutes }}分</text>
<text>{{ offtimeData.seconds }}秒</text>
</up-count-down>
</view>
<view class="text" v-if="groupInfo.sold_status === 0 && startTime">
<text>{{parseTime(groupInfo.sold_start_time)}}开团</text>
</view>
</view>
<view class="time-item" v-if="is_show_sales">
<text class="title">{{groupInfo.visitor * 1 + groupInfo.virtual_visitor * 1}}人查看</text>
<text class="boder"></text>
<text>{{total}}次跟团</text>
</view>
<view class="red_label" v-if="groupInfo.red_status === 1">
<template v-if="groupInfo.is_receive_red">
<view class="red_col red_col1">本团专享红包{{groupInfo.red_amount}}元</view>
<view class="red_col red_col2 disable">已领</view>
</template>
<template v-else-if="groupInfo.is_red_could_receive">
<view class="red_col red_col1 receive1">本团专享红包{{groupInfo.red_amount}}元</view>
<view class="red_col red_col2 receive2" @click="showRedPaper = true">领取</view>
</template>
</view>
<view class="couBox">
<view class="itm" v-for="it in groupCoupons" :key="it.id">
<view class="sign flex">¥<text class="money">{{it.amount * 1}}</text></view>
<view class="mid">
<view v-if="it.scene_type == 2" class="tit">新人劵减{{it.amount * 1}}元</view>
<template v-else>
<view class="tit" v-if="it.type == 13">满{{it.full_amount * 1}}元立减{{it.amount * 1}}</view>
<view class="tit" v-else>无门槛</view>
</template>
<text>领取后{{it.valid_days}}天内有效</text>
</view>
</view>
</view>
</view>
</template>
</view>
<!-- 团购详情 -->
<view class="edition">
<template v-for="itm in textModules" :key="itm.id">
<view class="edition_box" :class="groupInfo.pic_padding_type ? '' : 'verbtm'" v-if="itm.type == 1 && (is_crop_user || (!is_crop_user && !itm.only_crop))">
<template v-for="(imgs, index) in itm.imgs" :key="index">
<image :src="imgs + '?x-oss-process=image/format,webp'" :webp="true" mode="widthFix" style="width:100%;" @click="preViewImg(imgs, $event)" :lazy-load="true"></image>
</template>
</view>
<view class="edition_box" v-if="itm.type == 2 && (is_crop_user || (!is_crop_user && !itm.only_crop))">
<view class="small_img">
<view v-for="(it, index) in itm.img" :key="index" class="imgs">
<image :src="it + '?x-oss-process=image/format,webp'" :webp="true" mode="aspectFill" @click="viewSmallImg(itm.img, it)"></image>
</view>
</view>
</view>
<view class="edition_box" v-if="itm.type == 3 && (is_crop_user || (!is_crop_user && !itm.only_crop))">
<view class="background flex">
<up-icon name="play-right-fill" size="42" color="#fff" @click="viewVideo(itm.video_convert || itm.video[0], $event)" />
</view>
<image :src="itm.video_img" mode="widthFix" style="width:100%"></image>
</view>
<view class="edition_box text1_box" v-if="itm.type == 4 && (is_crop_user || (!is_crop_user && !itm.only_crop))">
<rich-text :nodes="parseText(itm.text)" :user-select="true"></rich-text>
</view>
<view class="baseInfo" v-if="itm.type == 5 && (is_crop_user || (!is_crop_user && !itm.only_crop))">
<view class="tit"><up-icon name="grid" size="22" :color="Color" />&nbsp;&nbsp;基础信息</view>
<view>
<view class="row" v-if="itm.spmc"><view class="txt"><view class="span">商品名称</view></view><text>{{itm.spmc}}</text></view>
<view class="row" v-if="itm.spgg"><view class="txt"><view class="span">商品规格</view></view><text>{{itm.spgg}}</text></view>
<view class="row" v-if="itm.plb"><view class="txt"><view class="span">配料表</view></view><text>{{itm.plb}}</text></view>
<view class="row" v-if="itm.yfyl"><view class="txt"><view class="span">用法用量</view></view><text>{{itm.yfyl}}</text></view>
<view class="row" v-if="itm.cz"><view class="txt"><view class="span">材质</view></view><text>{{itm.cz}}</text></view>
<view class="row" v-if="itm.scrq"><view class="txt"><view class="span">生产日期</view></view><text>{{itm.scrq}}</text></view>
<view class="row" v-if="itm.bzq"><view class="txt"><view class="span">保质期</view></view><text>{{itm.bzq}}</text></view>
<view class="row" v-if="itm.cd"><view class="txt"><view class="span">产地</view></view><text>{{itm.cd}}</text></view>
<view class="row" v-if="itm.fhd"><view class="txt"><view class="span">发货地</view></view><text>{{itm.fhd}}</text></view>
<view class="row" v-if="itm.fhwl"><view class="txt"><view class="span">发货物流</view></view><text>{{itm.fhwl}}</text></view>
<view class="row" v-if="itm.bfhqy"><view class="txt"><view class="span">不发货区域</view></view><text>{{itm.bfhqy}}</text></view>
<view class="row" v-if="itm.jyfqy"><view class="txt"><view class="span">加运费区域</view></view><text>{{itm.jyfqy}}</text></view>
<view class="row" v-if="itm.fhsx"><view class="txt"><view class="span">发货时效</view></view><text>{{itm.fhsx}}</text></view>
<view class="row" v-if="itm.shzc"><view class="txt"><view class="span">售后政策</view></view><text>{{itm.shzc}}</text></view>
</view>
</view>
<view class="lightBox" v-if="itm.type == 6 && itm.text && (is_crop_user || (!is_crop_user && !itm.only_crop))">
<view class="tit"><text class="iconfont icon-lighting"></text>&nbsp;&nbsp;温馨提示</view>
<view class="txt">
<rich-text :nodes="parseText(itm.text)" :user-select="true"></rich-text>
</view>
</view>
</template>
</view>
<!-- 团购商品 -->
<view class="goods-group" id="goodsGroup" v-if="groupInfo.types && groupInfo.types.length > 0">
<view class="tit_msg">本团商品
<template v-if="groupInfo.limit_type === 1">{{groupInfo.start_sale_num}}件起购</template>
<template v-if="groupInfo.limit_type === 2">限购{{groupInfo.limit}}件</template>
<template v-if="groupInfo.actives && groupInfo.actives.length">
<view v-for="(it, i) in groupInfo.actives" class="move_img" :key="i">{{it.name}}</view>
</template>
</view>
<view class="bbox" id="container">
<view class="goodBox">
<view v-for="(t_item, i) in groupInfo.types" :key="t_item.id">
<block v-for="goods in t_item.list" :key="goods.id">
<view class="goods-item" v-if="t_item.id > 0">
<template v-if="goods.specs_type === 1">
<view class="left" @click="getGoodsSkus(goods)">
<view class="tip" v-if="goods.goods.stock <= 0">已抢光</view>
<image class="img" :src="goods.face_img" mode="aspectFill"></image>
</view>
</template>
<template v-else>
<view class="left">
<view class="tip" v-if="goods.goods.stock <= 0">已抢光</view>
<image class="img" :src="goods.face_img" mode="aspectFill"></image>
<view class="tag" v-if="goods.goods.is_gift == 1">赠品</view>
</view>
</template>
<view class="right">
<view @click="getGoodsSkus(goods)">
<view class="title">
<view class="kuajing" v-if="goods.goods.is_cross_border === 1">跨境包税</view>
<view class="kuajing" v-else-if="goods.goods.overseas_direct_mail === 1">海外直邮</view>{{goods.title}}
</view>
<view>
<span v-if="goods.goods.limit_type == 1" class="box_number1">{{goods.goods.start_sale_num}}件起购</span>
<span v-if="goods.goods.limit_type == 2" class="box_number1">限购{{goods.goods.limit}}件</span>
</view>
<view class="flex4" style="padding: 10rpx 0;">
<span class="tites" v-if="show_stock === 1">库存:{{goods.goods.stock <= 0 ? 0 : goods.goods.stock}}</span>
<text class="total" v-if="is_show_sales && groupInfo.copy_shared_on === 0">已团{{goods.sales + (goods.goods.virtual_sales * 1)}}</text>
<text class="total" v-if="is_show_sales && groupInfo.copy_shared_on === 1">已团{{goods.goods.sales + (goods.goods.virtual_sales * 1)}}</text>
</view>
</view>
<view class="flex4">
<view style="display: flex;align-items: center;flex-wrap: wrap;">
<!-- 会员下普通价格 -->
<view class="text text2" v-if="vipOn && goods.vip_price > 0 && (is_vip || (!is_vip && vip_price_show))">
<view class="price">
<text class="icon">¥</text>
<text v-if="goods.specs_type === 0">{{goods.price * 1}}</text>
<text v-else>
<text v-if="goods.max_price === goods.min_price">{{goods.min_price * 1}}</text>
<text v-else>{{goods.min_price * 1}}<text class="st">起</text></text>
</text>
</view>
</view>
<view class="text">
<!-- 显示会员价 -->
<view v-if="vipOn && goods.vip_price > 0 && (is_vip || (!is_vip && vip_price_show))" class="vip">
<view class="vip-tag"><text>会员&nbsp;¥</text>{{goods.vip_price * 1}}</view>
</view>
<!-- 显示普通价格 -->
<view v-else class="vip">
<view class="price">
<text class="icon">¥</text>
<text v-if="goods.specs_type === 0">{{goods.price * 1}}</text>
<text v-else>
<text v-if="goods.max_price === goods.min_price">{{goods.min_price * 1}}</text>
<text v-else>{{goods.min_price * 1}}<text class="st">起</text></text>
</text>
</view>
</view>
</view>
</view>
<template v-if="goods.show2 && goods.goods.is_gift == 0">
<text class="right1" :class="(goods.goods.stock <= 0 || !can_buy) ? 'dis' : ''"
v-if="groupInfo.status !== 3 && groupInfo.sold_status !== 2"
@click="(goods.goods.stock > 0 && can_buy) ? getGoodsSkus(goods) : ''">加入购物车</text>
</template>
<template v-if="goods.show1 && goods.goods.is_gift == 0">
<up-number-box
v-model="goods.num"
:min="goods.goods.limit_type == 1 ? parseInt(goods.goods.start_sale_num) : goods.goods.limit_type == 0 ? 1 : 1"
:max="goods.goods.limit_type == 2 ? parseInt(goods.goods.limit) : goods.goods.limit_type == 0 ? (goods.goods.stock <= 0 ? 0 : goods.goods.stock) : 0"
@overlimit="plusBtn(goods.goods.limit_type == 1 ? 0 : goods.goods.limit_type == 2 ? 1 : 2, goods.num, goods.goods.limit, (goods.goods.stock <= 0 ? 0 : goods.goods.stock))"
disabledInput
bgColor="#f2f3f5"
:longPress="false"
:asyncChange="true"
@change="changeNumOne($event, goods)">
</up-number-box>
</template>
</view>
</view>
</view>
</block>
</view>
</view>
</view>
</view>
<!-- 评价 -->
<view class="commentBox" v-if="commentTotal > 0">
<view class="toptitle flex4">
<text class="num">宝贝评价({{commentTotal}})</text>
<view class="more" @click="toPage(`/pages/groups/comment?id=${groupId}&is_show_sales=${is_show_sales}`, 1)">
好评率{{goodCommentRate}}<up-icon name="arrow-right" color="#444" size="14" />
</view>
</view>
<view class="commentlist">
<view class="item" v-for="itm in commentList" :key="itm.id">
<view class="itemtop">
<view class="user">
<image :src="itm.user.avatar" class="avatar"></image>
<view class="right">
<view>
<text class="name">{{itm.user && itm.user.nickname}}</text>
<text class="border">已购{{itm.report && itm.report.total_trade_count}}次</text>
</view>
<view class="rate">
<view class="star" v-for="i in 5" :key="i">
<up-icon v-if="i <= Math.ceil(itm.stars)" name="star-fill" color="#FFD81E" size="14" />
<up-icon v-else name="star" color="#ccc" size="14" />
</view>
</view>
</view>
</view>
<view class="date">{{itm.date.replace(/-/g, '/')}}发布于{{provTxt[itm.order.province_id]}}</view>
</view>
<view v-if="itm.item.sku_name" style="font-size: 24rpx;color: #999;margin-top: 16rpx;">
规格:{{itm.item.sku_name}}
</view>
<view class="text">{{itm.comment}}</view>
<div class="box_zong" v-if="itm.material.length">
<view class="box_imgs" v-for="(it, index) in itm.material" :key="index">
<div v-show="index < 3">
<image :src="it.url" mode="aspectFill" v-if="it.type === 1" @click="hanleImgs(it, itm.material)"></image>
</div>
</view>
</div>
</view>
</view>
</view>
<!-- 跟团记录 -->
<view class="recordBox" v-if="total > 0">
<view class="title">跟团记录</view>
<view class="list">
<view class="item" v-for="(item, index) in buyList" :key="item.id">
<text class="id" v-if="is_show_sales">{{total - index}}</text>
<image v-if="item.user" :src="item.user.avatar"></image>
<view class="text">
<view class="">{{item.buy_time}}<text class="border" v-if="item.purchase_count * 1 > 1">购买{{item.purchase_count }}次</text></view>
<view class="bottom">
<view class="name">
<text>{{item.goods_name}}</text>
<text v-if="item.sku_name">{{item.sku_name}}</text>
</view>
<text class="num">{{' +' + item.number}}</text>
</view>
</view>
</view>
</view>
<view class="more" v-if="page < lastPage" @click="moreRecord">查看更多<up-icon name="arrow-down" /></view>
</view>
<view style="height: 220rpx;"></view>
<!-- 查看商品 -->
<view class="viewBox" v-show="showJump && imageList.length" @click="jumpFloor()">
<swiper class="swiperBox" :autoplay="true" :interval="3000" :duration="500" :indicator-dots="false" :circular="true" @change="swiperChange">
<swiper-item v-for="(it, index) in imageList" :key="index">
<image class="img" :src="it" mode="aspectFill"></image>
</swiper-item>
</swiper>
<view class="num" v-if="imageList.length > 1">{{swiperIndex + 1}}</view>
<view class="text">查看商品</view>
</view>
<!-- 购买提示信息 -->
<view class="payTips" v-if="(endtime && offtimeData.days == 0) || (groupInfo.limit_type == 1 && cartNum < groupInfo.start_sale_num && cartNum > 0)">
<swiper class="swiper" :autoplay="true" :interval="5000" :duration="500" :indicator-dots="false" :circular="true" :vertical="true">
<swiper-item v-if="endtime && offtimeData.days == 0">
<view class="timeTips flex3">
<up-icon name="clock-fill" color="#f66d2d" />&nbsp;
<up-count-down use-slot :time="endtime">
<text>距下架还剩</text>
<text>{{ offtimeData.days }}</text>
<text>{{ offtimeData.hours }}</text>
<text>{{ offtimeData.minutes }}</text>
<text>{{ offtimeData.seconds }}</text>
</up-count-down>
</view>
</swiper-item>
<swiper-item v-if="groupInfo.limit_type == 1 && cartNum < groupInfo.start_sale_num && cartNum > 0">
<view class="timeTips flex">
<up-icon name="bell-fill" color="#f66d2d" />&nbsp;
<text>尚未满足起购件数{{groupInfo.start_sale_num}}件起购</text>
</view>
</swiper-item>
</swiper>
</view>
</div>
<view class="fixedBox">
<view class="row" @click="toPage('/pages/index/index')">
<up-icon name="home" size="22" />
<view>首页</view>
</view>
<view class="row" @click="showService = true">
<up-icon name="kefu-ermai" size="22" />
<view>客服</view>
</view>
<view class="row" @click="openCart()">
<view class="badge" v-if="number">{{number}}</view>
<up-icon name="shopping-cart" size="24" />
<view>购物车</view>
</view>
<template v-if="groupInfo.group_goods && groupInfo.group_goods.length !== 0">
<!-- 开团中-开团隐藏 -->
<view class="btn flex3" :class="can_buy ? '' : 'disabled'" @click="can_buy ? toPay() : ''" v-if="groupInfo.status !== 3 && groupInfo.sold_status === 1 && parseInt(groupInfo.total_stock) > 0">
<!-- 没有购买记录且购物车无商品 -->
<view class="aux" v-if="cartPrice * 1 == 0 && total < 4">
<text class="large">跟团购买</text>
</view>
<!-- 没有购买记录且购物车有商品 -->
<view class="aux" v-else-if="cartPrice * 1 > 0 && total < 4" style="flex-direction: column;">
<view class="price">
<view class="mid" v-if="discountAmount">券后</view>
<view class="icon">¥</view>
<text class="txt">{{cartPrice * 1}}</text>
<text v-if="discountAmount" class="yh">&nbsp;共优惠¥{{discountAmount}}</text>
</view>
<view class="mid">{{discountAmount ? '立即抢购' : '跟团购买'}}</view>
</view>
<!-- 有购买记录且购物车无商品 -->
<view class="aux" v-else-if="cartPrice * 1 == 0 && total > 3">
<view class="scrBox">
<view class="row" v-for="(it, index) in avatarsList" :key="index"
:class="isAnimate && it.class == 'enter' ? 'enter' : isAnimate && it.class == 'leave' ? 'leave' : isAnimate && it.class == 'animate' ? 'animate' : ''">
<img :src="it.url" alt="" class="img" />
</view>
</view>
<view>
<view class="large">跟团购买</view>
<view class="renshu">{{total}}人已跟团</view>
</view>
</view>
<!-- 有购买记录且购物车有商品 -->
<view class="aux" v-else-if="cartPrice * 1 > 0 && total > 3">
<view class="scrBox">
<view class="row" v-for="(it, index) in avatarsList" :key="index"
:class="isAnimate && it.class == 'enter' ? 'enter' : isAnimate && it.class == 'leave' ? 'leave' : isAnimate && it.class == 'animate' ? 'animate' : ''">
<img :src="it.url" alt="" class="img" />
</view>
</view>
<view>
<view class="price">
<view class="mid" v-if="discountAmount">券后</view>
<view class="icon">¥</view>
<text class="txt">{{cartPrice * 1}}</text>
<text v-if="discountAmount" class="yh">&nbsp;共优惠¥{{discountAmount}}</text>
</view>
<view class="mid">{{discountAmount ? '立即抢购' : '跟团购买'}}</view>
</view>
</view>
<view class="aux" v-else>
<view class="flex">
<text v-if="discountAmount" class="quanhou">券后</text>
<text class="total">¥{{cartPrice}}</text>
<text v-if="discountAmount" class="yh">(共优惠¥{{discountAmount}}</text>
</view>
<text>跟团购买</text>
</view>
</view>
<!-- 开团状态为开团中库存为0 或 开团状态为已结束都显示为到货提醒-->
<view v-else-if="orign_status == 2" class="btn flex3 hui">
<text>已售罄</text>
</view>
<!-- 预览 -->
<view class="btn disabled flex3" v-else-if="groupInfo.status === 3">
<text>团购未发布</text>
</view>
<!-- 未开团-(开团、隐藏) -->
<view class="btn flex3" v-if="groupInfo.status !== 3 && groupInfo.sold_status === 0"
:class="groupInfo.is_subscribe_remind ? 'disabled' : ''">
<view class="item"><text>即将开团</text></view>
<view class="countDown">
<up-count-down use-slot :time="startTime" @change="onTimeChange" @finish="timeFinish">
<text>距开售</text>
<text v-if="timeData.days > 0">{{ timeData.days }}天</text>
<text>{{ timeData.hours }}时</text>
<text>{{ timeData.minutes }}分</text>
<text>{{ timeData.seconds }}秒</text>
</up-count-down>
</view>
</view>
</template>
<!-- 团购没有商品 -->
<view v-else class="btn disabled flex3">
<text>团购已下架</text>
</view>
</view>
</up-popup>
<video-dialog :url="videoUrl" :show="showVideo" @close="showVideo = false"></video-dialog>
<!-- 团购专享红包 -->
<up-overlay :show="showRedPaper" :z-index="999">
<view class="red_paper">
<view class="block">
<view class="close_red_paper" @click="showRedPaper = false">
<up-icon name="close-circle" color="#fff" size="30" />
</view>
<image v-if="showRedOne" src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2023/10/16/UcEFMWggvafmivnSuPtEk2WIAwYdJGy7MdmVXNtr.png?x-oss-process=image/format,webp" :webp="true" mode="widthFix" class='red_paper_img' @click="openRedPaper()"></image>
<template v-if="showRedTwo">
<image src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2022/11/16/0RE5YpTsOMrZdlyO5fgT0tiKGkKpGghsAonyXSsC.png?x-oss-process=image/format,webp" :webp="true" mode="widthFix" class='red_paper_img'></image>
<view class="openbox">
<view class="tit">恭喜获得</view>
<view class="price"><text>{{groupInfo.red_amount}}</text></view>
<view class="text">{{groupInfo.title}}团购活动内下单立减</view>
<view class="btn" @click="showRedPaper = false">立即使用</view>
</view>
</template>
</view>
</view>
</up-overlay>
<!-- 团购购物车 -->
<up-popup :show="showCart" :round="10" mode="bottom" @close="showCart = false" :z-index="200" closeable>
<view class="cartBox">
<view class="Tit">已选{{number}}件商品</view>
<view class="bbox">
<view class="item" v-for="itm in groupCartList" :key="itm.id">
<image :src="itm.goods.pic_url + '?x-oss-process=image/format,webp'" @click="viewSmallImg([itm.goods.pic_url], 0)" :webp="true" mode="aspectFill"></image>
<view class="info">
<view class="around">
<view class="name">
<view class="kuajing" v-if="itm.goods.is_cross_border === 1">跨境包税</view>
<view class="kuajing" v-else-if="itm.goods.overseas_direct_mail === 1">海外直邮</view>{{itm.goods.title}}
</view>
<view v-if="itm.goods.limit_type == 1" class="box_number">{{itm.goods.start_sale_num}}件起购</view>
<view v-if="itm.goods.limit_type == 2" class="box_number">限购{{itm.goods.limit}}</view>
<view class="sku" v-if="itm.shop_goods_sku_id && itm.goods.specs_type && itm.goods.sku">
<text>{{itm.goods.sku.v1}}</text>
<text v-if="itm.goods.sku.v2">-{{itm.goods.sku.v2}}</text>
<text v-if="itm.goods.sku.v3">-{{itm.goods.sku.v3}}</text>
<text v-if="itm.goods.sku.v4">-{{itm.goods.sku.v4}}</text>
</view>
</view>
<view class="price flex4">
<view class="price-left">
<text class="icon"></text>
<text class="text" v-if="is_vip && vip_on === 1 && itm.goods.vip_price > 0">{{itm.goods.vip_price}}</text>
<text class="text" v-else>{{itm.goods.price}}</text>
</view>
<view @click.stop>
<up-number-box
v-model="itm.num"
:min="itm.goods.limit_type == 1 ? parseInt(itm.goods.start_sale_num) : itm.goods.limit_type === 0 ? (itm.goods.stock <= 0 ? itm.num : 0) : 0"
:max="itm.goods.limit_type == 2 ? parseInt(itm.goods.limit) : itm.goods.limit_type == 0 ? (itm.goods.stock <= 0 ? 0 : itm.goods.stock) : (itm.goods.stock <= 0 ? 0 : itm.goods.stock)"
@overlimit="plusCartBtn($event, itm.goods.limit_type, itm.num, itm.goods.limit, (itm.goods.stock <= 0 ? 0 : itm.goods.stock))"
disabledInput
bgColor="#f2f3f5"
:longPress="false"
:asyncChange="true"
@change="changeCartNum($event, itm)">
</up-number-box>
</view>
</view>
</view>
</view>
<view v-if="!groupCartList.length">
<up-empty mode="order" icon="https://ct-upimg.yx090.com/g.ii090/images/sprite/empty/cart.png" text="购物车还是空的"></up-empty>
</view>
</view>
</view>
</up-popup>
<!-- 有任选几件活动并且与起购数量一致sku弹窗 -->
<multiple-sku
:show="showVanSku"
@close="closeSku"
@getnum="getnum"
:show_stock="show_stock"
:specs-num="specsNum"
:goodId="goodId"
:groupId="groupId"
:sourceId="source_id"
:sourceType="source_type"
:sold-status="orign_status"
:remind-stock="groupInfo.is_subscribe_remind_stock"
@remind="goodsRemind">
</multiple-sku>
<direct-pay
:show="showMorePay"
@close="showMorePay = false"
:sourceId="source_id"
:sourceType="source_type"
:show_stock="show_stock"
:groupId="groupId"
:skus_1="skus_1"
:goodId="goodId"
:live_id="liveFrom.live_id"
:streamer_id="liveFrom.streamer_id"
@back="payBack">
</direct-pay>
<!-- 选规格 -->
<choose-sku
:show-sku="showSku"
:skus_1="skus_1"
:sku-info="skuInfo"
@close="closeSku"
:type="type"
@getnum="getnum"
:show_stock="show_stock"
:showDetail="true"
:groupId="groupId"
:sourceId="source_id"
:sourceType="source_type"
:can-buy="can_buy"
:sold-status="orign_status"
:remind-stock="groupInfo.is_subscribe_remind_stock"
@remind="goodsRemind"
:sales="total"
:short-status="shortStatus"/>
<!-- 客服 -->
<call-center :show="showService" @close="showService = false" :type="1" />
</view>
</template>
<script>
import { ref, reactive, toRefs, watch } from 'vue'
import { get, post } from '@/Api/request.js'
import { showToast, parseTime, formatDate, goodsItem } from '@/components/common.js'
import videoDialog from '@/components/videoDialog/index.vue'
import { Style } from '@/utils/list.js'
import { sp2 } from '@/components/img.js'
import { provTxt } from '@/components/scene.js'
import ChooseSku from '@/components/sku/ChooseSku.vue'
import multipleSku from '@/components/sku/multiple.vue'
import directPay from '@/components/sku/directPay.vue'
import callCenter from '@/components/callCenter/index.vue'
export default {
components: {
videoDialog,
ChooseSku,
multipleSku,
directPay,
callCenter
},
props: {
show: {
type: Boolean,
default: false
},
id: {
type: Number,
default: 0
},
live_id: {
type: Number,
default: 0
},
streamer_id: {
type: Number,
default: 0
}
},
setup(props, context) {
const data = reactive({
showDialog: false,
groupId: 0,
textModules: [],
zeroList: [],
groupInfo: {},
userInfo: {},
orign_status: 0,
logo: uni.getStorageSync('logo'),
is_crop_user: uni.getStorageSync('is_crop_user') || false,
Color: uni.getStorageSync('theme_color') || '#F14939',
priceColor: Style[uni.getStorageSync('theme_index') * 1].priceColor,
tagColor: Style[uni.getStorageSync('theme_index') * 1].tagColor,
vip_on: uni.getStorageSync('vip_on') || 0,
is_vip: uni.getStorageSync('is_vip') || false,
vipOn: uni.getStorageSync('vip_on') === 1,
showVideo: false,
videoUrl: '',
endtime: '',
startTime: '',
timeData: {},
offtimeData: {},
is_show_sales: false,
total: 0,
buyList: [],
page: 1,
lastPage: 0,
showRedPaper: false,
showRedOne: true,
showRedTwo: false,
hasReceive: false,
groupCoupons: [],
shortStatus: 1,
can_buy: true,
number: 0,
showVanSku: false,
goodId: 0,
specsNum: 0,
show_stock: 0,
discountAmount: 0,
cartPrice: '0.00',
vip_price_show: uni.getStorageSync('vip_price_show') || false,
cartList: [],
cartNum: 0,
avatarsList: [
{ url: 'https://ct-upimg.yx090.com/ju8hn6/shop/image/94fcfdd8-a998-49ef-a0ed-26405cf7853f_suffix.png', class: 'animate'},
{ url: 'https://ct-upimg.yx090.com/ju8hn6/shop/image/101e86e4-6fab-41cf-ac00-b4bcaa450610_suffix.png', class: 'animate'},
{ url: 'https://ct-upimg.yx090.com/ju8hn6/shop/image/e5ec20d5-d460-45dc-a8bf-79fa84b8ccbb_suffix.png', class: 'animate'}
],
avatarsAll: [
'https://ct-upimg.yx090.com/ju8hn6/shop/image/31b5ee50-2dc4-4d0f-86a8-43d63733b37a_suffix.png',
'https://ct-upimg.yx090.com/ju8hn6/shop/image/b7109d3a-fc56-41f0-8c68-1a68a56ecc17_suffix.png',
'https://ct-upimg.yx090.com/ju8hn6/shop/image/be1ab082-0a3a-4a70-960e-26bb0bfd5385_suffix.png',
'https://ct-upimg.yx090.com/ju8hn6/shop/image/fc7a9b1c-1c72-4d34-b7af-19c2d063b456_suffix.png',
'https://ct-upimg.yx090.com/ju8hn6/shop/image/853263fa-3edc-49f5-8607-7397718c7458_suffix.png',
'https://ct-upimg.yx090.com/ju8hn6/shop/image/e5ec20d5-d460-45dc-a8bf-79fa84b8ccbb_suffix.png',
'https://ct-upimg.yx090.com/ju8hn6/shop/image/ab4ecc1e-f8ef-45d4-a4b8-3d7f8737a928_suffix.png',
'https://ct-upimg.yx090.com/ju8hn6/shop/image/d7f4b8c3-cc9c-4ddc-922a-3a4dce9784c1_suffix.png',
'https://ct-upimg.yx090.com/ju8hn6/shop/image/1c77dc22-4092-49f4-8fda-8467d415c728_suffix.png',
'https://ct-upimg.yx090.com/ju8hn6/shop/image/7aa9622d-bc35-4737-a26e-2be9f579fec7_suffix.png'
],
source: '',
avatarTimer: null,
isAnimate: false,
showDirect: false,
groupCartList: [],
showCart: false,
type: 1,
liveFrom: {
live_id: 0,
streamer_id: 0
},
commentList: [],
goodCommentRate: '',
commentTotal: 0,
source_id: 0,
source_type: 'normal',
showService: false,
showMorePay: false,
showJump: true,
imageList: [],
swiperIndex: 0,
loading: true
})
async function getDetail() {
data.loading = true
uni.showLoading({
title: '加载中',
mask: true
})
await get(`/api/v1/goods/group/detail/${data.groupId}`).then((res) => {
data.userInfo = res.user
data.groupCoupons = res.data.groupCoupons || []
data.can_buy = !res.data.is_new_purchase || (res.data.is_new_purchase && res.user.is_purchase === 0)
// 如果团购为已结束状态,改为和售罄状态一样
data.groupInfo = JSON.parse(JSON.stringify(res.data))
data.orign_status = res.data.sold_status
if(res.data.sold_status == 2) {
data.groupInfo.total_stock = 0
data.groupInfo.group_goods.forEach((it) => {
it.goods.stock = 0
})
}
if(res.data.sold_status == 1 && res.data.total_stock <= 0) {
data.orign_status = 2
}
data.is_show_sales = res.data.is_show_sales === 1
data.show_stock = res.data.shop.show_stock
// 商品短期下架,将商品库存设为0
data.groupInfo.group_goods.forEach((it) => {
if(it.goods && it.goods.short_status == 0) {
it.goods.stock = 0
}
})
data.textModules = res.data.text_modules || []
data.groupInfo.created_at = res.data.created_at.split(' ')[0]
// 开团剩余时间
getSoldOffTime()
// 未到开团时间
getStartTime()
// 分组下商品
let groupGoods = data.groupInfo.group_goods
for (let i = 0; i < groupGoods.length; i++) {
let itm = groupGoods[i]
data.groupInfo.types.forEach((it) => {
if (!it.list) {
it.list = []
}
if (itm.pivot.type_id === it.id) {
if (itm.length > 15 && itm.goods.stock <= 0) {
data.zeroList.push(itm)
} else {
it.list.push(itm)
}
}
})
data.imageList.push(itm.face_img)
}
data.groupInfo.types.forEach((it, i) => {
if(it.list && it.list.length === 0) {
data.groupInfo.types.splice(i, 1)
}
})
if(data.groupInfo.group_goods.length === 0) {
data.groupInfo.types = []
}
if (data.zeroList.length > 0){
data.groupInfo.types.push({
id: 0,
list: data.zeroList
})
}
uni.setNavigationBarTitle({
title: res.data.title
})
sourceId.value = data.source_id
sourceType.value = data.source_type
uni.hideLoading()
data.loading = false
}).catch(() => {
data.loading = false
})
}
function closeDialog() {
data.imageList = []
if(data.avatarTimer) {
clearInterval(data.avatarTimer)
data.avatarTimer = null
}
data.showDialog = false
context.emit('close')
}
const preViewImg = (img, e) => {
uni.previewImage({
urls: [img],
current: 0
})
}
const viewSmallImg = (e, img) => {
uni.previewImage({
urls: e,
current: img
})
}
function parseText(text) {
let reg =/#(.+?)#/g;
let strBr = text.replace(/(\r\n|\n|\r)/gm, '<br />')
let strArr = strBr.match(reg)
if(strArr) {
for (let i = 0; i < strArr.length; i++) {
let txt = '<span style="color: red;">' + strArr[i] + '</span>'
strBr = strBr.replace(strArr[i], txt)
}
strBr = strBr.replace(/#/g, '')
}
return strBr
}
const viewVideo = (video, e) => {
data.showVideo = true
data.videoUrl = video
}
// 跳转会员页
const to_VipPage = () => {
get('/api/v1/shop').then((res) => {
if(res.data.vip_detail_on === 1) {
uni.navigateTo({ url: '/pages/vip/intro/index' })
} else {
uni.navigateTo({ url: '/pages/vip/mine/index' })
}
})
}
const jumpFloor = (time = 300) => {
const el = document.querySelector('#goodsGroup')
if (el) {
el.scrollIntoView({ behavior: 'auto' })
}
}
function onTimeChange(e) {
data.timeData = e
}
function timeFinish() {
data.groupInfo.sold_status = 1
getSoldOffTime()
}
function offTimeChange(e) {
data.offtimeData = e
}
function offtimeFinish() {
data.groupInfo.sold_status = 2
}
function getSoldOffTime() {
if (data.groupInfo.sold_off_time && data.groupInfo.sold_status === 1) {
let endAt = new Date(data.groupInfo.sold_off_time.replace(/-/g, '/')).getTime() // 结束时间
let nowAt = new Date().getTime() // 当前时间
let timestamp = endAt - nowAt //计算时间差
data.endtime = timestamp
}
}
function getStartTime() {
if (data.groupInfo.sold_status === 0 && data.groupInfo.sold_start_time) {
let startAt = new Date(
data.groupInfo.sold_start_time.replace(/-/g, '/')
).getTime() // 开始时间
let nowAt = new Date().getTime() // 当前时间
let timestamp = startAt - nowAt //计算时间差
data.startTime = timestamp
}
}
// 跟团记录
async function getBuyList() {
let res = await get(`/api/v1/goods/record/${data.groupId}`, {
page: data.page,
pageSize: 5
})
res.data.forEach((item) => {
item.buy_time = formatDate(Date.parse(item.created_at.replace(/-/g, '/')))
})
data.buyList = data.buyList.concat(res.data)
data.lastPage = res.meta.last_page
data.total = res.meta.total
}
function toPage(url, type) {
if (type === 1) {
uni.navigateTo({ url })
return
}
uni.switchTab({ url })
}
const getGoodsSkus = (goods) => {
data.shortStatus = goods.goods.short_status
if(goods.specs_type === 0) {
return
}
if(goods.goods.stock <= 0 && goods.specs_type === 0) {
showToast('商品已被抢光了')
return
}
if(data.groupInfo.limit_type === 2 && data.number >= data.groupInfo.limit) {
showToast('本团商品限购' + data.groupInfo.limit + '件')
return
}
if(goods.goods.show_sku_style == 1 || goods.goods.show_sku_style == 2) {
data.specsNum = data.groupInfo.group_goods[0].goods.show_sku_style == 1 ? 2 : 3
data.showVanSku = true
data.goodId = goods.id
} else {
console.log('0.0')
getGoodsSku(goods).then((res) => {
if (goods.specs_type === 0) {
if (data.show_1) {
data.show_1 = false
getCartList()
}
setTimeout(() => {
showToast('已加入购物车')
data.show_1 = true
}, 1000)
}
})
}
}
const {
sourceId,
sourceType,
showSku,
getGoodsSku,
skuInfo,
getNum,
num,
showBtn,
getGoodsSpecs,
skus_1
} = goodsItem()
const getnum = () => {
showBtn.value = true
getStartTime()
getCartList()
getNum()
}
function changeNumOne(e, goods) {
// 减按钮
if(e.value < goods.num && goods.num > 0) {
if (!showBtn.value) {
showBtn.value = true
getStartTime()
}
var num = (goods.num -= 1)
data.cartList.forEach((res) => {
if (res.shop_goods_id === goods.id) {
post(`/api/v1/carts/${res.id}`, {
shop_goods_id: res.shop_goods_id,
shop_goods_sku_id: res.shop_goods_sku_id,
num: num,
shop_group_goods_id: res.shop_group_goods_id,
source_id: data.source_id,
source_type: data.source_type
}, 'PUT').then((res) => {
get('/api/v1/carts', { shop_group_goods_id: data.group_id }).then((res) => {
data.number = res.num
getCartList()
})
})
}
})
} else if(e.value > goods.num) { // 加按钮
if(data.groupInfo.limit_type === 2 && data.number >= data.groupInfo.limit) {
showToast('本团商品限购' + data.groupInfo.limit + '件')
return
}
if (!showBtn.value) {
showBtn.value = true
getStartTime()
}
let num = (goods.num += 1)
data.cartList.forEach((res) => {
if (res.shop_goods_id === goods.id) {
post(`/api/v1/carts/${res.id}`, {
shop_goods_id: res.shop_goods_id,
shop_goods_sku_id: res.shop_goods_sku_id,
num: num,
shop_group_goods_id: res.shop_group_goods_id,
source_id: data.source_id,
source_type: data.source_type
}, 'PUT').then((res) => {
get('/api/v1/carts', {
shop_group_goods_id: data.group_id
}).then((res) => {
data.number = res.num
data.cartPrice = res.total_price
data.discountAmount = res.active_discount_amount * 1
getCartList()
})
})
}
})
}
}
const getCartList = async () => {
let shop_goods = []
await get('/api/v1/carts', {
shop_group_goods_id: data.groupId
}).then((res) => {
data.cartList = res.data
let list = []
let num = 0
res.data.forEach((itm) => {
shop_goods.push({
num: itm.num,
shop_goods_id: itm.shop_goods_id,
shop_goods_sku_id: itm.shop_goods_sku_id,
shop_group_goods_id: itm.shop_group_goods_id,
source_id: 0,
source_type: "normal"
})
if(itm.goods.status !== 1 || itm.goods.sold_status == 2 || (itm.goods.sku && itm.goods.sku.stock <= 0)){
} else {
num += itm.num
list.push(itm)
}
})
data.cartNum = num
data.groupCartList = list
data.number = list.length
isRepeat()
})
if(shop_goods.length) {
let params = {
shop_id: 1,
shop_goods: shop_goods,
address: null,
purchase_vip: 0,
use_coupons: [],
gift_goods_ids: null,
score_cash: 0
}
post('/api/v1/order/check', params).then((res) => {
data.cartPrice = res.data.sum.total_price
data.discountAmount = res.data.sum.total_discount_amount * 1
})
} else {
data.cartPrice = '0.00'
data.discountAmount = 0
}
}
const isRepeat = () => {
var list = []
data.groupInfo.group_goods && data.groupInfo.group_goods.forEach((element, index) => {
list.push(element.id)
data.cartList.forEach((item) => {
if (element.id === item.shop_goods_id) {
element.num = item.num
}
})
})
data.cartList.forEach((item) => {
list.push(item.shop_goods_id)
})
Array.prototype.duplicate = function() {
let tmp = []
this.concat().sort().sort(function(a, b) {
if (a == b && tmp.indexOf(a) === -1) tmp.push(a)
})
return tmp
}
data.groupInfo.group_goods && data.groupInfo.group_goods.forEach((element) => {
if (list.duplicate().includes(element.id)) {
if (element.specs_type === 0) {
element.show1 = true
} else {
element.show2 = true
}
} else {
element.show2 = true
}
if (element.show1 === element.show2) {
element.show2 = false
}
})
}
const plusBtn = (number, index, e, sock) => {
if (number == 0) {
showToast('该商品不能低于起购件数')
} else if (number == 1) {
if (index == e) {
showToast('已达到商品限购件数')
} else if (index > e) {
showToast('已达到商品限购件数')
} else if (index != e) {
showToast('该商品不能低于1件')
}
} else {
if (sock <= 1) {
showToast('已达到该商品最大件数')
} else {
showToast('该商品不能低于1件')
}
}
}
function closeSku(val) {
data.type = 1
showSku.value = false
data.showVanSku = false
}
function goodsRemind(flag) {
data.groupInfo.is_subscribe_remind_stock = flag
}
const getComment = () => {
get(`/api/v1/goods/comment/${data.groupId}`, {
pageSize: 2,
page: 1,
type: 1,
is_home: 1
}).then((res) => {
data.commentList = res.data
data.goodCommentRate = res.goodCommentRate
data.commentTotal = !data.is_show_sales && res.meta.total > 20 ? 20 : res.meta.total
})
}
const hanleImgs = (e, list) => {
let img = []
list.forEach((res) => {
if (res.type == 1) {
img.push(res.url)
}
})
if (e.type === 1) {
uni.previewImage({
current: e.url,
urls: img
})
} else {
data.showVideo = true
data.videoUrl = e.url
}
}
function moreRecord() {
data.page += 1
getBuyList()
}
function openCart() {
if(data.showCart) {
data.showCart = false
} else {
if(data.number) {
data.showCart = true
} else {
showToast('请选择商品')
jumpFloor(0)
}
}
}
function avatarAnimate() {
setTimeout(() => {
let length = data.avatarsList.length
data.avatarsList[length - 1].class = 'leave'
let index = Math.floor(Math.random() * 10)
let st = {
class: 'enter',
url: data.avatarsAll[index]
}
data.avatarsList.unshift(st) // 顶部添加
data.isAnimate = true
setTimeout(() => {
data.isAnimate = false
data.avatarsList.pop() // 尾部移除
data.avatarsList[0].class = 'animate'
}, 500)
}, 1000)
}
const plusCartBtn = (number, index, e, sock) => {
if (number == 0) {
} else if (number == 1) {
if (index == e) {
showToast('已达到商品限购件数')
} else if (index > e) {
showToast('已达到商品限购件数')
} else if (index != e) {
showToast('该商品不能低于1件')
}
} else {
if (sock <= 1) {
showToast('已达到该商品最大件数')
} else {
showToast('该商品不能低于1件')
}
}
}
function changeCartNum(e, itm) {
if(e.value == 0) {
itm.num = 1
uni.showModal({
title: '提示',
content: '确认删除该商品吗?',
confirmColor: '#42b983',
success(res) {
if (res.confirm) {
post('/api/v1/carts/' + itm.id, {}, 'DELETE').then((res) => {
getCartList()
getNum()
})
}
}
})
} else {
itm.num = e.value
post('/api/v1/carts/' + itm.id, {
shop_goods_id: itm.shop_goods_id,
shop_goods_sku_id: itm.shop_goods_sku_id,
num: itm.num,
shop_group_goods_id: itm.shop_group_goods_id,
source_id: 0,
source_type: 'normal'
}, 'PUT').then(() => {
getCartList()
getNum()
})
}
}
// 直接购买
async function toPay() {
let num = 0
if (data.cartList.length > 0) {
let cartList = []
for (let i = 0; i < data.cartList.length; i++) {
let obj = data.cartList[i]
if(obj.goods.status !== 1 || obj.goods.sold_status == 2 || (obj.goods.sku && obj.goods.sku.stock <= 0)){
} else {
num += obj.num
cartList.push(obj)
}
}
if(cartList.length) {
if(data.groupInfo.limit_type == 1 && num < data.groupInfo.start_sale_num) {
showToast('距离起购件数还差' + (data.groupInfo.start_sale_num - num) + '件')
jumpFloor()
if (data.groupInfo.group_goods.length === 1 && data.groupInfo.group_goods[0].specs_type == 1) {
data.type = 2
getGoodsSku(data.groupInfo.group_goods[0])
}
} else {
uni.setStorageSync('shopGoods', cartList)
// uni.navigateTo({
// url: '/pages/pay/index?type=1&source=' + data.source + '&live_id=' + data.liveFrom.live_id + '&streamer_id=' + data.liveFrom.streamer_id
// })
context.emit('back')
}
}
} else if (data.groupInfo.group_goods.length === 1) {
if (data.groupInfo.group_goods[0].specs_type == 1) {
if(data.groupInfo.group_goods[0].goods.show_sku_style == 1 || data.groupInfo.group_goods[0].goods.show_sku_style == 2) {
data.specsNum = data.groupInfo.group_goods[0].goods.show_sku_style == 1 ? 2 : 3
data.showVanSku = true
data.goodId = data.groupInfo.group_goods[0].id
} else {
// 如果设置了团购起购数量&&没有添加任何商品&&团购仅有一个商品,拉起商品弹窗,否则可直接购买
if(data.groupInfo.limit_type == 1 && data.groupInfo.start_sale_num > 1) {
data.type = 2
getGoodsSku(data.groupInfo.group_goods[0])
} else {
data.goodId = data.groupInfo.group_goods[0].id
data.showMorePay = true
}
}
} else {
if(data.groupInfo.group_goods[0].goods.stock <= 0) {
return showToast('当前商品已经抢光啦')
}
data.goodId = data.groupInfo.group_goods[0].id
data.showMorePay = true
}
} else {
showToast('请选择商品')
jumpFloor()
}
}
function swiperChange(e) {
data.swiperIndex = e.detail.current
}
watch(props, async (newProps) => {
if (newProps.show) {
data.showDialog = true
data.groupId = newProps.id
data.liveFrom = {
live_id: (newProps.live_id || 0) * 1,
streamer_id: (newProps.streamer_id || 0) * 1
}
await getDetail()
getCartList()
getBuyList()
getComment()
data.avatarTimer = setInterval(avatarAnimate, 2000);
}
})
return {
getGoodsSku,
skus_1,
sourceId,
sourceType,
showSku,
skuInfo,
getNum,
num,
closeSku,
showBtn,
provTxt,
...toRefs(data),
getDetail,
closeDialog,
parseText,
preViewImg,
viewSmallImg,
viewVideo,
to_VipPage,
jumpFloor,
onTimeChange,
timeFinish,
offTimeChange,
offtimeFinish,
getStartTime,
getSoldOffTime,
parseTime,
getBuyList,
toPage,
getGoodsSkus,
getnum,
changeNumOne,
getCartList,
plusBtn,
isRepeat,
goodsRemind,
getComment,
hanleImgs,
moreRecord,
openCart,
avatarAnimate,
plusCartBtn,
changeCartNum,
toPay,
swiperChange,
}
}
}
</script>
<style lang="scss" scoped>
::v-deep .u-popup__content{
overflow: hidden;
}
.pageBox{
height: 80vh;
overflow: auto;
position: relative;
.vip-tag{
font-size: 24rpx;
color: #fbe6c3;
background: #353648;
border-radius: 20rpx 0 0 0;
padding: 8rpx 10rpx;
line-height: 1;
}
.banBox{
.swiper {
width: 100%;
height: 600rpx;
.item_img {
width: 100%;
height: 100%;
border-radius: 20px 20px 0 0;
}
}
}
.description {
padding: 0 24rpx;
font-size: 34rpx;
color: #222;
display: inline-block;
font-weight: bold;
line-height: 55rpx;
margin-top: 24rpx;
}
.goods-info {
position: relative;
padding: 1rpx 30rpx 0;
background-color: #fff;
.description {
font-size: 34rpx;
color: #222;
display: inline-block;
font-weight: bold;
line-height: 55rpx;
margin-top: 24rpx;
&.large{
font-size: 48rpx;
line-height: 64rpx;
}
}
.vip_advert {
width: 100%;
height: 67rpx;
margin: 30rpx 0rpx -20rpx;
.vip_advert_img {
width: 100%;
height: 100%;
}
}
.item {
display: flex;
align-items: center;
background: #f7f7f7;
height: 95rpx;
padding: 25rpx 40rpx;
border-radius: 10rpx;
&.martop{
margin-top: 30rpx;
}
.left {
display: flex;
justify-content: center;
flex-direction: column;
font-size: 30rpx;
padding-right: 25rpx;
border-right: 2rpx solid #d9d9d9;
margin-right: 30rpx;
color: #2c2c2c;
white-space: nowrap;
}
.right {
display: flex;
overflow: auto;
flex: 1;
.right-item {
display: flex;
overflow: hidden;
flex-shrink: 0;
padding-right: 24rpx;
}
image {
width: 80rpx;
height: 80rpx;
background: #999999;
border-radius: 10rpx;
margin-right: 20rpx;
}
&-text {
.text {
font-size: 28rpx;
color: #2c2c2c;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
max-width: 230rpx;
}
.vip {
display: flex;
align-items: center;
font-size: 28rpx;
color: v-bind('priceColor');
.icon {
font-size: 24rpx;
}
}
.price {
font-size: 24rpx;
}
}
}
}
.rankBox{
margin-top: 24rpx;
background-color: #f7f7f7;
border-radius: 10rpx;
padding: 24rpx;
.icon{
width: 26px;
height: 26px;
background-repeat: no-repeat;
background-size: 678px 612px;
background-position: -496.5px -204.5px;
transform: scale(0.75);
}
.text{
font-size: 28rpx;
color: #333;
text{
color: v-bind('priceColor');
}
}
}
.time {
margin-top: 30rpx;
padding-bottom: 30rpx;
font-size: 28rpx;
border-bottom: 2rpx solid #efefef;
&-item {
color: #999999;
.title {
height: 40rpx;
padding: 20rpx 0;
box-sizing: border-box;
}
.boder {
display: inline-block;
height: 18rpx;
border-right: 2rpx solid #d1d1d1;
margin: 0 20rpx;
}
.text{
display: flex;
text{
color: v-bind('priceColor');
font-size: 26rpx;
}
}
}
}
}
.edition{
padding: 0 24rpx 24rpx;
margin-top: 24rpx;
.edition_box{
margin: 8rpx 0;
position: relative;
&.verbtm{
margin: 0;
image{
vertical-align: bottom;
}
}
.background{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 1;
image{
width: 30px;
height: 30px;
}
}
.img{
width: 100%;
}
.small_img{
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
.imgs{
width: calc(33% - 11rpx);
height: 220rpx;
margin: 16rpx 16rpx 0 0;
image{
width: 100%;
height: 100%;
object-fit: cover;
}
}
.imgs:nth-child(3n+3){
margin: 16rpx 0 0 0;
}
}
&.text1_box{
margin: 10rpx 0;
line-height: 55rpx;
font-size: 30rpx;
color: #222;
}
.text{
line-height: 55rpx;
font-size: 30rpx;
color: #222;
}
}
}
.baseInfo{
background-color: #FaFaFa;
border-radius: 8rpx;
padding: 0 24rpx;
color: #333;
margin-bottom: 30rpx;
.tit{
font-size: 32rpx;
font-weight: bold;
line-height: 110rpx;
display: flex;
}
.row{
display: flex;
padding: 8rpx 0;
font-size: 30rpx;
line-height: 46rpx;
.txt{
width: 160rpx;
text-align: justify;
text-align-last: justify;
padding-right: 30rpx;
display: flex;
white-space: nowrap;
font-size: 26rpx;
}
.span{
display: inline-block;
text-align: justify;
text-align-last: justify;
width: 100%;
}
text{
flex: 1;
}
&:first-child{
padding-top: 36rpx;
border-top: 1px solid #E7E7E7;
}
&:last-child{
padding-bottom: 36rpx;
}
}
}
.lightBox{
background-color: #FaFaFa;
border-radius: 8rpx;
padding: 0 24rpx;
color: #333;
margin-top: 30rpx;
.tit{
font-size: 32rpx;
font-weight: bold;
height: 110rpx;
border-bottom: 1px solid #e9e9e9;
display: flex;
align-items: center;
.iconfont{
font-size: 42rpx;
color: v-bind('Color');
}
}
.txt{
font-size: 30rpx;
line-height: 54rpx;
padding: 30rpx 0;
}
}
}
.red_paper{
display: flex;
align-items: center;
justify-content: center;
height: 100%;
padding-top: 80rpx;
box-sizing: border-box;
.block{
position: relative;
width: 76%;
.close_red_paper{
position: absolute;
right: 0;
top: -80rpx;
}
.red_paper_img{
width: 100%;
height: auto;
}
.openbox{
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
text-align: center;
padding-top: 25%;
box-sizing: border-box;
.tit{
font-size: 40rpx;
color: #6F3C20;
}
.price{
margin: 30rpx 0;
font-size: 50rpx;
font-weight: bold;
color: #6F3C20;
line-height: 1;
text{
font-size: 100rpx;
}
}
.text{
background: #F14939;
color: #FFDB62;
font-size: 30rpx;
line-height: 40rpx;
padding: 8rpx 20rpx;
max-width: 70%;
display: inline-block;
}
.btn{
color: #F14939;
font-size: 36rpx;
width: 80%;
height: 11.8%;
bottom: 12.3%;
position: absolute;
left: 10%;
display: flex;
align-items: center;
justify-content: center;
}
}
.open{
position: absolute;
width: 120px;
height: 120px;
top: 50%;
left: 50%;
margin-left: -60px;
text-align: center;
animation-name: scaleDraw;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-duration: 2s;
}
@keyframes scaleDraw {
0% {
transform: scale(1);
}
25% {
transform: scale(1.05);
}
50% {
transform: scale(1);
}
75% {
transform: scale(1.05);
}
}
.openbox1{
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
text-align: center;
padding-top: 25%;
box-sizing: border-box;
.price{
margin: 30rpx 0;
font-size: 50rpx;
font-weight: bold;
color: #FC3733;
line-height: 1;
text{
font-size: 100rpx;
}
}
.text{
color: #C17C65;
font-size: 30rpx;
line-height: 40rpx;
padding: 8rpx 20rpx;
display: inline-block;
}
.btn{
color: #F14939;
font-size: 36rpx;
font-weight: bold;
width: 80%;
height: 14.8%;
bottom: 10.3%;
position: absolute;
left: 10%;
display: flex;
align-items: center;
justify-content: center;
}
}
}
}
.red_label{
margin-top: 20rpx;
.red_col{
font-size: 24rpx;
color: #F14939;
padding: 4rpx 14rpx;
background: rgba(241,73,57,0.1);
border: 1px solid #F14939;
display: inline-block;
border-radius: 6rpx;
&.red_col1{
border-right: none;
}
&.red_col2{
border-left: 1px dashed #F14939;
}
&.disable{
opacity: 0.7;
}
&.receive1{
background: linear-gradient(to right , rgba(241,73,57,0.8), #F14939);
color: #fff;
border: none;
}
&.receive2{
background: #F14939;
border: none;
border-left: 1px dashed #fff;
color: #fff;
}
}
}
.couBox{
display: flex;
flex-wrap: wrap;
.itm{
padding: 32rpx 24rpx 32rpx 0;
display: flex;
align-items: center;
background-color: #FFF8F1;
width: 100%;
margin-top: 20rpx;
position: relative;
border-radius: 10rpx;
border: 1px solid #F14939;
&::before{
position: absolute;
left: 25%;
top: -2rpx;
width: 28rpx;
height: 14rpx;
margin-left: -20rpx;
content: '';
background-color: #fff;
border: 1px solid #F14939;
border-top: none;
border-radius: 0 0 14rpx 14rpx;
z-index: 2;
box-sizing: border-box;
}
&::after{
position: absolute;
left: 25%;
bottom: -2rpx;
width: 28rpx;
height: 14rpx;
margin-left: -20rpx;
content: '';
background-color: #fff;
border: 1rpx solid #F14939;
border-bottom: none;
border-radius: 14rpx 14rpx 0 0;
z-index: 2;
box-sizing: border-box;
}
.sign{
font-weight: 600;
font-size: 30rpx;
color: #F14939;
width: 25%;
height: 100%;
border-right: 2rpx dashed rgba(241,73,57,0.5);
box-sizing: border-box;
.money{
font-size: 48rpx;
}
}
.mid{
flex: 1;
font-size: 30rpx;
color: #333;
padding-left: 24rpx;
.tit{
font-weight: 600;
}
text{
font-size: 24rpx;
color: #555;
}
}
.recv{
width: 140rpx;
height: 50rpx;
border-radius: 60rpx;
background-color: #F14939;
font-size: 28rpx;
color: #fff;
&.dis{
opacity: 0.5;
}
}
}
}
.goods-group{
border-top: 20rpx solid #F5F5F5;
.tit_msg{
font-size: 30rpx;
font-weight: bold;
padding: 20rpx 30rpx;
background: #fff;
}
&-name,
&-more {
background-color: #fff;
}
&-name {
padding: 30rpx;
font-size: 28rpx;
}
&-more {
text-align: center;
height: 90rpx;
line-height: 90rpx;
color: #b1acac;
font-size: 26rpx;
}
.goods-item {
display: flex;
background-color: #fff;
padding: 30rpx;
border-bottom: 1rpx solid #f0f0f0;
.left {
margin-right: 14rpx;
width: 240rpx;
height: 240rpx;
border-radius: 10rpx;
overflow: hidden;
position: relative;
.tip {
position: absolute;
bottom: 0;
background: rgba(0, 0, 0, 0.4);
color: #fff;
font-size: 24rpx;
width: 100%;
text-align: center;
height: 36rpx;
line-height: 36rpx;
}
.tag{
background: v-bind('Color');
position: absolute;
top: 0;
left: 0;
padding: 4rpx 8rpx;
font-size: 22rpx;
color: #fff;
border-radius: 10rpx 0 10rpx 0;
}
.img {
width: 100%;
height: 100%;
background: #999999;
}
}
.right {
flex-direction: column;
justify-content: space-between;
font-size: 30rpx;
flex: 1;
overflow: hidden;
.title {
color: #2c2c2c;
&.large{
font-size: 40rpx;
}
}
.vip {
display: flex;
align-items: center;
color: v-bind('priceColor');
.price {
font-size: 34rpx;
font-weight: bold;
.icon {
font-size: 24rpx;
}
}
}
.total {
font-size: 30rpx;
color: v-bind('priceColor');
}
.text {
display: flex;
justify-content: space-between;
font-size: 24rpx;
}
.btn {
display: flex;
justify-content: flex-end;
text {
font-size: 28rpx;
color: #fff;
background: $Color3;
border-radius: 5rpx;
height: 62rpx;
line-height: 62rpx;
width: 165rpx;
text-align: center;
}
}
.text2 {
font-size: 34rpx !important;
color: v-bind('priceColor');
font-weight: 600;
margin-right: 10rpx;
.icon{
font-weight: normal;
font-size: 24rpx;
}
}
.tites {
font-size: 28rpx;
font-weight: 400;
color: #666666;
}
}
}
.right1 {
float: right;
background: v-bind('Color');
color: #fff;
padding: 15rpx 20rpx;
border-radius: 8rpx;
font-size: 24rpx;
white-space: nowrap;
}
.dis {
opacity: 0.65;
}
}
.commentBox{
padding: 30rpx;
border-top: 20rpx solid #F5F5F5;
.toptitle{
.num{
font-size: 30rpx;
font-weight: bold;
}
.more{
font-size: 28rpx;
}
}
.commentlist{
.item{
margin-top: 30rpx;
.itemtop{
display: flex;
justify-content: space-between;
.user{
display: flex;
flex: 1;
.avatar{
width: 70rpx;
height: 70rpx;
border-radius: 50%;
margin-right: 12rpx;
}
.right{
font-size: 24rpx;
flex: 1;
.time{
color: #98989f;
}
}
}
.date{
font-size: 24rpx;
color: #999;
white-space: nowrap;
line-height: 70rpx;
}
}
.text{
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
white-space: break-spaces;
margin-top: 16rpx;
font-size: 28rpx;
}
.rate{
display: flex;
align-items: center;
margin-top: 5px;
.star{
margin-right: 3px;
}
}
}
}
}
.recordBox{
border-top: 20rpx solid #F5F5F5;
.title {
font-size: 30rpx;
font-weight: bold;
padding: 40rpx 30rpx;
}
.list {
padding: 0 30rpx;
.item {
display: flex;
align-items: center;
font-size: 26rpx;
padding-bottom: 30rpx;
.id {
font-size: 30rpx;
margin-right: 20rpx;
}
image {
width: 70rpx;
height: 70rpx;
background: #98989f;
margin-right: 15rpx;
}
.text {
color: #98989f;
overflow: hidden;
flex: 1;
.bottom {
display: flex;
}
.name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex: 1;
}
.num {
color: v-bind('priceColor');
flex-shrink: 0;
}
}
}
}
.more {
font-size: 30rpx;
text-align: center;
padding: 30rpx 0;
border-top: 2rpx solid #e9e9e9;
}
}
.payTips{
position: fixed;
bottom: 110rpx;
width: 100%;
background-color: #fff3cd;
z-index: 100;
color: #f66d2d;
.swiper{
height: 70rpx;
}
&.btm{
bottom: 220rpx;
}
.timeTips{
height: 70rpx;
padding: 0 20rpx;
text-align: left;
text{
font-size: 28rpx;
}
}
}
.fixedBox{
display: flex;
align-items: center;
width: 100%;
height: 110rpx;
background: #ffffff;
z-index: 201;
.row{
font-size: 24rpx;
width: 100rpx;
position: relative;
text-align: center;
border-right: 2rpx solid #e9e9e9;
.badge{
position: absolute;
top: -10rpx;
left: 60rpx;
background-color: v-bind('tagColor');
color: #fff;
display: inline-block;
line-height: 1;
padding: 2px 4px;
border-radius: 10px;
}
.addtip{
position: absolute;
bottom: 120rpx;
left: 50%;
margin-left: -80rpx;
padding: 16rpx 0 16rpx 12rpx;
background-color: v-bind('bgColor');
display: flex;
align-items: center;
&::before{
width: 0;
height: 0;
left: 60rpx;
top: 100%;
border-left: 20rpx solid transparent;
border-right: 20rpx solid transparent;
border-top: 20rpx solid v-bind('bgColor');
content: '';
position: absolute;
}
.hand{
width: 46rpx;
height: 46rpx;
margin-right: 10rpx;
animation: myfirst 1s infinite;
margin-top: 5px;
}
@keyframes myfirst {
0% {
transform: translate(0px, 0px);
}
50% {
transform: translate(0px, -5px);
}
100% {
transform: translate(0px, 0px);
}
}
.txt{
max-width: 400rpx;
width: max-content;
font-size: 28rpx;
line-height: 50rpx;
text-align: left;
}
.cross{
width: 80rpx;
height: 50rpx;
}
}
}
.row:nth-child(3) {
border: none;
}
.btn{
flex-direction: column;
flex: 1;
height: 100%;
color: #fff;
background: v-bind('Color');
font-size: 32rpx;
line-height: inherit;
border-radius: 0;
.aux{
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
.price{
display: flex;
align-items: baseline;
flex-wrap: wrap;
line-height: 1;
margin-bottom: 10rpx;
.icon{
font-size: 22rpx;
}
.txt{
font-size: 32rpx;
font-weight: 600;
}
.yh{
font-size: 24rpx;
opacity: 0.8;
}
}
.renshu{
font-size: 28rpx;
opacity: 0.8;
}
}
.mid{
font-size: 28rpx;
}
.large{
font-size: 38rpx;
}
.total{
font-weight: 600;
font-size: 34rpx;
}
&.hui{
opacity: 0.65;
color: #eee;
}
.item {
display: flex;
align-items: center;
image {
width: 35rpx;
}
}
}
.disabled{
opacity: 0.7;
}
.countDown{
text{
color: #fff;
font-size: 28rpx;
}
}
}
.cartBox{
.Tit{
font-size: 30rpx;
display: flex;
align-items: center;
height: 80rpx;
border-bottom: 1px solid #eee;
padding: 0 24rpx;
font-weight: 600;
}
.bbox{
height: 75vh;
overflow: auto;
padding: 0 24rpx 110rpx;
box-sizing: border-box;
.item{
display: flex;
justify-content: space-between;
padding: 24rpx 0;
border-bottom: 1px solid #F5F5F5;
image{
width: 200rpx;
height: 200rpx;
border-radius: 8rpx;
margin-right: 24rpx;
}
.info{
flex: 1;
display: flex;
flex-direction: column;
min-height: 200rpx;
justify-content: space-between;
.name{
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
font-size: 28rpx;
line-height: 36rpx;
margin-bottom: 6rpx;
}
.sku{
display: inline-block;
font-size: 24rpx;
color: #999999;
background: #f7f8fa;
border-radius: 5rpx;
padding: 4rpx 14rpx;
}
.price{
&-left{
color: v-bind('Color');
font-weight: 600;
.icon{
font-size: 24rpx;
}
.text{
font-size: 34rpx;
}
}
}
}
}
}
}
@keyframes animate {
0% {
transform: translateX(-15px);
}
100% {
transform: translateX(0);
}
}
@keyframes enter {
0% {
transform: translateX(-15px);
transform: scale(0);
}
100% {
transform: translateX(0);
transform: scale(1);
}
}
@keyframes leave {
0% {
transform: translateX(-15px);
opacity: 1;
}
100% {
transform: translateX(0);
opacity: 0;
}
}
.scrBox{
display: flex;
align-items: center;
padding-left: 15px;
width: 66px;
margin-right: -10px;
.row{
width: 30px;
height: 30px;
border: 1px solid v-bind('Color');
position: relative;
margin-left: -15px;
border-radius: 50%;
box-sizing: border-box;
.img{
width: 100%;
height: 100%;
border-radius: 50%;
}
&:nth-child(1){
z-index: 4;
}
&:nth-child(2){
z-index: 3;
}
&:nth-child(3){
z-index: 2;
}
&:nth-child(4){
z-index: 1;
}
&.enter{
animation: enter 0.5s forwards;
}
&.leave{
animation: leave 0.5s forwards;
}
&.animate{
animation: animate 0.5s forwards;
}
}
}
.border{
height: 32rpx;
background: rgba(255, 255, 255, 0.39);
border: 1px solid v-bind('priceColor');
color: v-bind('priceColor');
padding: 0 10rpx;
border-radius: 5rpx;
margin-left: 10rpx;
font-size: 22rpx;
}
.box_zong{
margin-top: 20rpx;
display: flex;
flex-wrap: wrap;
.box_imgs {
width: 33.3%;
image {
width: 200rpx;
height: 200rpx;
margin-bottom: 30rpx;
}
}
}
.box_number {
margin-left: 20rpx;
color: #656565;
font-size: 25rpx;
}
.box_number1 {
padding: 2rpx 10rpx;
border: 1px solid #656565;
border-radius: 10rpx;
color: #656565;
font-size: 25rpx;
}
.viewBox{
text-align: center;
padding: 10rpx;
position: fixed;
right: 20rpx;
bottom: 240rpx;
background-color: #fff;
font-size: 24rpx;
color: #888;
border-radius: 8rpx;
z-index: 101;
box-shadow: 0rpx 3rpx 20rpx rgba(0, 0, 0, 0.16);
.swiperBox{
width: 120rpx;
height: 120rpx;
.img {
width: 100%;
height: 100%;
border-radius: 8rpx;
}
}
.num{
color: #fff;
background: rgba(0, 0, 0, 0.36);
width: 36rpx;
height: 36rpx;
top: 10rpx;
right: 10rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: 0 8rpx 0 8rpx;
position: absolute;
}
.text{
margin-top: 8rpx;
}
}
.loadBox{
position: absolute;
height: 86vh;
overflow: hidden;
z-index: 202;
top: 0;
left: 0;
width: 100%;
background-color: #fff;
.top_box{
background: #fff;
box-sizing: border-box;
padding: 24rpx;
.desc{
width: 100%;
height: 34rpx;
margin: 10rpx 0;
}
}
.box{
background: #e1e1e1;
animation: fade 2s infinite;
}
.text_box{
background: #fff;
padding: 30rpx;
.text{
height: 50rpx;
margin-bottom: 20rpx;
background: #e1e1e1;
}
}
}
@keyframes fade {
from {
opacity: 1;
}
50% {
opacity: 0.5;
}
to {
opacity: 1;
}
}
</style>