shop_app/pages/groups/index.vue

5356 lines
144 KiB
Vue
Raw Normal View History

2025-05-08 09:16:37 +08:00
<template>
<view class="whole" @touchmove="preventD">
<div v-if="loading_box" class="loadBox">
<div style="height: 430rpx;position: relative;"></div>
<div class="top_box">
<div class="top_box_left flex1">
<div class="imgs box"></div>
<div class="top_box_right">
<div class="li box"></div>
<view style="width: 10rpx;height: 10rpx;"></view>
<div class="li box"></div>
</div>
</div>
<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>
<template v-else>
<view class="goods">
<!-- 导航栏 -->
<view class="goods-bar" :style="{backgroundColor: 'rgba(255, 255, 255, ' + opacityStyle + ')', padding: statusBarHeight + 'px 15px 10px', height: statusBarHeight + 40 + 'px'}">
<view class="goods-bar-icon">
<view class="backBox flex">
<view class="back flex" @click="toBack('back')"><up-icon name="arrow-left" size="18" color="#333" /></view>
<zb-popover placement="bottom-start" :options="actions" @select="selectPop">
<view class="home"><up-icon name="list-dot" size="20" color="#333" /></view>
</zb-popover>
</view>
<!-- 店铺操作按钮 -->
<view class="shop-icon">
<!-- 收藏 -->
<view class="shop-icon-item flex" @click="handleCollection()">
<up-icon v-if="!is_collect" name="heart" size="20" />
<up-icon v-else name="heart-fill" size="20" :color="Color" />
</view>
<!-- 朋友圈 -->
<view class="shop-icon-item flex" @click="showImg = true">
<text class="iconfont icon-pengyouquan"></text>
</view>
<!-- 分享 -->
<button class="shop-icon-item flex" @click="handleShare()">
<text class="iconfont icon-share"></text>
</button>
</view>
</view>
</view>
<view class="tabsBox" v-if="showTabs" :style="{top: barHeight + 'px'}">
<view class="col" v-for="it in tabsList" :key="it.id" :class="it.id == tabVal ? 'active' : ''" @click="handleTabs(it.id, it.selector)">{{it.name}}</view>
</view>
<view class="oneBox">
<!-- 背景图 -->
<view class="goods-top">
<image :src="item.background_image || item.shop.background_image + '?x-oss-process=image/format,webp'" :webp="true" class="bgImg" mode="aspectFill"></image>
<view v-if="total > 0 && !hasRemove" class="broadcast animate" style="transition:opacity 1s ease-out;" :style="{opacity: opacity}">
<img style='width: 50rpx;height: 50rpx;border-radius: 50%;' :src="msg" />
<view class="broadcast-time">{{t}}跟团下单</view>
</view>
<view class="linear"></view>
</view>
<!-- 店铺信息 -->
<view class="vanBox">
<view class="shop_info">
<view class="one">
<view class="logobox">
<image class="img" :src="item.shop.logo" mode="aspectFill" @click="toPage('/pages/index/index')"></image>
<view class="name">{{item.shop.name}}<template v-if="item.shop.name_desc">&nbsp;{{item.shop.name_desc}}</template></view>
</view>
<view class="sub_box">
<view class="row">
<view class="row2" @click="toSubscribe()" v-if="!item.is_subscribe">
<up-icon name="plus" size="10" color="#fff" />&nbsp;<text>订阅</text>
</view>
<view class="row2 bai" @click="cancelSubscribe()" v-else>已订阅</view>
<view class="redBox" v-if="showPopOverRed">
<view class="img" :style="{backgroundImage: 'url(' + sp2 + ')'}"></view>
<text>领红包</text>
</view>
</view>
<view style="width: 10rpx;height: 10rpx;"></view>
<view class="row row1" @click="openService()">
<text class="iconfont icon-msg"></text>&nbsp;<text>客服</text>
</view>
</view>
</view>
<template v-if="is_subscribe === 0">
<div style="padding: 20rpx 0 0;" v-if="closure">
<div class="guanzhu flex1">
<div class="txt">关注公众号接收最新开团消息</div>
<div class="anniu" @click="followSubscribe()">关注</div>
<div class="chacha" @click="closure = false">
<up-icon name="close" size='15' />
</div>
</div>
</div>
</template>
<view class="desc" v-if="item.shop.describe">{{item.shop.describe}}</view>
<view class="vip_desc" v-if="vip_on === 0 && score_on === 0" @click="showDirect = true">
<view class="tit"><up-icon name="level" size="16" color="#A3A3A3" />&nbsp;合作商直销</view>
<view class="text">快递发货<up-icon name="arrow-right" color="#D3D3D3" /></view>
</view>
<view class="vip_desc er" v-if="vip_on === 1 || score_on === 1">
<view class="tit" @click="to_VipPage()" v-if="vip_on === 1">
<view style="display: flex;"><view class="hg" :style="{backgroundImage: 'url(' + sp2 + ')'}"></view>会员权益</view>
<up-icon name="arrow-right" size="14" color="#D3D3D3" />
</view>
<view class="tit" @click="toPage('/pages/mine/scoreShop/index', 1)" v-if="score_on === 1" :class="vip_on === 1 ? 'score' : ''">
<view style="display: flex;">
<text class="iconfont icon-score" style="font-size: 16px;color: #A3A3A3;"></text>&nbsp;积分商城
</view>
<up-icon name="arrow-right" size="14" color="#D3D3D3" />
</view>
<view class="tit score" @click="showDirect = true">
<view style="display: flex;"><up-icon name="level" size="16" color="#A3A3A3" />&nbsp;合作商直销</view>
<up-icon name="arrow-right" size="14" color="#D3D3D3" />
</view>
</view>
</view>
<view class="new_person" v-if="item.shop && item.shop.extendInfo && item.shop.extendInfo.new_user_ad_banner_url && item.shop.extendInfo.new_user_ad_banner_link && !userInfo.is_purchase">
<image :src="item.shop.extendInfo.new_user_ad_banner_url" mode="widthFix" @click="toPage(item.shop.extendInfo.new_user_ad_banner_link, item.shop.extendInfo.new_user_ad_banner_link.indexOf('index/index') > -1 ? 0 : 1)"></image>
</view>
</view>
<view class="empty" v-if="hasRemove">
<up-empty mode="data" icon="https://ct-upimg.yx090.com/g.ii090/images/sprite/empty/data.png" text="该团购已经删除"></up-empty>
</view>
<template v-if="!hasRemove">
<!-- 团购信息 -->
<view class="goods-info">
<text class="description" :class="fontSize == 'small' ? '' : 'large'" user-select v-if="item.description">{{item.description}}</text>
<template v-if="item.group_goods.length">
<view class="vip_advert" v-if="vip_on == 1 && !is_vip" @tap="to_VipPage">
2025-06-14 10:01:48 +08:00
<img src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2025/05/26/bACLVRl4jIRw77jmz3Mg3Uz64sYk3sR3OR8Ms9l5.png" alt="" class='vip_advert_img'>
2025-05-08 09:16:37 +08:00
</view>
<view class="item" @click="jumpFloor" v-if="item.types.length < 5" :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 item.group_goods" :key="goods.id">
<view class="right-item" :class="goodsClass" v-if="index < 15">
<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="item.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 flex1"
v-if="item.shop && item.shop.extendInfo && item.shop.extendInfo.top_of_shop_group_goods && item.top_on_shop_group && item.top_on_shop_group.shop_group"
@click="toPage('/pages/mine/other/ranking?id=' + item.top_on_shop_group.shop_group_id, 1)">
<view class="text flex">
<view class="icon" :style="{backgroundImage: 'url(' + sp2 + ')'}"></view>&nbsp;{{item.top_on_shop_group.shop_group.name}}热销榜&nbsp;&nbsp;&nbsp;<text>{{item.top_on_shop_group.sort}}</text>
</view>
<up-icon name="arrow-right" color="#999" />
</view>
<template v-if="item.status !== 3 && item.group_goods.length">
<view class="time">
<view class="time-item" style="display: flex; align-items: center;">
<text class="title" style="padding: 0;">{{item.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="item.sold_status === 0 && startTime">
距开始<up-count-down :color1="Color" format="DD天HH:mm:ss" :time="startTime" />
</view> -->
<view class="text" v-if="item.sold_status === 0 && startTime">
<text>{{parseTime(item.sold_start_time)}}开团</text>
</view>
</view>
<view class="time-item" v-if="is_show_sales">
<text class="title">{{item.visitor * 1 + item.virtual_visitor * 1}}人查看</text>
<text class="boder"></text>
<text>{{total}}次跟团</text>
</view>
<view class="red_label" v-if="item.red_status === 1">
<template v-if="item.is_receive_red">
<view class="red_col red_col1">本团专享红包{{item.red_amount}}</view>
<view class="red_col red_col2 disable">已领</view>
</template>
<template v-else-if="item.is_red_could_receive">
<view class="red_col red_col1 receive1">本团专享红包{{item.red_amount}}</view>
<view class="red_col red_col2 receive2" @click="receiveRed()">领取</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>
<template v-if="it.scene_type == 2">
<template v-if="it.receive_coupon_type">
<view class="recv flex" v-if="it.user_coupon_status == 1" @click="jumpFloor(0)">去使用</view>
<button open-type="share" id="invite" class="recv flex" v-else>去邀请</button>
</template>
<view v-else class="recv flex" @click="recvCoupon(it)">领取</view>
</template>
<template v-else>
<view class="recv flex" v-if="it.receive_coupon_type" @click="jumpFloor(0)">去使用</view>
<view class="recv flex" v-else @click="recvCoupon(it)">领取</view>
</template>
</view>
</view>
</view>
</template>
<view class="new_person" v-if="is_crop_user && crop_user_img">
<image :src="crop_user_img" mode="widthFix" @click="toPage('/pages/mine/aboutUs/service', 1)"></image>
</view>
</view>
</template>
</view>
<template v-if="!hasRemove">
<!-- 简单编辑器 -->
<view class="edition good-detail" id="goodDetail">
<template v-for="itm in textModules" :key="itm.id">
2025-06-14 10:01:48 +08:00
<view class="edition_box" :class="item.pic_padding_type ? '' : 'verbtm'" v-if="itm.type == 1 && (is_crop_user || (!is_crop_user && !itm.only_crop))">
2025-05-08 09:16:37 +08:00
<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>
2025-06-14 10:01:48 +08:00
<view class="edition_box" v-if="itm.type == 2 && (is_crop_user || (!is_crop_user && !itm.only_crop))">
2025-05-08 09:16:37 +08:00
<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>
2025-06-14 10:01:48 +08:00
<view class="edition_box" v-if="itm.type == 3 && (is_crop_user || (!is_crop_user && !itm.only_crop))" @longpress="showSaveVideo(itm.video_convert || itm.video[0])">
2025-05-08 09:16:37 +08:00
<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>
2025-06-14 10:01:48 +08:00
<view class="edition_box text1_box" :class="fontSize == 'small' ? '' : 'large'" v-if="itm.type == 4 && (is_crop_user || (!is_crop_user && !itm.only_crop))">
2025-05-08 09:16:37 +08:00
<rich-text :nodes="parseText(itm.text)" :user-select="true"></rich-text>
</view>
2025-06-14 10:01:48 +08:00
<view class="baseInfo" v-if="itm.type == 5 && (is_crop_user || (!is_crop_user && !itm.only_crop))" :class="fontSize == 'small' ? '' : 'large'">
2025-05-08 09:16:37 +08:00
<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>
2025-06-14 10:01:48 +08:00
<view class="lightBox" v-if="itm.type == 6 && itm.text && (is_crop_user || (!is_crop_user && !itm.only_crop))" :class="fontSize == 'small' ? '' : 'large'">
2025-05-08 09:16:37 +08:00
<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="item.types.length > 0">
<view class="tit_msg">本团商品
<template v-if="item.limit_type === 1">{{item.start_sale_num}}件起购</template>
<template v-if="item.limit_type === 2">限购{{item.limit}}</template>
<template v-if="item.actives && item.actives.length">
<view v-for="(it, i) in item.actives" class="move_img" :key="i">{{it.name}}</view>
</template>
</view>
<view class="bbox" ref="container" id="container" :class="item.types.length > 4 ? 'shux' : ''">
<view class="left" :class="item.types.length > 4 ? 'shux' : ''" v-if="item.types.length > 1">
<view class="typeBox" :class="item.types.length > 4 ? 'shux' : ''" :style="{'top': showGroups ? (statusBarHeight + 77) + 'px' : '37px'}">
<block v-for="(t_item, t_index) in item.types" :key="t_item.id">
<view
v-if="t_item.list && t_item.list.length > 0"
class="col"
:class="typeId === t_item.id ? 'active' : ''"
@click="changeType(t_item.id)">
{{t_item.name}}
</view>
</block>
</view>
</view>
<view class="goodBox" :class="item.types.length > 4 ? 'shux' : ''">
<view v-for="(t_item, i) in item.types" :key="t_item.id" :class="'group' + t_item.id">
<up-sticky :id="t_item.id" @scroll="changeTest" :z-index="i + 1" :offset-top="barHeight + 37"
v-if="item.types.length > 1 && t_item.id > 0 && t_item.list && t_item.list.length > 0">
<view class="goods-group-name">{{t_item.name}}</view>
</up-sticky>
<block v-for="goods in t_item.list" :key="goods.id">
<view class="goods-item" v-if="t_item.id > 0 || showZero">
<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" @click="can_buy ? getGoodsSkus1(goods) : ''">
<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" :class="fontSize == 'small' ? '' : 'large'">
<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 style="display: flex;align-items: center;justify-content: space-between;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 && item.copy_shared_on === 0">已团{{goods.sales + (goods.goods.virtual_sales * 1)}}</text>
<text class="total" v-if="is_show_sales && item.copy_shared_on === 1">已团{{goods.goods.sales + (goods.goods.virtual_sales * 1)}}</text>
</view>
</view>
<view style="display: flex;align-items: center;justify-content: space-between;">
<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="price">
<text><text class="icon"></text>{{goods.vip_price}}</text>
</view>
<text class="vip-tag" v-if="vipOn && goods.vip_price > 0 && vip_price_show">会员价</text> -->
<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="item.status !== 3 && item.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 class="goods-group-more" v-if="zeroList.length > 0" @click="showZero = !showZero">
<text v-if="showZero">收起全部</text>
<text v-else>{{zeroList.length}}款商品被抢光点击查看</text>
<up-icon :name="showZero ? 'arrow-up' : 'arrow-down'" />
</view>
</view>
</view>
</view>
<view class="supplyBox" v-if="item.service_provider">
<image :src="item.service_provider.logo" mode="aspectFill" @click="showDirect = true"></image>
<view class="text" @click="showDirect = true">
<view class="tit">{{item.service_provider.name}}</view>
<view class="num" v-if="item.service_provider.sub_num"><text>{{item.service_provider.sub_num}}</text>人关注</view>
</view>
<view class="shouc" @click="collectShop()">
<template v-if="collect_shop[item.service_provider.id]">
<up-icon name="star-fill" :color="Color" />
<text>已关注</text>
</template>
<template v-else>
<up-icon name="star" :color="Color" />
<text>关注店铺</text>
</template>
</view>
</view>
<!-- 评价 -->
<view class="commentBox" v-if="commentTotal > 0">
<view class="toptitle">
<text class="num">宝贝评价({{commentTotal}})</text>
<view class="more" @click="toPage(`/pages/groups/comment?id=${item.id}&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>
<div class="recomBox" v-if="recommendGroup.length && item.status === 1 && item.sold_status !== 2">
<view class="title">团购推荐</view>
<up-scroll-list :indicatorActiveColor="Color">
<div class="row" v-for="(item, index) in recommendGroup" :key="index" @click="toPage('/pages/groups/index?id=' + item.id, 1)">
<image :src="item.face_img" mode="aspectFill" class="img"></image>
<div class="tit">{{item.title}}</div>
<div class="price">
<text class="icon"></text>
<block v-if="item.group_goods.length === 1">
<text v-if="item.group_goods[0].specs_type === 0">{{item.group_goods[0].price}}</text>
<text v-else>
<text v-if="item.group_goods[0].max_price === item.group_goods[0].min_price">{{item.group_goods[0].min_price * 1}}</text>
<text v-else>{{item.group_goods[0].min_price * 1}}~{{item.group_goods[0].max_price * 1}}</text>
</text>
</block>
<block v-else>
<text v-if="item.max_price === item.min_price">{{item.min_price * 1}}</text>
<text v-else>{{item.min_price * 1}}~{{item.max_price * 1}}</text>
</block>
</div>
</div>
</up-scroll-list>
</div>
<!-- 跟团记录 -->
<view class="goods-record" v-if="total > 0" id="record">
<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: 30rpx;"></view>
<cf-cloud></cf-cloud>
<view class="payTips" v-if="(endtime && offtimeData.days == 0) || (item.limit_type == 1 && cartNum < item.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 flex">
<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="item.limit_type == 1 && cartNum < item.start_sale_num && cartNum > 0">
<view class="timeTips flex">
<up-icon name="bell-fill" color="#f66d2d" />&nbsp;
<text>尚未满足起购件数{{item.start_sale_num}}件起购</text>
</view>
</swiper-item>
</swiper>
</view>
<view class="goods-btn">
<view class="goods-btn-icon" @click="toPage('/pages/index/index')">
<up-icon name="home" size="22" />
<view>首页</view>
</view>
<view class="goods-btn-icon" @click.stop="openService()">
<up-icon name="kefu-ermai" size="22" />
<view>客服</view>
2025-06-14 10:01:48 +08:00
<view class="addtip" v-if="item.add_cs_tips">
2025-05-08 09:16:37 +08:00
<image src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2024/08/07/zbR6z0xICjDKjWEcGwTUHBKPTiQZ9dDLfU8eFmTy.png" mode="aspectFit" class="hand"></image>
<view class="txt">{{item.add_cs_tips}}</view>
<view class="cross flex" @click.stop="item.add_cs_tips = ''">
<up-icon name="close" size="20" color="#999" />
</view>
</view>
</view>
<view class="goods-btn-icon" @click="openCart()">
<view class="badge" v-if="number">{{number}}</view>
<up-icon name="shopping-cart" size="24" />
<view>购物车</view>
</view>
<template v-if="item.group_goods.length !== 0">
<!-- 开团中-开团隐藏 -->
<view class="btn" :class="can_buy ? '' : 'disabled'" @click="can_buy ? toPay() : ''" v-if="item.status !== 3 && item.sold_status === 1 && parseInt(item.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" :class="item.is_subscribe_remind_stock ? 'hui' : ''" @click="arrivalNotice()">
<text v-if="!item.is_subscribe_remind_stock">到货提醒</text>
<text v-else>取消到货提醒</text>
</view>
<!-- 预览 -->
<view class="btn disabled" v-else-if="item.status === 3">
<text>团购未发布</text>
</view>
<!-- 未开团-开团隐藏 -->
<view class="btn" v-if="item.status !== 3 && item.sold_status === 0"
@click="!item.is_subscribe_remind ? handleSubscrip() : ''" :class="item.is_subscribe_remind ? 'disabled' : ''">
<view class="item">
<image
src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2022/07/01/cuOPd5R1X6MBOOPo7Whc3wfErkvFD3raT9sZnbv9.png"
mode="widthFix" v-if="!item.is_subscribe_remind"></image>
<text v-if="!item.is_subscribe_remind">预约提醒</text>
<text v-else>已提醒</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">
<text>团购已下架</text>
</view>
</view>
</template>
<!-- 查看商品 -->
<view class="viewBox" v-show="showJump && imageList.length && !hasRemove" @click="viewGoods()">
<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="goods-tip" v-if="item.status === 3 || !item.group_goods.length && !hasRemove">
<div>该团购已下架或临时下架</div>
</view>
<!-- 选规格 -->
<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="group_id"
:sourceId="source_id"
:sourceType="source_type"
:can-buy="can_buy"
:sold-status="orign_status"
:remind-stock="item.is_subscribe_remind_stock"
@remind="goodsRemind"
:sales="total"
:short-status="shortStatus"/>
<!-- 分享海报 -->
<share-img v-if="showImg" :goods="item" @closeShow="showImg = false" />
<!-- 单规格商品详情 -->
<up-popup :show="danguige" :round="10" mode="bottom" @close="hanleClose" catchtouchmove="preventD" :z-index="202">
<div class="sku-top">
<view class="sku-top-box">
<image
class="img"
mode="aspectFill"
:src="list_1.pic_url || list_1.face_img"
:style="{width: imgWidth + 'rpx', height: imgWidth + 'rpx'}"
@click="preViewImg(list_1.pic_url_800 || list_1.pic_url || list_1.face_img, $event)" />
<view class="goodcol" :style="{width: 'calc(100% - ' + (imgWidth + 30) + 'rpx)'}">
<view class="tit" :class="imgWidth == 150 ? '' : 'sml'" v-if="imgWidth == 150">{{list_1.title}}</view>
<view class="pricebox">
<!-- 会员下普通价格 -->
<view class="text1" v-if="vipOn && list_1.vip_price > 0 && (is_vip || (!is_vip && vip_price_show))">
<text class="icon1"></text>
<text>{{list_1.price}}</text>
</view>
<view>
<!-- 显示会员价 -->
<view v-if="vipOn && list_1.vip_price > 0 && (is_vip || (!is_vip && vip_price_show))" class="vip">
<!-- <text><text class="icon1"></text>{{list_1.vip_price}}</text>
<text class="vip-tag" v-if="vipOn && list_1.vip_price > 0 && vip_price_show">会员价</text> -->
<view class="vip-tag"><text>会员价&nbsp;</text>{{list_1.vip_price}}</view>
</view>
<!-- 显示普通价格 -->
<view v-else class="vip">
<text class="icon1"></text>
<text>{{list_1.price}}</text>
</view>
</view>
</view>
<view class="text" v-if="show_stock === 1">剩余{{list_1.goods && (list_1.goods.stock <= 0 ? 0 : list_1.goods.stock)}}</view>
</view>
</view>
<scroll-view class="good_box" scroll-y="true" enhanced="true" @scroll="skuScroll">
<view style="box-sizing: border-box;">
<div class="sku_box" v-if="list_1.goods && list_1.goods.is_gift == 0">
<text>购买数量
<template v-if="show_stock === 1">(最多{{list_1.goods && (list_1.goods.stock <= 0 ? 0 : list_1.goods.stock)}})</template>
</text>
<text v-if="list_1.goods && list_1.goods.limit_type == 1" class="box_number">{{list_1.goods.start_sale_num}}件起购</text>
<text v-if="list_1.goods && list_1.goods.limit_type == 2" class="box_number">限购{{list_1.goods.limit}}</text>
<up-number-box
v-model="number1"
:min="list_1.goods && list_1.goods.limit_type == 1 ? parseInt(list_1.goods.start_sale_num) : list_1.goods && list_1.goods.limit_type == 0 ? 1 : 1"
:max="(list_1.goods && list_1.goods.limit_type == 2) ? parseInt(list_1.goods.limit) : list_1.goods && list_1.goods.limit_type == 0 ? list_1.goods && (list_1.goods.stock <= 0 ? 0 : list_1.goods.stock) : 0"
@overlimit="plusBtn1(list_1.goods && list_1.goods.limit_type == 1 ? 0 : list_1.goods && list_1.goods.limit_type == 2 ? 1 : 2, number1, list_1.goods.limit, (list_1.goods.stock <= 0 ? 0 : list_1.goods.stock))"
disabledInput
bgColor="#f2f3f5"
:longPress="false"
:asyncChange="true"
@change="changeNumTwo($event, number1)">
</up-number-box>
</div>
<div class="sku-buy" v-if="list_1.sales > 0">
<view class="imgbb" v-for="(img, idx) in avatars" :key="idx">
<image :src="img"></image>
</view>
已有 <span class="red">{{list_1.sales}}</span> 个社群好友购买
</div>
<view class="edition" v-if="danTextModule.length != 0">
<view v-for="(item, index) in danTextModule" :key="item.id">
<!-- 大图 -->
<view v-if="item.type == 1" class="edition_box" @click="preViewImg(item.imgs[0], $event)">
<view v-for="(imgs, i) in item.imgs" :key="i">
<image :src="imgs" mode="widthFix" style="width:100%"></image>
</view>
</view>
<!-- 小图 -->
<view class="edition_box" v-if="item.type == 2">
<view class="small_img">
<view v-for="(list, i) in item.img" :key="i" class="imgs"
@click="viewSmallImg(item.img, list)">
<img :src="list" alt="">
</view>
</view>
</view>
<!-- 视频 -->
<view class="edition_box" v-if="item.type == 3">
<video :src="item.video[0]" height="100%" width="250" class="video_box" style="display: block;margin: 0 auto;"></video>
</view>
<!-- 文字 -->
<view class="edition_box text1_box" v-if="item.type == 4">
<text user-select="true" class="text">{{item.text}}</text>
</view>
</view>
</view>
<view v-if="mainImg.length !== 0" class="imgbox">
<image v-for="(img, idx) in mainImg" :key="idx" :src="img" class="img" mode="widthFix"></image>
</view>
</view>
</scroll-view>
<view class="addbtn" v-if="list_1.goods && list_1.goods.is_gift == 0">
<view class="btn"
:class="((list_1.goods && list_1.goods.stock <= 0) || !can_buy) ? 'btn1' : ''"
@click="((list_1.goods && list_1.goods.stock > 0) && can_buy) ? getGoodsSkus2(list_1):''">加入购物车
</view>
</view>
</div>
</up-popup>
<up-popup :show="showCouponBox && !hasRemove" :round="10" @touchmove.stop.prevent="moveHandle" :z-index="202" mode="center">
<view class="couponBox">
<view class="couponTitle">恭喜获得</view>
<scroll-view scroll-y="true" class="scrolly">
<view class="coupon-itme" v-for="(item, index) in couponList" :key="index">
<view class="coupon">
<image
src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2022/07/01/aK2hoeg7NSS3AcQcUfWz4uHsllFFUpi1S605FExI.png?x-oss-process=image/format,webp"
class="couponImg" :webp="true">
<view class="couponmoney">
<text class="sign"><text class="money">{{item.amount}}</text></text>
<view class="tit" v-if="item.use_type === 30 || item.use_type === 31">{{item.full_amount}}</view>
<view class="tit" v-else>无门槛</view>
</view>
<view class="coupontype">
<template v-if="item.use_type === 20 || item.use_type === 31">团购{{item.extend && item.extend.title}}可用</template>
<template class="tit" v-else>全场通用</template>
</view>
<view class="coupontime">有效期至{{item.finish_time}}</view>
</image>
</view>
</view>
</scroll-view>
<view class="couponBtn" @click="showCouponBox = false">立即领取</view>
</view>
</up-popup>
<up-popup :show="showDirect" :round="10" mode="bottom" @close="showDirect = false" catchtouchmove="preventD" :z-index="202">
<view class="sale-goods">
<view style="padding: 10px 0 5px;font-size: 30rpx;">合作商直销</view>
<view style="height: 50vh;">
<view style="font-size: 28rpx;color: #999;" class="flex1" @click="toDirect">
<text>该商品由合作方直销由合作方提供货物及售后服务</text>
<up-icon name="arrow-right" size="14" color="#999" />
</view>
</view>
<view class="btnbox"><view class="btn flex" @click="showDirect = false">我知道了</view></view>
</view>
</up-popup>
</view>
</template>
<!-- 团购购物车 -->
<up-popup :show="showCart" :round="10" mode="bottom" @close="showCart = false" catchtouchmove="preventD" :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 flex1">
<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>
<!-- 团购专享红包 -->
<up-overlay :show="showRedPaper && !hasRemove" :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>{{item.red_amount}}</text></view>
<view class="text">{{item.title}}团购活动内下单立减</view>
<view class="btn" @click="toUseRedPaper()">立即使用</view>
</view>
</template>
</view>
</view>
</up-overlay>
<!-- 订阅红包 -->
<up-overlay :show="showDyRed" z-index="999">
<view class="red_paper">
<view class="block">
<view class="close_red_paper" @click="showDyRed = false">
<up-icon name="close-circle" color="#fff" size="30" />
</view>
<template v-if="showDyOne">
<image src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2023/04/10/AjOXc0U0pL83uJfXSc4ba0unT64ufhVGcjeoJQQv.png?x-oss-process=image/format,webp" :webp="true" mode="widthFix" class='red_paper_img'></image>
<view class="open"><image src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2023/04/10/JmR8ZENpKOYTRbZ8s79LcGeZcqupVcCtIMQI951T.png" mode="widthFix" @click="openDyRed()" class='red_paper_img'></image></view>
</template>
<template v-if="showDyTwo">
<image src="https://ct-upimg.yx090.com/ju8hn6/shop/image/2023/04/10/i6mFrDPyerUbIoBythnqgMA2s0hF9xX3l3lqhccA.png?x-oss-process=image/format,webp" :webp="true" mode="widthFix" class='red_paper_img'></image>
<view class="openbox1">
<view class="price"><text>{{dyRedData.amount}}</text></view>
<view class="text">有效期至{{dyRedData.finish_time}}</view>
<view class="btn" @click="showDyRed = false">立即使用</view>
</view>
</template>
</view>
</view>
</up-overlay>
<!-- 新人优惠券 -->
<new-vip :show-van="showVan" @close="showVan = false" :coupon-info="couponInfo" />
<!-- 隐私协议弹窗 -->
<privacy-popup :show-dialog="showPrivacy" @close="showPrivacy = false" @agree="showPrivacy = false" @refuse="showPrivacy = false" />
<!-- 有任选几件活动并且与起购数量一致sku弹窗 -->
<multiple-sku
:show="showVanSku"
@close="closeSku"
@getnum="getnum"
:show_stock="show_stock"
:specs-num="specsNum"
:goodId="goodId"
:groupId="group_id"
:sourceId="source_id"
:sourceType="source_type"
:sold-status="orign_status"
:remind-stock="item.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="group_id"
:skus_1="skus_1"
:goodId="goodId"
@back="payBack">
</direct-pay>
<!-- 赠送会员 -->
<gifts-vip :show-gifts="showGifts" @close="showGifts = false" :info="giftsInfo"></gifts-vip>
<!-- 客服 -->
<call-center :show="showService" @close="showService = false" :type="1" />
<!-- 视频讲解 -->
<movable-area class="movableArea">
<movable-view class="movableView" :animation="false" direction="all" :x="write[0]" :y="write[1]"
:style="{'height': 'auto','width': videoWid + 'px'}">
<view class="videoBox" v-if="showDialog && videoHg && video_url && !hasRemove">
<view @click="toJump('/pages/groups/video?id=' + group_id, $event)">
<view :style="{'height': videoHg + 'px','width': videoWid + 'px'}">
<DomVideoPlayer
ref="domVideoPlayer"
object-fit="contain"
:isLoading="true"
:muted="true"
:controls="false"
:autoplay="true"
:loop="true"
:poster="video_url + '?x-oss-process=video/snapshot,t_1000,m_fast'"
:src="video_url" />
</view>
<view class="text">商品讲解</view>
</view>
<view class="close" @click="showDialog = false"><up-icon name="close" color="#fff" /></view>
</view>
</movable-view>
</movable-area>
<video-dialog :url="videoUrl" :show="showVideo" @close="showVideo = false"></video-dialog>
</view>
</template>
<script>
import { ref, reactive, toRefs } from 'vue'
import { get, post } from '@/api/request.js'
import { goodsItem, getImg, showToast, formatDate, getUserPhone, getShopInfo, judgePrivacy, parseTime, downloadVideo, uniShare, whetherLogin, toMiniProgram } from '@/components/common.js'
import ChooseSku from '@/components/sku/ChooseSku.vue'
import shareImg from '@/components/shareImg/shareImg.vue'
import StickyCalculate from './StickyCalculate.js'
import { sp2 } from '@/components/img.js'
import { Style } from '@/utils/list.js'
import privacyPopup from '@/components/privacyPopup/index.vue'
import multipleSku from '@/components/sku/multiple.vue'
import directPay from '@/components/sku/directPay.vue'
import newVip from '@/components/newVip/index.vue'
import giftsVip from '@/components/giftsVip/index.vue'
import videoDialog from '@/components/videoDialog/index.vue'
import cfCloud from '@/components/cfCloud/index.vue'
import DomVideoPlayer from '@/components/DomVideoPlayer/index.vue'
import { provTxt } from '@/components/scene.js'
import callCenter from '@/components/callCenter/index.vue'
import zbPopover from '@/components/Popover/index.vue'
export default {
components: {
ChooseSku,
shareImg,
privacyPopup,
multipleSku,
directPay,
newVip,
giftsVip,
videoDialog,
cfCloud,
DomVideoPlayer,
callCenter,
zbPopover
},
setup() {
const data = reactive({
temp: {},
tabsList: [
{ id: 0, name: '详情', selector: 'goodDetail' },
{ id: 1, name: '商品', selector: 'goodsGroup' },
{ id: 2, name: '跟团记录', selector: 'record' }
],
tabVal: 0,
textModules: [],
sp2: sp2,
recommendGroup: [],
styleObject: {
height: '300rpx'
},
showCouponBox: false,
couponList: [],
is_collect: false,
is_subscribe: '',
is_vip: false,
vip_on: 0,
score_on: 0,
closure: true,
loading_box: true,
number1: 1,
show_stock: 0,
list_1: {},
group_id: '',
danguige: false,
number: '',
buyList: [],
page: 1,
lastPage: 0,
type: 1,
showImg: false,
shareUrl: '',
total: 0,
showJump: false,
imageUrl: '',
commentList: [],
goodCommentRate: '',
commentTotal: 0,
commentHg: 0,
skuList: [],
endtime: '',
startTime: '',
timeData: {},
offtimeData: {},
opacityStyle: 0,
pagesLength: 0,
openType: '',
cartList: [],
typeId: 0,
goodsClass: 'per50',
showGroups: true,
zeroList: [],
showZero: false,
show_1: true,
showVideo: false,
videoUrl: '',
curIndex: 0,
waitForTime: 1,
delayTime: 4,
opacity: 0,
msg: '',
t: '',
stickyCalculate: null,
lockScoll: false,
danTextModule: [],
imgWidth: 150,
textType: 1,
discountAmount: 0,
cartPrice: '0.00',
vip_price_show: false,
mainImg: [],
avatars: [],
sunList: [],
showRedPaper: false,
showRedOne: true,
showRedTwo: false,
hasReceive: false,
number: 0,
showVan: false,
couponInfo: [],
showGifts: false,
giftsInfo: {},
is_show_sales: false,
customVal: {
height: 32,
top: 24
},
imageList: [],
swiperIndex: 0,
showView: true,
showDyRed: false,
showDyOne: true,
showDyTwo: false,
dyRedData: {},
showPopOverRed: false,
userInfo: {},
scoreShareInfo: {},
can_buy: true,
canClick: true,
img_preview_suffix: '',
Color: '',
priceColor: '',
bgColor: '',
tagColor: '',
Theme: '',
showPrivacy: false,
source_id: 0,
source_type: 'normal',
showTabs: false,
barHeight: 0,
oneBoxHg: 0,
goodsHg: 0,
detailHg: 0,
interval: null,
timeOut: null,
showVanSku: false,
goodId: 0,
specsNum: 0,
vipOn: false,
onTimeOut: null,
orign_status: 0,
collect_shop: {},
video_url: '',
showDialog: false,
videoWid: 0,
videoHg: 0,
show_explain_video: false,
hasRemove: false,
shortStatus: 1,
write: [],
showMorePay: false,
statusBarHeight: 0,
is_crop_user: uni.getStorageSync('is_crop_user') || false,
crop_user_img: '',
showDirect: false,
groupCartList: [],
showCart: false,
groupCoupons: [],
showService: false,
backInfo: null,
fontSize: 'small',
actions: [
{ id: 0, text: '首页', icon: 'home-fill' },
{ id: 1, text: '联系团长', icon: 'chat-fill' },
{ id: 2, text: '搜索团购', icon: 'bag-fill' },
{ id: 3, text: '收藏与浏览', icon: 'heart-fill' },
{ id: 4, text: '购物车', icon: 'shopping-cart-fill' },
{ id: 5, text: '调大字体', icon: 'setting-fill' }
],
cartNum: 0,
avatarsList: [
{ url: 'http://ct-upimg.yx090.com/ju8hn6/shop/image/94fcfdd8-a998-49ef-a0ed-26405cf7853f_suffix.png', class: 'animate'},
{ url: 'http://ct-upimg.yx090.com/ju8hn6/shop/image/101e86e4-6fab-41cf-ac00-b4bcaa450610_suffix.png', class: 'animate'},
{ url: 'http://ct-upimg.yx090.com/ju8hn6/shop/image/e5ec20d5-d460-45dc-a8bf-79fa84b8ccbb_suffix.png', class: 'animate'}
],
avatarsAll: [
'http://ct-upimg.yx090.com/ju8hn6/shop/image/31b5ee50-2dc4-4d0f-86a8-43d63733b37a_suffix.png',
'http://ct-upimg.yx090.com/ju8hn6/shop/image/b7109d3a-fc56-41f0-8c68-1a68a56ecc17_suffix.png',
'http://ct-upimg.yx090.com/ju8hn6/shop/image/be1ab082-0a3a-4a70-960e-26bb0bfd5385_suffix.png',
'http://ct-upimg.yx090.com/ju8hn6/shop/image/fc7a9b1c-1c72-4d34-b7af-19c2d063b456_suffix.png',
'http://ct-upimg.yx090.com/ju8hn6/shop/image/853263fa-3edc-49f5-8607-7397718c7458_suffix.png',
'http://ct-upimg.yx090.com/ju8hn6/shop/image/e5ec20d5-d460-45dc-a8bf-79fa84b8ccbb_suffix.png',
'http://ct-upimg.yx090.com/ju8hn6/shop/image/ab4ecc1e-f8ef-45d4-a4b8-3d7f8737a928_suffix.png',
'http://ct-upimg.yx090.com/ju8hn6/shop/image/d7f4b8c3-cc9c-4ddc-922a-3a4dce9784c1_suffix.png',
'http://ct-upimg.yx090.com/ju8hn6/shop/image/1c77dc22-4092-49f4-8fda-8467d415c728_suffix.png',
'http://ct-upimg.yx090.com/ju8hn6/shop/image/7aa9622d-bc35-4737-a26e-2be9f579fec7_suffix.png'
],
avatarTimer: null,
isAnimate: false,
})
// 订阅活动提醒消息
const handleSubscrip = () => {
toMiniProgram('pages/groups/index?id=' + data.group_id)
}
const item = ref({})
// 编辑器查看图片
const viewSmallImg = (e, img) => {
uni.previewImage({
urls: e,
current: img
})
}
const startAnimate = () => {
let item = data.buyList[data.curIndex]
if (item == null || item == undefined) return;
(data.msg = item.user.avatar),
(data.t = item.buy_time),
(data.opacity = 1)
data.curIndex++
if (data.curIndex >= data.buyList.length) {
data.curIndex = 0
}
setTimeout(() => {
data.opacity = 0
setTimeout(() => {
startAnimate()
}, (data.waitForTime + 1) * 800)
}, data.delayTime * 800)
}
const moveHandle = () => {}
// 获取优惠券信息
const getNocheckList = () => {
post('/api/v1/UserCoupon/getNocheckList').then((res) => {
data.couponList = []
for (let i = 0; i < res.data.length; i++) {
if(res.data[i].type != 20) {
data.couponList.push(res.data[i])
}
}
if (data.couponList.length != 0) {
data.showCouponBox = true
}
})
}
const hanleClose = () => {
data.danguige = false
data.number1 = 1
}
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件')
}
}
}
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件')
}
}
}
const plusBtn1 = (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件')
}
}
}
const followSubscribe = () => {
uni.navigateTo({
url: '/pages/article/index'
})
}
// 订阅
const toSubscribe = () => {
post(`/api/v1/goods/subscribe/${data.group_id}`).then((res) => {
item.value.is_subscribe = 1
showToast('订阅成功')
isOpenSubscribeRed()
if(data.is_subscribe === 0) {
uni.navigateTo({
url: '/pages/article/index'
})
}
})
}
// 取消订阅
const cancelSubscribe = () => {
post(`/api/v1/goods/subscribe/cancel/${data.group_id}`).then((res) => {
showToast('已退订')
item.value.is_subscribe = 0
isOpenSubscribeRed()
})
}
// 收藏团购
const handleCollection = () => {
if(data.is_collect) {
// 取消收藏
post('/api/v1/users/collect/cancel', { type: 1, extend_id: data.group_id }).then((res) => {
data.is_collect = false
showToast('已取消收藏')
})
} else {
post('/api/v1/users/collect', { type: 1, extend_id: data.group_id }).then((res) => {
data.is_collect = true
showToast('收藏成功')
})
}
}
const handleShare = async () => {
uniShare(item.value.title, data.imageUrl, data.shareUrl)
}
function handleTabs(val, selector) {
data.tabVal = val
uni.pageScrollTo({
selector: '#' + selector,
offsetTop: 150,
duration: 0
})
}
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
}
}
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' })
}
})
}
async function getGoodsSkus1(e) {
await get(`/api/v1/goods/spec/${e.id}`).then((res) => {
data.danTextModule = res.data.text_modules || []
data.textType = res.data.text_type
data.mainImg = res.data.gallery
data.avatars = res.data.avatars
})
if (e.goods.limit_type == 1) {
data.number1 = e.goods.start_sale_num
}
data.danguige = true
data.list_1 = e
}
const getGoodsSkus2 = (res) => {
post('/api/v1/carts', {
shop_goods_id: res.pivot.shop_goods_id,
shop_goods_sku_id: 0,
num: data.number1,
shop_group_goods_id: res.pivot.shop_group_goods_id,
source_id: data.source_id,
source_type: data.source_type
}).then((res) => {
showToast('已加入购物车')
data.danguige = false
getCartList()
data.number1 = 1
}).catch((error) => {
showToast(error)
})
}
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(item.value.limit_type === 2 && data.number >= item.value.limit) {
showToast('本团商品限购' + item.value.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()
})
})
}
})
}
}
function changeNumTwo(e, number) {
// 减按钮
if(e.value < number && number > 0) {
data.number1 -= 1
} else if(e.value > number) { // 加按钮
if(item.value.limit_type === 2 && data.number >= item.value.limit) {
showToast('本团商品限购' + item.value.limit + '件')
return
}
data.number1 += 1
}
}
// 预览图片
const preViewImg = (img, e) => {
if(e.type === 'load') {
return
}
let imurl = img + data.img_preview_suffix
if(img.indexOf('.gif') >= 0 || img.indexOf('.GIF') >= 0) {
imurl = img
}
uni.previewImage({
urls: [imurl],
current: 0
})
}
async function getDetail() {
await get(`/api/v1/goods/group/detail/${data.group_id}`).then((res) => {
data.userInfo = res.user
if(res.data.status == 5) {
data.hasRemove = true
}
// 当前团购未设置仅新人可购 或 设置了仅新人可购并且当前用户是新人 才可以购买
data.can_buy = !res.data.is_new_purchase || (res.data.is_new_purchase && res.user.is_purchase === 0)
data.groupCoupons = res.data.groupCoupons || []
// 如果团购为已结束状态,改为和售罄状态一样
item.value = JSON.parse(JSON.stringify(res.data))
data.orign_status = res.data.sold_status
if(res.data.sold_status == 2) {
item.value.total_stock = 0
item.value.group_goods.forEach((it) => {
it.goods.stock = 0
})
}
if(res.data.sold_status == 1 && res.data.total_stock <= 0) {
data.orign_status = 2
}
// 商品短期下架,将商品库存设为0
item.value.group_goods.forEach((it) => {
if(it.goods && it.goods.short_status == 0) {
it.goods.stock = 0
}
})
if(item.value.service_provider) {
let collect = uni.getStorageSync('collect')
data.collect_shop = collect ? collect : {}
data.collect_shop[item.value.service_provider.id] = data.collect_shop[item.value.service_provider.id] || false
}
data.is_subscribe = res.user && res.user.is_subscribe
data.is_collect = res.data.is_collect
data.is_show_sales = res.data.is_show_sales === 1
data.show_stock = res.data.shop.show_stock
if(res.data.red_status === 1 && !res.data.is_receive_red && res.data.is_red_could_receive) {
data.showRedPaper = true
}
data.textModules = res.data.text_modules || []
data.stickyCalculate = new StickyCalculate(
res.data.types.map((i) => i.id)
)
item.value.created_at = res.data.created_at.split(' ')[0]
// 开团剩余时间
getSoldOffTime()
// 未到开团时间
getStartTime()
if(res.data.types.length !== 0) {
data.typeId = res.data.types[0].id
}
// 本团商品
if (item.value.group_goods.length === 1) {
data.goodsClass = 'per100'
} else if (item.value.group_goods.length === 2) {
data.goodsClass = 'per50'
} else {
data.goodsClass = 'per47'
}
// 分组下商品
let groupGoods = item.value.group_goods
for (let i = 0; i < groupGoods.length; i++) {
let itm = groupGoods[i]
item.value.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)
}
item.value.types.forEach((it, i) => {
if(it.list && it.list.length === 0) {
item.value.types.splice(i, 1)
}
})
if(item.value.group_goods.length === 0) {
item.value.types = []
}
if (data.zeroList.length > 0){
item.value.types.push({
id: 0,
list: data.zeroList
})
}
uni.setNavigationBarTitle({
title: res.data.title
})
data.loading_box = false
// 判断是否显示订阅红包
isOpenSubscribeRed()
sourceId.value = data.source_id
sourceType.value = data.source_type
// 获取讲解视频
if(data.show_explain_video && res.data.explain_video && res.data.explain_video.explain_video) {
data.video_url = res.data.explain_video.explain_video_convert || res.data.explain_video.explain_video
uni.getImageInfo({
src: data.video_url + '?x-oss-process=video/snapshot,t_1000,m_fast',
success: function(req) {
let rate = req.width / req.height
data.videoWid = rate > 1 ? 130 : 88
data.videoHg = (data.videoWid / rate).toFixed(2)
uni.getSystemInfo({
success: (ress) => {
data.write[0] = ress.windowWidth - data.videoWid - 10
data.write[1] = ress.windowHeight - 375 - data.videoHg
}
})
setTimeout(() => {
data.showDialog = true
}, 200)
}
})
}
})
}
function onTimeChange(e) {
data.timeData = e
}
function timeFinish() {
item.value.sold_status = 1
getSoldOffTime()
}
function offTimeChange(e) {
data.offtimeData = e
}
function offtimeFinish() {
item.value.sold_status = 2
}
function getSoldOffTime() {
if (item.value.sold_off_time && item.value.sold_status === 1) {
let endAt = new Date(item.value.sold_off_time.replace(/-/g, '/')).getTime() // 结束时间
let nowAt = new Date().getTime() // 当前时间
let timestamp = endAt - nowAt //计算时间差
data.endtime = timestamp
}
}
function getStartTime() {
if (item.value.sold_status === 0 && item.value.sold_start_time) {
let startAt = new Date(
item.value.sold_start_time.replace(/-/g, '/')
).getTime() // 开始时间
let nowAt = new Date().getTime() // 当前时间
let timestamp = startAt - nowAt //计算时间差
data.startTime = timestamp
}
}
function isOpenSubscribeRed() {
if(!item.value.is_receive_subscribe_red) {
if(item.value.is_subscribe === 1 && data.userInfo.is_subscribe === 1) {
data.showDyRed = true
data.showPopOverRed = false
} else {
data.showPopOverRed = true
}
}
}
// 切换滑动
function changeTest(e) {
if (data.lockScoll) {
return
}
let actionId = data.stickyCalculate.opFixArr(e.currentTarget.id, e.detail.isFixed).getActionId()
if (actionId > 0) {
data.typeId = actionId
}
data.lockScoll = true
setTimeout(() => {
data.lockScoll = false
}, 400)
}
function skuScroll(e) {
if(e.detail.scrollTop > 200){
data.imgWidth = 100
} else {
data.imgWidth = 150
}
}
const getRecommendList = () => {
get(`/api/v1/goods/recommend/${data.group_id}`).then((res) => {
data.recommendGroup = res.data
})
}
// 切换分组
const changeType = (typeId) => {
if (typeId == data.typeId) {
return
}
data.typeId = typeId
uni.createSelectorQuery().select('.group' + typeId).boundingClientRect((req) => {
uni.createSelectorQuery().select('.goods').boundingClientRect((res) => {
uni.pageScrollTo({
scrollTop: req.top - res.top - (data.customVal.top * 2 - data.statusBarHeight + data.customVal.height) + 10,
duration: 0
})
}).exec()
}).exec()
}
// 跟团记录
async function getBuyList() {
let res = await get(`/api/v1/goods/record/${item.value.id}`, {
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
if(res.meta.total === 0) {
data.tabsList.splice(2, 1)
}
startAnimate()
}
function moreRecord() {
data.page += 1
getBuyList()
}
const getGoodsSkus = (goods) => {
data.shortStatus = goods.goods.short_status
if(!data.can_buy && goods.specs_type === 0) {
return
}
if(goods.goods.stock <= 0 && goods.specs_type === 0) {
showToast('商品已被抢光了')
return
}
if(item.value.limit_type === 2 && data.number >= item.value.limit) {
showToast('本团商品限购' + item.value.limit + '件')
return
}
if(data.can_buy && goods.specs_type === 0) {
getGoodsSkus1(goods)
return
}
if(goods.goods.show_sku_style == 1 || goods.goods.show_sku_style == 2) {
data.specsNum = item.value.group_goods[0].goods.show_sku_style == 1 ? 2 : 3
data.showVanSku = true
data.goodId = goods.id
} else {
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()
// 直接购买
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(item.value.limit_type == 1 && num < item.value.start_sale_num) {
showToast('距离起购件数还差' + (item.value.start_sale_num - num) + '件')
jumpFloor()
if (item.value.group_goods.length === 1 && item.value.group_goods[0].specs_type == 1) {
data.type = 2
getGoodsSku(item.value.group_goods[0])
}
} else {
uni.setStorageSync('shopGoods', cartList)
uni.navigateTo({
url: '/pages/pay/index?type=1&source=' + data.source
})
}
}
} else if (item.value.group_goods.length === 1) {
if (item.value.group_goods[0].specs_type == 1) {
if(item.value.group_goods[0].goods.show_sku_style == 1 || item.value.group_goods[0].goods.show_sku_style == 2) {
data.specsNum = item.value.group_goods[0].goods.show_sku_style == 1 ? 2 : 3
data.showVanSku = true
data.goodId = item.value.group_goods[0].id
} else {
// 如果设置了团购起购数量&&没有添加任何商品&&团购仅有一个商品,拉起商品弹窗,否则可直接购买
if(item.value.limit_type == 1 && item.value.start_sale_num > 1) {
data.type = 2
getGoodsSku(item.value.group_goods[0])
} else {
data.goodId = item.value.group_goods[0].id
data.showMorePay = true
}
}
} else {
if(item.value.group_goods[0].goods.stock <= 0) {
return showToast('当前商品已经抢光啦')
}
data.goodId = item.value.group_goods[0].id
data.showMorePay = true
}
} else {
showToast('请选择商品')
jumpFloor()
}
}
// 到货提醒
async function arrivalNotice() {
if(item.value.is_subscribe_remind_stock) {
post(`/api/v1/goods/remind/cancel/${data.group_id}`, {type: 1}).then((res) => {
item.value.is_subscribe_remind_stock = false
showToast('已取消到货提醒')
})
} else {
toMiniProgram('pages/groups/index?id=' + data.group_id)
}
}
function closeSku(val) {
data.type = 1
showSku.value = false
data.showVanSku = false
}
function toPage(url, type) {
if (type === 1) {
uni.navigateTo({ url })
return
}
uni.switchTab({ url })
}
function toJump(url, e) {
if(e.type == 'tap' || e.type == 'click' || e.type == 'onClick') {
uni.navigateTo({ url })
}
}
const getnum = () => {
showBtn.value = true
getStartTime()
getCartList()
getNum()
}
// 分享路径
const getShareUrl = async () => {
await post('/api/v1/user/share', {
page: 'pages/groups/index',
query: `id=${data.group_id}`
}).then((res) => {
data.shareUrl = res.data.path
})
}
// 锚点跳转
const jumpFloor = (time = 300) => {
uni.pageScrollTo({
selector: '#goodsGroup',
offsetTop: -150,
duration: 0
})
}
function swiperChange(e) {
data.swiperIndex = e.detail.current
}
// 查看商品
function viewGoods() {
// 如果团购商品只有一个
if(item.value.group_goods.length === 1) {
jumpFloor(0)
// 单规格
if(item.value.group_goods[0].specs_type === 0) {
getGoodsSkus1(item.value.group_goods[0])
} else { // 多规格
getGoodsSkus(item.value.group_goods[0])
}
} else {
jumpFloor()
}
}
// 获取分享图
const getShareImage = async () => {
await post('/api/v1/sales/share', {
shop_goods_id: item.value.id
}).then((res) => {
data.imageUrl = res.data[0] && res.data[0].image
})
}
// 获取商品评论
const getComment = () => {
get(`/api/v1/goods/comment/${item.value.id}`, {
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
if(res.meta.total !== 0) {
setTimeout(() => {
uni.createSelectorQuery().select('.commentBox').boundingClientRect((res) => {
data.commentHg = res ? res.height : 0
}).exec()
}, 1000)
}
})
}
const preventD = () => {
return
}
let pages = getCurrentPages()
data.pagesLength = pages.length
// 获取当前团购购物车数据
const getCartList = async () => {
let shop_goods = []
await get('/api/v1/carts', {
shop_group_goods_id: data.group_id
}).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 = []
item.value.group_goods && item.value.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
}
item.value.group_goods && item.value.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 showSaveVideo = (url) => {
uni.showActionSheet({
itemList: ['保存视频'],
success: (res) => {
downloadVideo(url)
},
fail: (err) => {
// 取消
}
})
}
function selectPop(e) {
if(e.id == 0) {
toBack('home')
} else if(e.id == 1) {
openService({type: 'click'})
} else if(e.id == 2) {
toPage('/pages/search/index', 1)
} else if(e.id == 3) {
toPage('/pages/mine/collection/index', 1)
} else if(e.id == 4) {
toPage('/pages/cart/index')
} else if(e.id == 5) {
data.fontSize = data.fontSize == 'small' ? 'large' : 'small'
data.actions[5].text = data.fontSize == 'small' ? '调大字体' : '调小字体'
uni.setStorageSync('font', data.fontSize)
}
}
// 回退上一级
const toBack = (val) => {
if(val == 'back') {
if(data.pagesLength > 1) {
uni.navigateBack({ delta: 1 })
} else {
uni.switchTab({
url: '/pages/index/index'
})
}
} else {
uni.switchTab({
url: '/pages/index/index'
})
}
}
// 领取红包
function receiveRed() {
data.showRedPaper = true
}
// 拆红包
function openRedPaper() {
uni.showLoading({
title: '正在打开...'
})
post('/api/v1/UserCoupon/receiveGroupCoupon', {shop_goods_id: data.group_id}).then((res) => {
setTimeout(() => {
uni.hideLoading()
data.showRedOne = false
data.showRedTwo = true
item.value.is_receive_red = true
}, 1000)
})
}
// 打开订阅红包
function openDyRed() {
uni.showLoading({
title: '正在打开...'
})
post('/api/v1/userCoupon/subscribe/receive').then((res) => {
data.dyRedData = res.data
setTimeout(() => {
item.value.is_receive_subscribe_red = true
uni.hideLoading()
data.showDyOne = false
data.showDyTwo = true
data.showPopOverRed = false
}, 1000)
})
}
// 使用红包
function toUseRedPaper() {
data.showRedPaper = false
}
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]
}
})
}
// 下载zip文件
async function downloadZip(it) {
if(await judgePrivacy()) {
data.showPrivacy = true
return false
}
uni.downloadFile({
url: it.url,
// filePath: wx.env.USER_DATA_PATH + '/test.doc',
fileName: it.name,
success: res => {
if(it.name.indexOf('.zip') !== -1) {
uni.shareFileMessage({
filePath: res.tempFilePath,
fileName: it.name,
success(ress) {
}
})
} else {
uni.openDocument({
filePath: res.tempFilePath,
showMenu: true,
success: function (res) {}
})
}
}
})
}
function getBarHeight() {
data.timeOut = setTimeout(() => {
data.barHeight = data.statusBarHeight + 40
uni.createSelectorQuery().select('.oneBox').boundingClientRect((res0) => {
data.oneBoxHg = res0 ? res0.height : 0
uni.createSelectorQuery().select('.goods-group').boundingClientRect((res1) => {
data.goodsHg = res1 ? res1.height : 0
}).exec()
}).exec()
}, 2000)
let num = 0
data.interval = setInterval(() => {
num += 1
if(num > 10) {
clearInterval(data.interval)
data.interval = null
} else {
uni.createSelectorQuery().select('.good-detail').boundingClientRect((res2) => {
data.detailHg = res2 ? res2.height : 0
}).exec()
}
}, 2000)
}
const container = ref(null)
function goodsRemind(flag) {
item.value.is_subscribe_remind_stock = flag
}
function collectShop() {
data.collect_shop[item.value.service_provider.id] = !data.collect_shop[item.value.service_provider.id]
uni.showToast({
title: data.collect_shop[item.value.service_provider.id] ? '关注成功' : '取消成功',
icon: 'success'
})
uni.setStorageSync('collect', data.collect_shop)
}
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
}
function toSupplier(sid, id) {
// if(sid) {
// uni.navigateTo({
// url: '/pages/mine/other/supplier?id=' + id
// })
// }
}
function toDirect() {
data.showDirect = false
if(item.value.group_goods && item.value.group_goods[0]) {
toPage('/pages/mine/other/directsales/validate?id=' + item.value.group_goods[0].goods_id, 1)
}
}
function openService() {
data.showService = true
}
function openCart() {
if(data.showCart) {
data.showCart = false
} else {
if(data.number) {
data.showCart = true
} else {
showToast('请选择商品')
jumpFloor(0)
}
}
}
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()
})
}
}
// 领取团购关联优惠券
function recvCoupon(it) {
post('/api/v1/userCoupon/normal/receive', {shop_coupon_id: it.id}).then((res) => {
if(it.scene_type == 2) {
it.user_coupon_status = 1
}
it.receive_coupon_type = 1
showToast('领取成功')
})
}
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)
}
// 支付返回信息
function payBack(itm) {
data.backInfo = itm
}
function isPayOrder() {
if(data.backInfo) {
uni.showLoading({
title: '加载中...',
mask: true
})
get(`/api/v1/pay/check/${data.backInfo.pay_id}`).then((res) => {
if(data.backInfo.source == 'direct') {
data.showMorePay = false
}
uni.hideLoading()
if(res.data.status) {
uni.redirectTo({
url: '/pages/success/index?id=' + data.backInfo.create_id + '&type=1&pay_id=' + data.backInfo.pay_id + '&from=' + data.backInfo.from
})
} else {
showToast('支付失败')
uni.redirectTo({ url: '/pages/order/list/index' })
}
})
}
}
return {
uniShare,
skus_1,
parseTime,
provTxt,
whetherLogin,
...toRefs(data),
sourceId,
sourceType,
container,
handleSubscrip,
getNocheckList,
moveHandle,
startAnimate,
item,
getDetail,
handleShare,
handleTabs,
toSubscribe,
handleCollection,
cancelSubscribe,
followSubscribe,
changeNumOne,
plusBtn,
plusBtn1,
changeNumTwo,
hanleClose,
getBuyList,
moreRecord,
toBack,
toPay,
toPage,
toJump,
showSku,
getGoodsSku,
skuInfo,
getNum,
num,
closeSku,
showBtn,
getnum,
getShareUrl,
jumpFloor,
viewGoods,
swiperChange,
getImg,
preViewImg,
getShareImage,
getComment,
preventD,
getGoodsSpecs,
getCartList,
getGoodsSkus,
changeType,
isRepeat,
showSaveVideo,
changeTest,
to_VipPage,
getGoodsSkus1,
getGoodsSkus2,
hanleImgs,
viewSmallImg,
viewVideo,
getRecommendList,
skuScroll,
receiveRed,
openRedPaper,
toUseRedPaper,
judgeHasNewVip,
getGiftsInfo,
arrivalNotice,
getShopInfo,
openDyRed,
isOpenSubscribeRed,
downloadZip,
getBarHeight,
onTimeChange,
timeFinish,
offTimeChange,
offtimeFinish,
getStartTime,
getSoldOffTime,
goodsRemind,
collectShop,
parseText,
toSupplier,
toDirect,
plusCartBtn,
openCart,
openService,
changeCartNum,
recvCoupon,
avatarAnimate,
toMiniProgram,
payBack,
isPayOrder,
selectPop
}
},
async onLoad(options) {
// // await this.$onLaunched
this.vip_on = uni.getStorageSync('vip_on') || 0
this.fontSize = uni.getStorageSync('font') || 'small'
this.actions[5].text = this.fontSize == 'small' ? '调大字体' : '调小字体'
this.is_vip = uni.getStorageSync('is_vip') || false
this.img_preview_suffix = uni.getStorageSync('img_preview_suffix') || ''
this.show_explain_video = uni.getStorageSync('show_explain_video')
2025-06-14 10:01:48 +08:00
this.group_id = options.id * 1
2025-05-08 09:16:37 +08:00
const _this = this
uni.getSystemInfo({
success: (res) => {
this.statusBarHeight = res.statusBarHeight
}
})
await _this.getDetail()
this.Color = uni.getStorageSync('theme_color')
this.priceColor = Style[uni.getStorageSync('theme_index') * 1].priceColor
this.tagColor = Style[uni.getStorageSync('theme_index') * 1].tagColor
this.bgColor = Style[uni.getStorageSync('theme_index') * 1].bgColor
this.Theme = uni.getStorageSync('theme_index') * 1
_this.vipOn = uni.getStorageSync('vip_on') === 1
_this.vip_price_show = uni.getStorageSync('vip_price_show') || false
getShopInfo().then((res) => {
_this.score_on = Number(res.score_on)
_this.img_preview_suffix = res.img_preview_suffix
_this.crop_user_img = res.extendInfo && res.extendInfo.crop_user_ad_banner_url || ''
})
this.getShareImage()
this.getShareUrl()
if(whetherLogin()) {
this.getNum()
this.getCartList()
this.getNocheckList()
this.judgeHasNewVip()
this.getGiftsInfo()
}
_this.getBuyList() // 跟团记录
uni.removeStorageSync('shopGoods')
await _this.getComment() // 获取评论
_this.getRecommendList() // 推荐团购
_this.getBarHeight()
this.avatarTimer = setInterval(_this.avatarAnimate, 2000);
},
onShow() {
let args = plus.runtime.arguments
if (args) {
plus.runtime.arguments = null
this.isPayOrder()
}
},
onUnload() {
clearInterval(this.interval)
this.interval = null
clearInterval(this.timeOut)
this.timeOut = null
clearTimeout(this.onTimeOut)
this.onTimeOut = null
},
onHide() {
clearInterval(this.interval)
this.interval = null
clearInterval(this.timeOut)
this.timeOut = null
clearTimeout(this.onTimeOut)
this.onTimeOut = null
},
onPageScroll(e) {
if (e.scrollTop == 0) {
this.opacityStyle = 0
} else {
let opacity = e.scrollTop / 80
opacity = opacity > 1 ? 1 : opacity
this.opacityStyle = opacity
}
this.showTabs = e.scrollTop > this.oneBoxHg - 300 && this.oneBoxHg != 0
let hg1 = this.oneBoxHg + this.detailHg
this.showJump = e.scrollTop > (this.oneBoxHg > 0 ? this.oneBoxHg : 400) + 100 && e.scrollTop < hg1 - 600
clearTimeout(this.onTimeOut)
this.onTimeOut = setTimeout(() => {
uni.createSelectorQuery().select('.goods-group').boundingClientRect((req) => {
if(req) {
if(req.height + req.top > this.statusBarHeight + 85) {
this.showGroups = true
} else {
this.showGroups = false
}
}
}).exec()
uni.createSelectorQuery().select('#goodDetail').boundingClientRect((req) => {
if(req) {
this.detailHg = req.height
}
}).exec()
hg1 = this.oneBoxHg + this.detailHg
let hg2 = hg1 + this.goodsHg + this.commentHg
let hg3 = hg2 + 245
if(e.scrollTop + 160 < hg1) {
this.tabVal = 0
} else if(hg1 < e.scrollTop + 160 && e.scrollTop + 110 < hg2) {
this.tabVal = 1
} else if(e.scrollTop + 100 > hg3 && this.total > 0) {
this.tabVal = 2
}
}, 200)
},
onPullDownRefresh() {
this.getDetail()
this.getCartList()
setTimeout(() => {
uni.stopPullDownRefresh()
}, 1000)
}
}
</script>
<style lang="scss" scoped>
.whole{
overflow-y: auto;
}
.flex{
display: flex;
align-items: center;
justify-content: center;
}
.flex1{
display: flex;
align-items: center;
justify-content: space-between;
}
.loadBox{
width: 100%;
height: 100vh;
}
.st{
font-size: 28rpx;
}
.black {
color: v-bind('priceColor');
font-weight: 600;
font-size: 36rpx;
.icon{
font-weight: normal;
font-size: 24rpx;
}
}
.text1_box {
margin: 10rpx 0 !important;
line-height: 55rpx;
font-size: 30rpx;
color: #222;
&.large{
font-size: 42rpx;
line-height: 64rpx;
}
}
.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;
}
}
.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{
// font-weight: bold;
flex: 1;
}
&:first-child{
padding-top: 36rpx;
border-top: 1px solid #E7E7E7;
}
&:last-child{
padding-bottom: 36rpx;
}
}
&.large{
.row{
font-size: 36rpx;
.span{font-size: 34rpx;}
}
}
}
.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;
}
&.large{
.tit{
font-size: 42rpx;
}
.txt{
font-size: 36rpx;
}
}
}
.text2 {
font-size: 36rpx !important;
color: v-bind('priceColor');
font-weight: 600;
margin-right: 10rpx;
.icon{
font-weight: normal;
font-size: 24rpx;
}
}
.recomBox{
padding: 30rpx;
background: #fff;
border-top: 20rpx solid #F5F5F5;
position: relative;
z-index: 100;
.title{
font-size: 30rpx;
font-weight: bold;
margin-bottom: 20rpx;
}
.row{
padding: 0 10rpx;
box-sizing: border-box;
overflow: hidden;
flex-shrink: 0;
width: 33.33%;
.img{
width: 214rpx;
height: 214rpx;
}
.tit{
font-size: 26rpx;
font-family: Source Han Sans CN;
font-weight: 400;
color: #2c2c2c;
margin: 10rpx 0;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.price{
font-size: 32rpx;
font-family: Source Han Sans CN;
font-weight: 400;
color: v-bind('priceColor');
.icon {
font-size: 25rpx;
}
}
}
}
.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;
}
.guanzhu{
position: relative;
font-size: 27rpx;
background: v-bind('bgColor');
padding: 15rpx 30rpx;
.txt{
color: v-bind('Color');
}
.anniu {
background: v-bind('Color');
border-radius: 8rpx;
color: #fff;
font-size: 25rpx;
padding: 5rpx 25rpx;
margin-right: 50rpx;
}
.chacha{
position: absolute;
top: 50%;
right: 3%;
transform: translateY(-50%);
color: #a1a1a1;
}
}
.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;
}
}
}
.text_box {
background: #fff;
padding: 30rpx;
.text {
height: 50rpx;
margin-bottom: 20rpx;
background: #e1e1e1;
}
}
.topicon{
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 240rpx;
margin-top: 20px;
height: 70rpx;
.yuan{
width: 60rpx;
height: 60rpx;
margin: 0 20rpx;
border-radius: 50%;
}
}
.top_box{
background: #fff;
margin: -75rpx 30rpx 0;
box-sizing: border-box;
padding: 20rpx;
.top_box_left{
width: 100%;
.imgs {
width: 80rpx;
height: 80rpx;
border: 4px solid #fff;
background: #e1e1e1;
}
}
.desc{
width: 100%;
height: 34rpx;
margin: 10rpx 0;
}
.top_box_right {
width: 50%;
display: flex;
flex-direction: column;
align-items: flex-end;
.li {
width: 130rpx;
height: 48rpx;
background: #e1e1e1;
border-radius: 10rpx;
}
}
}
@keyframes fade {
from {
opacity: 1;
}
50% {
opacity: 0.5;
}
to {
opacity: 1;
}
}
.box {
background: #e1e1e1;
animation: fade 2s infinite;
}
.btn1 {
opacity: 0.65;
}
.right1 {
float: right;
background: v-bind('Color');
color: #fff;
padding: 15rpx 20rpx;
border-radius: 8rpx;
font-size: 24rpx;
white-space: nowrap;
}
.tites {
font-size: 28rpx;
font-family: Source Han Sans CN;
font-weight: 400;
color: #666666;
}
.goods{
min-height: 100%;
padding-bottom: 210rpx;
-webkit-overflow-scrolling: touch;
.vip-tag {
font-size: 32rpx;
color: #fbe6c3;
background: #353648;
border-radius: 20rpx 0 0 0;
padding: 8rpx 10rpx;
line-height: 1;
text{
font-size: 22rpx;
}
}
.goods-bar {
position: fixed;
width: 100%;
z-index: 102;
top: 0;
padding: 35px 15px 5px;
height: 70px;
box-sizing: border-box;
.backBox{
border-radius: 60rpx;
background-color: rgba(255, 255, 255, 0.7);
border: 1px solid #EAEAEA;
height: 60rpx;
box-sizing: border-box;
.back{
width: 74rpx;
height: 100%;
}
.home{
font-size: 26rpx;
display: flex;
align-items: center;
padding: 0 24rpx 0 20rpx;
white-space: nowrap;
border-left: 1px solid #eee;
text{
margin-left: 4rpx;
}
}
}
}
.oneBox{
position: relative;
z-index: 100;
}
.goods-top {
height: 430rpx;
width: 100%;
position: relative;
.bgImg{
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
.linear{
position: absolute;
bottom: 0;
height: 50rpx;
width: 100%;
background: linear-gradient(to bottom , rgba(255,255,255,0.01), #fff);
}
}
.shop-icon {
display: flex;
text-align: center;
width: calc(100% - 220rpx);
justify-content: flex-end;
box-sizing: border-box;
&-item {
background: rgba(255, 255, 255, 0.7);
border-radius: 50%;
width: 60rpx;
height: 60rpx;
margin: 0 10rpx;
.iconfont{
font-size: 20px;
color: #444;
}
}
}
.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;
}
}
}
}
}
.good-detail {
padding: 30rpx;
word-wrap: break-word;
background-color: #fff;
}
.goods-group {
margin-top: 20rpx;
.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;
}
}
}
}
.dis {
opacity: 0.65;
}
.goods-record {
background-color: #fff;
position: relative;
z-index: 100;
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;
}
}
.goods-btn {
position: fixed;
bottom: 0;
display: flex;
align-items: center;
width: 100%;
height: 110rpx;
background: #ffffff;
box-shadow: 0rpx 3rpx 20rpx rgba(0, 0, 0, 0.16);
box-sizing: border-box;
z-index: 201;
&-icon {
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;
}
}
}
&-icon:nth-child(3) {
border: none;
}
.btn {
display: flex;
align-items: center;
justify-content: center;
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;
}
}
}
.goods-sale{
position: fixed;
bottom: 0;
width: 100%;
display: flex;
justify-content: space-around;
align-items: center;
background-color: #fff;
height: 110rpx;
z-index: 201;
&-item{
display: flex;
justify-content: center;
align-items: center;
width: 100%;
font-size: 26rpx;
color: v-bind('priceColor');
position: relative;
&:after{
content: '';
position: absolute;
top: 50%;
width: 1px;
height: 36rpx;
margin-top: -18rpx;
background-color: #d8d8d8;
right: 0;
}
.icon{
background-repeat: no-repeat;
background-size: 900px 900px;
height: 21px;
width: 21px;
transform: scale(0.8);
&.icon1{
background-position: -193.5px -563px;
&.color0{
background-position: -193.5px -563px;
}
&.color1{
background-position: -193.5px -597.5px;
}
&.color2{
background-position: -193.5px -631.5px;
}
&.color3{
background-position: -193.5px -664px;
}
&.color4{
background-position: -193.5px -698.5px;
}
}
&.icon2{
background-position: -243.5px -563px;
&.color0{
background-position: -243.5px -563px;
}
&.color1{
background-position: -243.5px -597.5px;
}
&.color2{
background-position: -243.5px -631.5px;
}
&.color3{
background-position: -243.5px -664px;
}
&.color4{
background-position: -243.5px -698.5px;
}
}
&.icon4{
background-position: -293.5px -563px;
&.color0{
background-position: -293.5px -563px;
}
&.color1{
background-position: -293.5px -597.5px;
}
&.color2{
background-position: -293.5px -631.5px;
}
&.color3{
background-position: -293.5px -664px;
}
&.color4{
background-position: -293.5px -698.5px;
}
}
}
}
.volume{
flex-direction: column;
.sbl{
font-size: 24rpx;
.nub{
font-size: 26rpx;
}
}
.per{
font-size: 22rpx;
color: #666666;
}
}
&-item:last-child{
&:after{
width: 0;
}
}
}
.suspendBtn{
position: fixed;
left: 50%;
transform: translate(-50%, 0);
background-color: #fff;
font-size: 30rpx;
color: #999;
border-radius: 40rpx;
padding: 5rpx 20rpx;
box-shadow: 0rpx 3rpx 20rpx rgba(0, 0, 0, 0.16);
z-index: 101;
}
.commentBox{
padding: 30rpx;
background-color: #fff;
position: relative;
z-index: 100;
border-top: 20rpx solid #F5F5F5;
.toptitle{
display: flex;
align-items: center;
justify-content: space-between;
.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;
}
}
}
}
}
.sale-goods{
padding: 30rpx;
box-sizing: border-box;
.vanbox{
max-height: 65vh;
overflow: auto;
margin-bottom: 30rpx;
.qaTxt{
color: #333;
font-size: 28rpx;
line-height: 46rpx;
margin-bottom: 30rpx;
}
}
.row{
font-size: 24rpx;
line-height: 50rpx;
.zip{
word-break: break-all;
}
.download{
color: #007aff;
margin-left: 20rpx;
}
}
&-item{
padding: 10rpx 0;
border-bottom: 1rpx solid #e5e5e5;
.share{
border: 1rpx solid v-bind('Color');
border-radius: 6rpx;
padding: 4rpx 10rpx;
margin-left: 20rpx;
font-size: 22rpx;
color: v-bind('Color');
display: inline;
line-height: 1;
}
}
.title{
font-size: 34rpx;
text-align: center;
padding-bottom: 30rpx;
font-weight: 600;
position: relative;
.icon{
position: absolute;
right: 0;
top: 0;
}
}
.price,
.item{
padding: 10rpx 0;
font-size: 28rpx;
}
.item {
.copy{
border: 1rpx solid #d3d3d3;
border-radius: 6rpx;
padding: 2rpx 10rpx;
margin-left: 20rpx;
font-size: 22rpx;
line-height: 1;
display: inline-block;
}
}
.price {
.commission {
color: v-bind('Color');
}
.sku {
margin-top: 10rpx;
}
}
.btnbox{
width: 100%;
.btn{
height: 86rpx;
width: 100%;
background-color: v-bind('Color');
color: #fff;
font-size: 30rpx;
border-radius: 49rpx;
}
}
}
&-tip{
position: fixed;
bottom: 110rpx;
width: 100%;
background-color: #fff3cd;
color: #f66d2d;
font-size: 28rpx;
height: 50rpx;
line-height: 50rpx;
text-align: center;
z-index: 100;
}
}
.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;
}
}
}
.down{
width: 100rpx;
height: 100rpx;
background-color: #007aff;
color: #ffffff;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.video{
display: block;
}
.good_box{
height: calc(70vh - 270rpx);
.edition{
padding-bottom: 50rpx;
}
.edition_box{
margin: 8rpx 0;
position: relative;
padding: 0 20rpx;
.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;
}
}
.text{
line-height: 55rpx;
font-size: 30rpx;
color: #222;
}
}
}
.sku-top{
height: 70vh;
overflow: hidden;
position: relative;
.img{
width: 150rpx;
height: 150rpx;
background: #bbbbbb;
border-radius: 8rpx;
margin-right: 30rpx;
transition: all 0.3s;
}
.sku-top-box{
border-bottom: 1rpx solid #eee;
padding-bottom: 10rpx;
display: flex;
padding: 30rpx;
justify-content: space-between;
.goodcol{
width: calc(100% - 180rpx);
.tit{
width: calc(100% - 70rpx);
margin-bottom: 8rpx;
}
}
.pricebox{
display: flex;
align-items: center;
flex-wrap: wrap;
margin-bottom: 20rpx;
.text1{
font-size: 34rpx;
color: #f66d2d;
font-weight: 600;
margin-right: 12rpx;
}
.icon1{
font-size: 24rpx;
}
.vip{
display: flex;
align-items: center;
font-size: 34rpx;
color: #f66d2d;
font-weight: bold;
}
}
.text{
font-size: 24rpx;
color: #999999;
}
}
.sku_box{
border-bottom: 1rpx solid #eee;
font-size: 28rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx;
.red{
color: #f56a18;
margin-left: 10rpx;
}
.item1{
display: inline-block;
image{
width: 50rpx;
height: 50rpx;
margin-right: 10rpx;
border-radius: 5rpx;
}
}
}
.sku-buy{
display: flex;
align-items: center;
padding: 30rpx;
border-bottom: 1rpx solid #eee;
font-size: 28rpx;
margin-bottom: 30rpx;
.imgbb{
width: 50rpx;
height: 50rpx;
margin-left: -10rpx;
border: 4rpx solid #fff;
box-sizing: border-box;
image{
width: 100%;
height: 100%;
border-radius: 10rpx;
}
}
.red{
color: v-bind('priceColor');
}
}
.addbtn{
background-color: #fff;
position: absolute;
bottom: 0;
left: 0;
height: 104rpx;
width: 100%;
}
.btn{
position: absolute;
height: 104rpx;
color: #fff;
font-size: 30rpx;
background: v-bind('Color');
width: 100%;
display: flex;
align-items: center;
justify-content: center;
bottom: 0;
left: 0;
}
}
.swiper-img{
width: 30px;
height: 30px;
}
.goods-bar-icon{
display: flex;
align-items: center;
justify-content: space-between;
height: 100%;
}
.broadcast{
height: 60rpx;
background: rgba(0, 0, 0, 0.6);
opacity: 0;
color: #fff;
font-size: 24rpx;
border-radius: 36px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 10rpx;
box-sizing: border-box;
line-height: 60rpx;
position: absolute;
bottom: 40%;
left: 30rpx;
.broadcast-time{
margin-left: 10rpx;
}
}
.couponBox{
width: 640rpx;
background: #ffff;
border-radius: 15rpx;
.couponTitle{
text-align: center;
line-height: 110rpx;
font-size: 30rpx;
font-weight: bold;
}
.couponBtn{
width: 90%;
height: 80rpx;
background: #f14939;
margin: 30rpx auto;
border-radius: 15rpx;
text-align: center;
line-height: 80rpx;
color: #fff;
}
.coupon{
margin-bottom: 20rpx;
}
.couponImg{
width: 90%;
height: 180rpx;
position: relative;
left: 50%;
transform: translateX(-50%);
}
.couponmoney{
position: absolute;
top: 50%;
left: 7%;
transform: translateY(-50%);
color: #f14939;
.sign{
font-size: 28rpx;
color: #f14939;
}
.money{
font-size: 48rpx;
font-weight: bold;
}
.tit{
font-size: 24rpx;
text-align: center;
}
}
.coupontype{
position: absolute;
left: 36%;
top: 40rpx;
font-size: 30rpx;
font-weight: bold;
color: #f14939;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 54%;
}
.coupontime{
position: absolute;
left: 36%;
top: 105rpx;
font-size: 22rpx;
color: #98989f;
}
}
.scrolly{
min-height: 160rpx;
max-height: calc(60vh - 200rpx);
}
.goodqa{
display: flex;
align-items: center;
}
.imgbox{
padding: 20rpx 0;
.img{
width: 100%;
border-radius: 0;
}
}
.sucai{
box-shadow: 0 -1px 9px #ebedf0;
border-radius: 6rpx;
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx 20rpx 20rpx 30rpx;
margin-top: 24rpx;
.tit{
font-size: 30rpx;
font-weight: bold;
}
.right{
width: calc(100% - 150rpx);
display: flex;
justify-content: space-between;
align-items: center;
.itm{
height: 70rpx;
border-left: 1px solid #F2F2F2;
display: flex;
align-items: center;
.img{
width: 70rpx;
height: 70rpx;
margin-right: 20rpx;
border-radius: 6rpx;
vertical-align: bottom;
}
}
.btn{
background: v-bind('Color');
color: #fff;
font-size: 24rpx;
padding: 8rpx 16rpx;
border-radius: 8rpx;
display: flex;
}
}
}
.sunsheet{
padding: 20rpx 0;
background: #fff;
border-bottom: 1px solid #F2F2F2;
.tit{
display: flex;
font-size: 30rpx;
font-weight: bold;
align-items: center;
justify-content: space-between;
text{
font-size: 28rpx;
font-weight: normal;
}
}
.sunbox{
display: flex;
flex-wrap: wrap;
.itm{
width: 32%;
height: 0;
position: relative;
padding-top: 32%;
margin-right: 2%;
margin-top: 20rpx;
&:nth-child(3n+3){
margin-right: 0;
}
.img{
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 100%;
height: 100%;
}
}
}
}
.qabox{
padding: 20rpx 0;
background: #fff;
border-bottom: 1px solid #F2F2F2;
.tit{
display: flex;
font-size: 30rpx;
font-weight: bold;
align-items: center;
justify-content: space-between;
text{
font-size: 28rpx;
font-weight: normal;
}
}
.god{
padding-top: 20rpx;
.tt{
font-size: 28rpx;
line-height: 60rpx;
}
}
}
.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;
}
}
}
}
.per100{
width: 100%;
}
.per50{
min-width: 50%;
}
.per47{
min-width: 47%;
}
.typeBox{
height: 90rpx;
border-bottom: 1px solid #dfdfdf;
display: flex;
align-items: center;
justify-content: space-around;
background: #fff;
box-sizing: border-box;
.col{
color: #646566;
font-size: 28rpx;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
position: relative;
&.active:after{
position: absolute;
bottom: 0;
left: 50%;
bottom: 0;
width: 40px;
height: 3px;
margin-left: -20px;
content: '';
background: v-bind('Color');
}
}
}
.bbox{
&.shux{
display: flex;
}
.left{
&.shux{
width: 200rpx;
background: #F5F5F5;
}
}
.typeBox{
&.shux{
display: block;
flex-direction: column;
background: transparent;
width: 200rpx;
border-bottom: none;
height: calc(100vh - 152px);
overflow: auto;
position: sticky;
.col{
height: auto;
padding: 30rpx 20rpx;
border-left: 3px solid #F5F5F5;
box-sizing: border-box;
width: 100%;
justify-content: flex-start;
&.active{
border-left: 3px solid v-bind('Color');
background: #fff;
&:after{
display: none;
}
}
}
}
}
.goodBox{
&.shux{
width: calc(100% - 200rpx);
position: relative;
z-index: 100;
.left{
width: 140rpx;
height: 140rpx;
}
}
}
}
.empty{
width: 100%;
}
.vvbox{
padding: 0 30rpx;
background: #fff;
}
.tabsBox{
width: 100%;
height: 37px;
display: flex;
align-items: center;
justify-content: space-around;
position: fixed;
top: 0;
background-color: #fff;
z-index: 101;
.col{
font-size: 30rpx;
color: #222;
height: 100%;
box-sizing: border-box;
display: flex;
align-items: center;
border-bottom: 2px solid #fff;
&.active{
border-bottom: 2px solid v-bind('Color');
color: v-bind('Color');
font-weight: 600;
}
}
}
.vanBox{
width: 100%;
margin-top: -75rpx;
padding: 0 30rpx;
position: relative;
z-index: 10;
box-sizing: border-box;
background: linear-gradient(to bottom , rgba(255,255,255,0.01), rgba(255,255,255,1));
.shop_info{
width: 100%;
padding: 30rpx 20rpx 20rpx;
box-sizing: border-box;
background: linear-gradient(to bottom , rgba(255,255,255,0.6), #f9f9f9);
border-radius: 10rpx;
.one{
display: flex;
align-items: center;
justify-content: space-between;
}
.logobox{
display: flex;
align-items: center;
.img{
width: 80rpx;
height: 80rpx;
background: #fff;
box-shadow: 0rpx 3rpx 6rpx rgba(0, 0, 0, 0.16);
border-radius: 10rpx;
margin-right: 20rpx;
}
.name{
font-size: 30rpx;
font-weight: bold;
}
}
.sub_box{
.row{
font-size: 24rpx;
display: flex;
align-items: center;
justify-content: center;
width: 120rpx;
height: 44rpx;
border-radius: 8rpx;
box-sizing: border-box;
position: relative;
.row2{
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background: v-bind('Color');
color: #fff;
border-radius: 8rpx;
&.bai{
opacity: 0.5;
}
}
&.row1{
background: #fff;
color: v-bind('Color');
border: 1px solid v-bind('Color');
.iconfont{
font-size: 12px;
}
}
.redBox{
position: absolute;
background: rgba(0, 0, 0, 0.8);
color: #fff;
font-size: 24rpx;
display: flex;
align-items: center;
line-height: 1;
padding: 8rpx 12rpx;
top: -70rpx;
white-space: nowrap;
border-radius: 6rpx;
.img{
width: 16px;
height: 16px;
background-repeat: no-repeat;
background-size: 452px 408px;
background-position: -259.67px -136.67px;
}
&:after{
content: "";
width: 0px;
height: 0px;
border-top: 10rpx solid rgba(0, 0, 0, 0.8);
border-left: 10rpx solid transparent;
border-right: 10rpx solid transparent;
position: absolute;
bottom: -10rpx;
left: 50%;
margin-left: -5rpx;
}
}
}
}
.desc{
font-size: 24rpx;
color: #666;
line-height: 42rpx;
padding: 12rpx 0;
}
.vip_desc{
font-size: 24rpx;
color: #666;
display: flex;
align-items: center;
justify-content: space-between;
padding-top: 16rpx;
border-top: 1px solid #F2F2F2;
.tit{
display: flex;
align-items: center;
font-size: 24rpx;
color: #555;
&.score{
width: 50%;
padding-left: 20rpx;
box-sizing: border-box;
border-left: 1px solid #D1D1D1;
}
}
&.er{
.tit{
width: 50%;
display: flex;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
padding-right: 10rpx;
}
}
.text{
font-size: 22rpx;
color: #999;
display: flex;
}
.hg{
width: 15px;
height: 15px;
margin-right: 6rpx;
background-repeat: no-repeat;
background-size: 226px 204px;
background-position: -136.67px -91.33px;
}
}
}
}
.new_person{
margin-top: 24rpx;
image{
width: 100%;
border-radius: 14rpx;
vertical-align: bottom;
}
}
.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;
}
}
.movableArea{
position: fixed;
top: 120px;
left: 20rpx;
width: calc(100% - 40rpx);
height: calc(100vh - 240px);
pointer-events: none;
z-index: 100;
}
.movableView{
pointer-events: auto;
}
.videoBox{
text-align: center;
// position: fixed;
// right: 20rpx;
background-color: #fff;
font-size: 24rpx;
color: #fff;
border-radius: 8rpx;
z-index: 101;
box-shadow: 0rpx 3rpx 20rpx rgba(0, 0, 0, 0.16);
overflow: hidden;
video{
vertical-align: bottom;
}
.text{
padding: 4rpx 0;
background-color: v-bind('Color');
}
.close{
position: absolute;
right: 0;
top: 0;
background-color: rgba(0, 0, 0, 0.16);
padding: 0 2px;
z-index: 10;
}
}
.move_img {
display: inline-block;
font-size: 24rpx;
color: #fff;
margin: 3px 10px 3px 0;
background-image: url('@/static/image/move_img.png');
background-repeat: no-repeat;
padding: 0px 3px 0px 12px;
height: 40rpx;
background-size: 100% 100%;
line-height: 40rpx;
font-weight: normal;
}
.caseBox{
padding: 40rpx;
box-sizing: border-box;
.tit{
font-size: 30rpx;
color: #000;
font-weight: 600;
padding: 40rpx;
text-align: center;
line-height: 50rpx;
}
.copycase{
display: flex;
align-items: center;
justify-content: center;
height: 80rpx;
width: 100%;
border-radius: 8rpx;
background: #F14939;
font-size: 26rpx;
color: #fff;
}
.title{
font-size: 30rpx;
color: #000;
font-weight: 600;
padding: 20rpx 0 40rpx;
text-align: center;
}
.num{
text-align: center;
font-size: 28rpx;
padding-bottom: 40rpx;
text{
color: #F14939;
font-weight: 600;
font-size: 36rpx;
}
}
}
.supplyBox{
margin-top: 20rpx;
border-radius: 8rpx;
padding: 32rpx 24rpx;
display: flex;
align-items: center;
background-color: #fff;
image{
width: 46px;
height: 46px;
margin-right: 24rpx;
border-radius: 6rpx;
}
.text{
display: flex;
flex-direction: column;
color: #333;
font-size: 30rpx;
width: calc(100% - 250rpx);
.num{
font-size: 26rpx;
margin-top: 6rpx;
}
text{
font-weight: bold;
}
}
.shouc{
padding: 10rpx;
width: 180rpx;
height: 56rpx;
border: 1px solid v-bind('Color');
color: v-bind('Color');
font-size: 26rpx;
border-radius: 56rpx;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
}
}
.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;
}
}
}
</style>
<style scoped>
.goodBox.shux ::v-deep .up-sticky-wrap--fixed{
width: calc(100% - 200rpx);
left: 200rpx;
}
</style>