Files
xdd-uniapp-new/pages/shop/GoodsCon/index.vue
T

1938 lines
63 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view :class="productConClass">
<hx-navbar :back="true" :fixed="true" color="#fff" :statusBar="true" transparent="hidden" barPlaceholder="hidden">
</hx-navbar>
<view v-if="storeInfo.id">
<!-- 原模块 -->
<product-con-swiper :img-urls="storeInfo.sliderImageArr"
v-if="source!='pre' && source!='day'"></product-con-swiper>
<!-- v4 预售轮播图 -->
<product-con-swiper :img-urls="preInfo.sliderImageArr" v-if="source==='pre'"></product-con-swiper>
<!-- v4 每日特价轮播图 -->
<product-con-swiper :img-urls="dayInfo.sliderImageArr" v-if="source==='day'"></product-con-swiper>
<view class="wrapper">
<!-- 原模块 -->
<view class="change-section bg-white" v-if="source==='' || source==='famous' ">
<view class="introduce bold">{{ storeInfo.storeName }}</view>
<rich-text class="subInfo" :nodes="storeInfo.storeInfo" v-if="storeInfo.storeInfo"/>
<view class="share acea-row row-between row-middle" style="flex-wrap: nowrap;">
<view class="money font-color-lightred acea-row ai-end">
<text class="num">{{ attr.productSelect.price }}</text>
<text style="color: #999999;font-size: 24rpx;"></text>
<text style="color: #999999;font-size: 24rpx;text-decoration: line-through;">
{{ attr.productSelect.otPrice }}
</text>
<!-- <block v-if="Object.values(productValue).length>1">-->
<!-- <text class="num">{{ priceRangeStr(productValue) }}</text>-->
<!-- <text style="color: #999999;font-size: 24rpx;"></text>-->
<!-- <text-->
<!-- style="color: #999999;font-size: 24rpx;text-decoration: line-through;">-->
<!-- {{ minMaxOtPrice(productValue).min }}-->
<!-- </text>-->
<!-- <text style="color: #999999;font-size: 24rpx;">-</text>-->
<!-- <text style="color: #999999;font-size: 24rpx;"></text>-->
<!-- <text-->
<!-- style="color: #999999;font-size: 24rpx;text-decoration: line-through;">-->
<!-- {{ minMaxOtPrice(productValue).max }}-->
<!-- </text>-->
<!-- </block>-->
<!-- <block v-else>-->
<!-- <text class="num"-->
<!-- v-if="storeInfo.vipPrice && storeInfo.vipPrice > 0">{{ force2Decimal(storeInfo.vipPrice) }}-->
<!-- </text>-->
<!-- <text v-else class="num">{{ force2Decimal(storeInfo.price) }}</text>-->
<!-- <text style="text-decoration: line-through;color: #999999;font-size: 24rpx;"-->
<!-- v-if="storeInfo.otPrice && storeInfo.otPrice>0">{{ force2Decimal(storeInfo.otPrice) }}-->
<!-- </text>-->
<!-- </block>-->
<text v-if="storeInfo.vipPrice && storeInfo.vipPrice > 0" class="vip-price-tag">已享受会员价格</text>
</view>
<view style="flex-shrink:0;" class="acea-row row-middle" @click="listenerActionSheet">
<image :src="webUrl+'/20210806121714655368.png'" mode="" style="width: 36rpx;height: 36rpx;"></image>
</view>
</view>
<!-- 文玩 -->
<!-- <view class="wenwan-info flex jc-between ai-center" v-if="isWenwan===1">-->
<!-- <text>产地:{{ storeInfo.origin }}</text>-->
<!-- <text>单位:{{ storeInfo.unitName }}</text>-->
<!-- <text>规格:{{ storeInfo.storeInfo }}</text>-->
<!-- </view>-->
</view>
<!-- v4 特产 -->
<view class="spe-section change-section bg-white" v-if="source==='spe'">
<view class="spe-line-1 flex ai-center">
<img class="icon-spe" :src="webUrl+'/20220514112935428191.png'" mode="scaleToFill">
<view class="one-t">{{ storeInfo.storeName }}</view>
</view>
<view class="spe-line-2 flex jc-between ai-center">
<view class="flex ai-center">
<view class="money font-color-lightred acea-row row-bottom">
<text class="num bold">{{ attr.productSelect.price }}</text>
<text style="color: #999999;font-size: 24rpx;"></text>
<text style="color: #999999;font-size: 24rpx;text-decoration: line-through;">
{{ attr.productSelect.otPrice }}
</text>
</view>
<!-- <block v-if="Object.values(productValue).length>1">-->
<!-- <view class="money font-color-lightred acea-row row-middle">-->
<!-- <text class="num">{{ priceRangeStr(productValue) }}</text>-->
<!-- <text style="color: #999999;font-size: 24rpx;"></text>-->
<!-- <text-->
<!-- style="color: #999999;font-size: 24rpx;text-decoration: line-through;">-->
<!-- {{ minMaxOtPrice(productValue).min }}-->
<!-- </text>-->
<!-- <text style="color: #999999;font-size: 24rpx;">-</text>-->
<!-- <text style="color: #999999;font-size: 24rpx;"></text>-->
<!-- <text-->
<!-- style="color: #999999;font-size: 24rpx;text-decoration: line-through;">-->
<!-- {{ minMaxOtPrice(productValue).max }}-->
<!-- </text>-->
<!-- </view>-->
<!-- </block>-->
<!-- <block v-else>-->
<!-- <text class="price"-->
<!-- v-if="storeInfo.vipPrice && storeInfo.vipPrice > 0">{{ force2Decimal(storeInfo.vipPrice) }}-->
<!-- </text>-->
<!-- <text v-else class="price">{{ force2Decimal(storeInfo.price) }}</text>-->
<!-- <text style="text-decoration: line-through;color: #A5A5A5;font-size: 22rpx;"-->
<!-- v-if="storeInfo.otPrice && storeInfo.otPrice>0">{{ force2Decimal(storeInfo.otPrice) }}-->
<!-- </text>-->
<!-- </block>-->
<text v-if="storeInfo.origin" class="vip-price-tag">{{ storeInfo.origin }}</text>
</view>
<view style="flex-shrink:0;" class="acea-row row-middle" @click="listenerActionSheet">
<image :src="webUrl+'/20210806121714655368.png'" mode="" style="width: 36rpx;height: 36rpx;"></image>
</view>
</view>
</view>
<!-- v4 预售抬头 -->
<view class="pre-section change-section bg-white" v-if="source==='pre'">
<view class="pre-line-1 flex">
<view class="surplus flex">
<view class="red-grid tc">还剩</view>
<view class="white-grid flex">
<text style="color:#ED0F0F">{{ preInfo.surplus }}</text>
</view>
</view>
<view class="one-t">{{ preInfo.title }}</view>
</view>
<view class="pre-line-2 flex jc-between ai-center">
<view class="flex ai-center">
<image class="label-vip" :src="webUrl+'/20221118104357701129.png'" mode="scaleToFill"
v-if="storeInfo.vipPrice && storeInfo.vipPrice > 0"></image>
<text class="price">{{ force2Decimal(preInfo.price) }}</text>
<view class="date-box">
<text class="post-grid" v-if="preInfo.postTime">{{ preInfo.postTime.substring(0, 10) }}发货</text>
<text class="stop-grid" v-if="preInfo.stopTime">{{ preInfo.stopTime.substring(0, 10) }}结束</text>
</view>
</view>
<view style="flex-shrink:0;" class="acea-row row-middle" @click="listenerActionSheet">
<image :src="webUrl+'/20210806121714655368.png'" mode="" style="width: 36rpx;height: 36rpx;"></image>
</view>
</view>
</view>
<!-- v4 秒杀抬头 -->
<view class="kill-section change-section bg-white" v-if="source==='kill'">
<view class="kill-line-1 more-t">{{ killInfo.storeInfo.title }}</view>
<view class="kill-line-2 flex jc-between ai-center">
<view class="flex ai-center">
<text class="price">{{ force2Decimal(killInfo.storeInfo.price) }}</text>
<text style="text-decoration: line-through;color: #A5A5A5;font-size: 22rpx;margin-left:12rpx"
v-if="killInfo.storeInfo.otPrice && killInfo.storeInfo.otPrice>0">
{{ force2Decimal(killInfo.storeInfo.otPrice) }}
</text>
<view class="count-box flex ai-center">
<text class="gray">倒计时:</text>
<count-down :isDay="true" :isSecond="false" dayText="天" hourText="时" minuteText="分"
:datatime="killInfo.stop"></count-down>
</view>
</view>
<view style="flex-shrink:0;" class="acea-row row-middle" @click="listenerActionSheet">
<image :src="webUrl+'/20210806121714655368.png'" mode="" style="width: 36rpx;height: 36rpx;"></image>
</view>
</view>
</view>
<!-- v4 每日特价抬头 -->
<view class="day-section change-section bg-white" v-if="source==='day'">
<view class="day-line-1 flex ai-center">
<img class="icon-day" :src="webUrl+'/20220514103348573632.png'" mode="scaleToFill">
<view class="one-t">{{ dayInfo.title }}</view>
</view>
<view class="day-line-2 flex jc-between ai-center">
<view class="flex ai-center">
<text class="price">{{ force2Decimal(dayInfo.price) }}</text>
<text style="text-decoration: line-through;color: #A5A5A5;font-size: 22rpx;"
v-if="dayInfo.productPrice && dayInfo.productPrice>0">{{ force2Decimal(dayInfo.productPrice) }}
</text>
<!-- 原价 -->
<view class="count-box flex ai-center">
<text class="gray">倒计时:</text>
<count-down :isDay="true" :isSecond="false" dayText="天" hourText="时" minuteText="分"
:datatime="dayInfo.stop"></count-down>
</view>
</view>
<view style="flex-shrink:0;" class="acea-row row-middle" @click="listenerActionSheet">
<image :src="webUrl+'/20210806121714655368.png'" mode="" style="width: 36rpx;height: 36rpx;"></image>
</view>
</view>
<view style="border-bottom: 1px solid #F0F0F0;height: 1px;margin: 10rpx 32rpx;"></view>
<view class="label acea-row row-middle row-around" style="color: #666666;flex-wrap: nowrap;">
<text>库存:{{ dayInfo.stock }}{{ dayInfo.unitName }}</text>
<text v-if="tempName">{{ tempName }}</text>
<text>销量:{{ dayInfo.sales }}{{ dayInfo.unitName }}</text>
</view>
</view>
<!-- v9 优惠券开始 -->
<u-popup :show="show" :round="10" mode="bottom" closeOnClickOverlay @close="changeCoupons()">
<CouponsPopup :two-list="couponList" @change="changeCoupons"/>
</u-popup>
<!-- v9 优惠券结束 -->
<!-- v6服务项目开始 -->
<view class="service-section goods-section" v-if="storeInfo && storeInfo.isTickets!=1">
<view class="cell flex jc-between ai-center" @click="changeCoupons()" v-if="couponList['usable'].length>0">
<view>
<template v-for="(item, index) in couponList.usable">
<text
v-if="index < 2"
:key="index"
class="coupon-label tc"
>
{{ item.couponTitle }}
</text>
</template>
</view>
<view class="value">优惠详情
<uni-icons type="right" size="13" color="#707070"></uni-icons>
</view>
</view>
<view class="cell flex jc-between ai-center" @click="selecAttrTap">
<view class="flex ai-center">
<view class="after-title">规格</view>
<view class="title bold">{{ attrValue }}</view>
</view>
<view class="value">库存{{ storeInfo.stock }}
<uni-icons type="right" size="13" color="#707070"></uni-icons>
</view>
</view>
<view class="cell flex jc-between ai-center">
<view class="flex">
<view class="after-title">送至</view>
<view class="title bold" v-if="postAddress">{{ postAddress }}
<view class="sub-title flex ai-end">
<image class="icon-time" :src="webUrl+'/20230106150523489905.png'" mode="scaleToFill"/>
<view class="text">
{{ storeInfo.isFastPost == 1 ? "预计48小时内发货" : "预计发货时间:" + storeInfo.postTime }}
</view>
</view>
</view>
<view class="title bold" @click="getAddress" v-else>无法获取定位信息点击重新授权定位</view>
</view>
</view>
<view class="cell flex jc-between ai-center">
<view class="flex ai-center">
<view class="after-title">快递</view>
<view class="title bold">{{ storeInfo.postage === 0 ? "免运费" : `¥${storeInfo.postage}` }}</view>
</view>
<view class="value red">销量{{ storeInfo.sales }}</view>
</view>
<view class="cell flex jc-between ai-center" v-if="storeInfo.guarantee">
<view class="flex ai-center">
<view class="after-title flex-0">保障</view>
<view class="title bold">{{ storeInfo.guarantee }}</view>
</view>
</view>
</view>
<!-- v6服务项目结束 -->
<!-- 门店信息开始 -->
<!-- <view class="shop-info" v-if="systemStore">-->
<!-- <view class="title flex jc-between ai-center">-->
<!-- <view class="flex ai-center">-->
<!-- <image class="icon-shop" :src="webUrl+'/20210806122617026592.png'"/>-->
<!-- <text class="tip">门店信息</text>-->
<!-- </view>-->
<!-- <text class="font-color-lightred" @click="goStore">进入店铺</text>-->
<!-- </view>-->
<!-- <view class="flex" @click="showChang(systemStore)">-->
<!-- <image class="cover flex-0" :src="systemStore.image"/>-->
<!-- <view class="flex flex-col jc-between" style="width: 100%;">-->
<!-- <view class="flex jc-between ai-center">-->
<!-- <text class="name">{{ systemStore.name }}</text>-->
<!-- <text class="distance" v-if="systemStore.distance != null">距离{{ systemStore.distance }}千米</text>-->
<!-- </view>-->
<!-- <view class="flex jc-between ai-center">-->
<!-- <view class="address one-t">{{ systemStore.address }}</view>-->
<!-- <image class="icon-pos flex-0" :src="webUrl+'/20220903142929759087.png'"/>-->
<!-- </view>-->
<!-- </view>-->
<!-- </view>-->
<!-- </view>-->
<view class="store-section goods-section" v-if="systemStore">
<view class="flex jc-between ai-center">
<view class="title bold flex ai-center">
<image class="logo" :src="systemStore.image" mode="scaleToFill"/>
{{ systemStore.name }}
</view>
<view
class="flex ai-center store-btn"
@click="goStore"
>
进店逛逛
</view>
</view>
<view class="product-list flex" v-if="merBestProducts.length>0">
<view class="item flex flex-col jc-between" v-for="(item,index) in merBestProducts" :key="index"
@click="goodsDetail(item)">
<view>
<view class="cover-box">
<image class="tag" :src="webUrl+'/20230224104110531590.png'" mode="scaleToFill" v-if="index===0"/>
<image class="tag" :src="webUrl+'/20230224104120134853.png'" mode="scaleToFill" v-if="index===1"/>
<image class="tag" :src="webUrl+'/20230224104130457881.png'" mode="scaleToFill" v-if="index===2"/>
<image class="cover" :src="item.image" mode="scaleToFill"/>
</view>
<view class="more-t bold">{{ item.storeName }}</view>
</view>
<view class="price bold">{{ item.price }}</view>
</view>
</view>
</view>
<!-- 门店信息结束 -->
<!-- v6产品参数开始 -->
<view class="param-section goods-section"
v-if="Object.entries(storeInfo.exPropertiesData).length>0 && storeInfo.isTickets!==1">
<view class="bold">产品参数</view>
<view class="table">
<view class="row flex ai-center" v-for="(item,index) in storeInfo.exPropertiesData.slice(0,exSliceEnd)"
:key="index">
<view class="title tc">{{ item.key }}</view>
<view class="value tc bold">{{ item.value }}</view>
</view>
<view class="row value tc" style="color:#666" @click="changeExEnd"
v-if="storeInfo.exPropertiesData.length>3">
<uni-icons :type="exSliceEnd===3?'bottom':'top'" size="13" color="#707070"></uni-icons>
点击{{ exSliceEnd === 3 ? '展开查看' : '折叠' }}更多参数
</view>
</view>
</view>
<!-- v6产品参数结束 -->
<!-- 用户评价开始 -->
<view class="userEvaluation" v-if="replyCount">
<view class="title acea-row row-between-wrapper">
<view>用户评价({{ replyCount }})</view>
<text @click="goEvaluateList(id)" class="praise">
<text class="font-color-red">{{ replyChance }}%</text>
好评率
<text class="iconfont icon-jiantou"></text>
</text>
</view>
<user-evaluation :reply="reply"></user-evaluation>
</view>
<!-- 用户评价结束 -->
<!-- 商品信息开始 -->
<!-- <view class="product-info acea-row row-column" style="flex-wrap: nowrap;">
<view class="product-info-item acea-row row-between" style="border-bottom: none;">
<view class="product-item-title" style="font-size: 32rpx;color: #080F1A;font-weight: bold;">商品信息</view>
<view class="product-item-value" @click="toggleProductInfo">
<uni-icons :type="isProductInfoExpand?'arrowdown':'arrowup'"></uni-icons>
</view>
</view>
<block v-if="isProductInfoExpand">
<view class="product-info-item acea-row row-between">
<view class="product-item-title">销量</view>
<view class="product-item-value">{{storeInfo.sales}}{{storeInfo.unitName||''}}</view>
</view>
<view class="product-info-item acea-row row-between">
<view class="product-item-title">库存</view>
<view class="product-item-value">{{storeInfo.stock||0}}{{storeInfo.unitName||''}}</view>
</view>
<view v-if="systemStore" class="product-info-item acea-row row-between">
<view class="product-item-title">店铺</view>
<view class="product-item-value acea-row row-middle" style="flex-wrap: nowrap;">
<image :src="systemStore.image" mode="" style="width: 40rpx;height: 40rpx;border-radius: 50%;flex-shrink: 0;"></image>
{{systemStore.name||''}}
</view>
</view>
<view v-if="systemStore" class="product-info-item acea-row row-between">
<view class="product-item-title">地址</view>
<view class="product-item-value">{{systemStore.address||''}}</view>
</view>
<view class="product-info-item acea-row row-between">
<view class="product-item-title">距离</view>
<view class="product-item-value">{{systemStore.distance}}km</view>
</view>
</block>
</view> -->
<!-- 商品信息结束 -->
<!-- 商品详情开始 -->
<view class="product-intro" style="margin-top: 24rpx">
<!-- 原模块 -->
<!-- <view class="conter" v-html="storeInfo.description" ></view>-->
<rich-text :nodes="storeInfo.description" v-if="source!='pre' && source!='day'"/>
<!-- v4 预售详情 -->
<rich-text :nodes="preInfo.description" v-if="source==='pre'"/>
<!-- v4 每日特价详情 -->
<rich-text :nodes="dayInfo.description" v-if="source==='day'"/>
</view>
<!-- 商品详情结束 -->
<!-- 购买须知开始 -->
<view class="acea-row row-column bg-white" style="padding: 20rpx;border-width: 2px;border-color: #939390;">
<view class="conter">
<rich-text :nodes="buyNotice" />
</view>
</view>
<!-- 购买须知结束 -->
<!-- 占位 -->
<view style="height:100rpx;"></view>
<view class="footer acea-row row-between-wrapper">
<view style="position: relative;" class="item">
<view class="iconfont icon-kefu"></view>
<view style="text-align: center;">
客服
</view>
<button class="cus-btn" @click="goRoom"></button>
</view>
<view @click="goShoppingCart()" v-if="animated" class="item animated bounceIn">
<view class="iconfont icon-gouwuche1">
<text class="num bg-color-lightred" v-if="CartCount > 0">{{ CartCount }}</text>
</view>
<text style="text-align: center;">购物车</text>
</view>
<view @click="goShoppingCart()" class="item animated" v-if="!animated">
<view class="iconfont icon-gouwuche1">
<text class="num bg-color-lightred" v-if="CartCount > 0">{{ CartCount }}</text>
</view>
<text style="text-align: center;">购物车</text>
</view>
<view class="item" @click="doneFavorite">
<!-- <view class="iconfont icon-shouye-xianxing"></view>-->
<image style="width: 40rpx;height: 40rpx" :src="webUrl+'/20240113230535491918.png'" mode="scaleToFill" v-if="isFavorite"/>
<image style="width: 40rpx;height: 40rpx" :src="webUrl+'/20240122001533781400.png'" mode="scaleToFill" v-else/>
<view style="text-align: center;">收藏</view>
</view>
<view
class="bnt acea-row row-middle row-right"
style="background: transparent !important;border-radius: 0 !important;"
>
<view
class="btn-car"
:class="{
'btn-car-disabled': attr.productSelect.stock === 0
}"
@click="joinCart"
>
加入购物车
</view>
<view
class="btn-buy"
:class="{
'btn-buy-disabled': attr.productSelect.stock === 0
}"
@click="tapBuy"
>
立即购买
</view>
</view>
</view>
<ProductWindow
v-on:changeFun="changeFun"
:attr="attr"
:product-value-str="JSON.stringify(productValue)"
:cartNum="cart_num"
/>
<StorePoster v-on:setPosterImageStatus="setPosterImageStatus" :posterImageStatus="posterImageStatus"
:posterData="posterData" :goodId="id"></StorePoster>
<ShareInfo v-on:setShareInfoStatus="setShareInfoStatus" :shareInfoStatus="shareInfoStatus"></ShareInfo>
<view class="generate-posters acea-row row-middle on" v-if="posters">
<view class="item" @click="setPosterImageStatus">
<view class="iconfont icon-haibao"></view>
<view>生成海报</view>
</view>
</view>
<view class="generate-posters acea-row row-middle" v-if="!posters">
<view class="item" @click="setPosterImageStatus">
<view class="iconfont icon-haibao"></view>
<view>生成海报</view>
</view>
</view>
<view class="mask" @touchmove.prevent @click="listenerActionClose" v-show="posters"></view>
<view class="posterCanvasWarp">
<canvas class="posterCanvas" canvas-id="myCanvas"></canvas>
</view>
</view>
</view>
</view>
</template>
<script>
import ProductConSwiper from "@/components/ProductConSwiper";
import UserEvaluation from "@/components/UserEvaluation";
import ProductWindow from "@/components/ProductWindow";
import StorePoster from "@/components/StorePoster";
import ShareInfo from "@/components/ShareInfo";
import CountDown from "@/components/CountDown";
import {getCartCount, getProductCode, getProductDetail, postCartAdd} from "@/api/store";
import {userBindParent} from "@/api/user";
import {handleQrCode, isWeixin} from "@/utils";
import {getHomeData} from "@/api/public";
import {getDailyGoods, getPreSale, getYxStoreSeckill} from "@/api/goods";
import {mapGetters} from "vuex";
import {diffDay, formatDateTime} from "@/utils/index";
import {getCurAddress, getLocation, getUrlParam} from "@/utils/common.js";
import cookie from "@/utils/store/cookie";
import {famousGoodsShareImage, secKillGoodsShareImage} from "@/api/share";
import CouponsPopup from "@/components/CouponsPopup.vue"
import {addProduct, checkProduct, removeProduct} from "@/api/favorite";
export default {
name: "GoodsCon",
components: {
CountDown,
ProductConSwiper,
UserEvaluation,
ProductWindow,
StorePoster,
ShareInfo,
CouponsPopup
},
data: function () {
return {
isProductInfoExpand: true, //商品信息是否展开
shareInfoStatus: false,
weixinStatus: false,
mapShow: false,
mapKey: "",
posterData: {
image: "",
title: "",
price: "",
code: ""
},
posterImageStatus: false,
animated: false,
coupon: {
coupon: false,
list: []
},
attr: {
cartAttr: false,
productAttr: [],
productSelect: {}
},
isOpen: false, //是否打开属性组件
productValue: {},
id: null,
partnerId: null,
activityId: 0, // v4 add
source: "", // v4 add
preInfo: {},
killInfo: {},
dayInfo: {},
storeInfo: {},
couponList: {},
attrTxt: "请选择",
attrValue: "",
cart_num: 1, //购买数量
replyCount: "",
replyChance: "",
reply: [],
priceName: 0,
CartCount: 0,
posters: false,
banner: [{}, {}],
swiperRecommend: {
pagination: {
el: ".swiper-pagination",
clickable: true
},
autoplay: false,
loop: false,
speed: 1000,
observer: true,
observeParents: true
},
goodList: [],
systemStore: {},
qqmapsdk: null,
productConClass: "product-con",
tempName: "",
merBestProducts: [],
buyNotice: null,
isWenwan: 0,
postAddress: null,
exSliceEnd: 3,
webUrl: this.$VUE_APP_RESOURCES_URL,
// v9-2
show: false,
uniqueId: null,
isFavorite: false
};
},
computed: mapGetters(["isLogin", "location", "userInfo"]),
onShareAppMessage() {
return new Promise(async (resolve, reject) => {
let result;
let params = `?id=${this.id}&partnerId=${this.userInfo.uid}`;
if (this.source === 'famous') {
result = await famousGoodsShareImage(this.id);
}
if (this.source === 'kill') {
result = await secKillGoodsShareImage(this.activityId);
params += `&activityId=${this.activityId}`
}
if (result?.status === 200) {
resolve({
title: this.storeInfo.storeName,
path: '/pages/shop/GoodsCon/index' + params,
imageUrl: result.data
})
} else {
resolve({
title: this.storeInfo.storeName,
path: '/pages/shop/GoodsCon/index' + params,
imageUrl: this.storeInfo.image
})
}
})
},
onLoad: function (options) {
// test data
console.log("getLaunchOptionsSync", uni.getLaunchOptionsSync());
console.log("getEnterOptionsSync", uni.getEnterOptionsSync());
uni.removeStorageSync('couponId')
let url = handleQrCode();
if (url && url.productId) {
this.id = url.productId;
} else if (options.id) {
this.id = options.id || null;
this.partnerId = options.partnerId || null;
this.activityId = this._route.query.activityId;
this.source = this._route.query.from || "";
} else {
let obj = uni.getEnterOptionsSync();
if (options.scene != null || obj.query.scene != null) {
let query = options ? decodeURIComponent(options.scene) : decodeURIComponent(obj.query.scene);
this.id = getUrlParam(query, "id") || null;
this.partnerId = getUrlParam(query, "partnerId") || null;
}
}
if (this.partnerId) cookie.set("spread", this.partnerId);
//已登录状态的扫码进入绑定一下上级
if (url != null && url.spread != null) {
let urlSpread = parseInt(url.spread);
if (!Number.isNaN(urlSpread)) {
//绑定上级
userBindParent({
spread: urlSpread
}).catch(err => {
}).finally(() => {
})
}
}
setTimeout(() => {
this.productCon();
this.fetchCompanyDatea();
switch (this.source) {
case "pre":
this.getPreInfo();
break;
case "kill":
this.getKillInfo();
break;
case "day":
this.getDayInfo();
break;
}
}, 500)
},
onShow() {
this.getMapData()
},
watch: {
posterImageStatus(status) {
if (status) {
this.productConClass = "noscroll product-con";
} else {
this.productConClass = "product-con";
}
},
attr: {
deep: true,
handler(newVal, oldVal) {
this.uniqueId = newVal.productSelect.unique || null
if (this.uniqueId) this.checkFavorite()
}
}
},
methods: {
goRoom() {
uni.navigateTo({
url: `/pkg_common/views/room?id=${this.storeInfo.merId}&name=${this.storeInfo.merName}`
})
},
goodsDetail: function (item) {
this.$yrouter.push({
path: '/pages/shop/GoodsCon/index',
query: {
id: item.id
}
})
},
async getMapData() {
let location = uni.getStorageSync("location");
if (location.length === 0) {
const map = await getLocation();
if (map.length > 1) {
const {latitude, longitude} = map[1];
let address = await getCurAddress(latitude, longitude);
address = address[1].data.result.ad_info;
location = address.province + address.city + address.district;
}
}
this.postAddress = location;
},
// 获取当前位置经纬度
handleLoacation(toast) {
let that = this;
uni.getLocation({
type: 'gcj02',
success: async (res) => {
// 获取到经纬度后根据实际业务做处理,下面业务逻辑仅供参考
const map = await getLocation();
if (map.length > 1) {
const {latitude, longitude} = map[1];
let address = await getCurAddress(latitude, longitude);
address = address[1].data.result.ad_info;
that.postAddress = address.province + address.city + address.district;
}
},
fail: err => {
// 判断是否获取到了定位
// this.isLocation = false
// 根据不同需求做了两种类型提示,需要根据实际业务修改
if (toast) {
// this.$u.toast是用的框架里封装的弹出消息
this.$u.toast('您已拒绝授权,相关功能会无法使用!')
return
}
//用户已授权,但是获取地理位置失败,提示用户去系统设置中打开定位
uni.showModal({
title: '提示',
content: '请在系统设置中打开定位服务,重新进入小程序!'
})
}
})
},
// 定位获取位置信息授权逻辑
getAddress() {
//wx.getSetting是获取用户授权的信息的,除了应用在位置信息授权还能应用在用户信息授权等等
uni.getSetting({
success: res => {
// true说明已经授权,如果还拿不到定位信息,说明用户的手机没开启定位功能
if (res.authSetting['scope.userLocation'] === true) {
// console.log('已经授权,非第一次')
//授权后默认加载,直接获取定位
this.handleLoacation(false)
}
// scope.userLocation === undefined代表用户未授权且第一次登陆
else if (res.authSetting['scope.userLocation'] === undefined) {
// 如果用户是第一次登陆且未授权的情况,会直接弹窗请求授权
// 使用 getlocation 获取用户 经纬度位置
// console.log('第一次登陆且未授权')
this.handleLoacation(true)
}
// 小程序检测到用户不是第一次进入该页面,且未授权
else if (res.authSetting['scope.userLocation'] !== undefined && res.authSetting['scope.userLocation'] !== true) {
// console.log('不是第一次进入该页面,且未授权')
uni.showModal({
title: '是否授权当前位置',
content: '需要获取您的地理位置,请确认授权,否则无法相关功能!',
success: res => {
//如果点击取消则显示授权失败
if (res.cancel) {
this.$u.toast('您已拒绝授权!')
}
//如果点击确定会打开授权页请求二次授权
else if (res.confirm) {
uni.openSetting({
success: dataAu => {
if (dataAu.authSetting['scope.userLocation'] === true) {
this.$u.toast('授权成功!')
//再次授权,调用getLocationt的API
this.handleLoacation(false)
} else {
// this.isLocation = false
this.$u.toast('授权失败!')
}
}
})
}
}
})
}
},
fail: err => {
// this.isLocation = false
uni.showModal({
title: '提示',
content: '未知错误,请重新打开小程序!'
})
}
})
},
changeExEnd() {
if (this.exSliceEnd === 3) {
this.exSliceEnd = this.storeInfo.exPropertiesData.length;
} else {
this.exSliceEnd = 3;
}
},
// v4 预售
getPreInfo() {
getPreSale(this.activityId).then(({
data
}) => {
var now = new Date().getTime();
var nowStr = formatDateTime(now, 'yyyy-MM-dd');
data.surplus = diffDay(nowStr, data.stopTime.substring(0, 10))
this.preInfo = data;
this.handleAttr(data);
}).catch(err => console.warn("err=", err))
},
// v4 秒杀
getKillInfo() {
getYxStoreSeckill(this.activityId).then(({
data
}) => {
let stopTime = data.storeInfo.stopTime;
let stopDate = new Date(stopTime.replace(/-/g, "/"));
data.stop = Math.floor(stopDate.getTime() / 1000);
this.killInfo = data
this.handleAttr(data);
}).catch(err => console.warn("err=", err))
},
// v4 每日特价
getDayInfo() {
getDailyGoods(this.activityId).then(({
data
}) => {
let stopTime = data.stopTime;
let stopDate = new Date(stopTime.replace(/-/g, "/"));
data.stop = Math.floor(stopDate.getTime() / 1000);
this.dayInfo = data
this.handleAttr(data);
}).catch(err => console.warn("err=", err))
},
// 关联商品规格
handleAttr(data) {
this.$set(this.attr, "productAttr", data.productAttr);
this.$set(this, "productValue", data.productValue);
this.DefaultSelect();
},
priceRangeStr: function (prices) {
var ret = '';
var maxPrice = 0;
var minPrice = Object.values(prices)[0].price;
Object.values(prices).forEach((item) => {
minPrice = Math.min(minPrice, item.price);
maxPrice = Math.max(maxPrice, item.price);
})
if (maxPrice >= 0 && minPrice >= 0) {
if (maxPrice > minPrice) {
ret = minPrice + '-' + maxPrice;
} else if (maxPrice == minPrice) {
ret = minPrice;
}
}
return ret;
},
minMaxOtPrice: function (prices) {
var maxPrice = Object.values(prices)[0].otPrice;
var minPrice = Object.values(prices)[0].otPrice;
Object.values(prices).forEach((item) => {
minPrice = Math.min(minPrice, item.otPrice);
maxPrice = Math.max(maxPrice, item.otPrice);
})
return {
min: minPrice,
max: maxPrice
}
},
fetchCompanyDatea: function () {
var that = this;
getHomeData().then(res => {
that.buyNotice = res.data.buyNotice.replace(
/\<img/gi,
'<img style="max-width:100%;height:auto;"'
);
});
},
force2Decimal(v) {
return this.$force2Decimal(v);
},
toggleProductInfo() {
this.isProductInfoExpand = !this.isProductInfoExpand;
},
goShoppingCart() {
this.$yrouter.switchTab("/pages/cart");
},
goCustomerList() {
this.$yrouter.push({
path: "/pages/user/CustomerList/index"
});
},
goStoreList() {
this.$yrouter.push({
path: "/pages/shop/StoreList/index"
});
},
goEvaluateList(id) {
this.$yrouter.push({
path: "/pages/shop/EvaluateList/index",
query: {
id
}
});
},
// 2022/9/28 add
goStore() {
this.$yrouter.push({
path: "/pagesInn/inn/innHome",
query: {
id: this.systemStore.id
}
});
},
showChang: function (data) {
this.$yrouter.push({
path: "/pages/map/index",
query: data
});
},
setShareInfoStatus: function () {
this.shareInfoStatus = !this.shareInfoStatus;
this.posters = false;
},
shareCode: function () {
var that = this;
getProductCode(that.id).then(res => {
that.posterData.code = res.data.code;
that.listenerActionSheet();
});
},
setPosterImageStatus: function () {
this.posterImageStatus = !this.posterImageStatus;
this.posters = false;
},
//产品详情接口;
productCon: function () {
let that = this;
let from = this.location;
if (this.$deviceType == "app") {
from.from = "app";
}
if (that.source === 'kill') {
from.seckillId = that.activityId
}
uni.showLoading({
title: "加载中",
mask: true
});
getProductDetail(that.id, from)
.then(res => {
// 会造成两个style属性,并且生效的是后一个
// res.data.storeInfo.description = res.data.storeInfo.description.replace(
// /\<img/gi,
// '<img style="display:block;max-width:100%;height:auto;"'
// );
that.$set(that, "storeInfo", res.data.storeInfo);
that.isWenwan = res.data.isWenwan;
// 给 attr 赋值,将请求回来的规格赋值给 attr
if (this.source === "" || this.source === 'famous') {
that.$set(that.attr, "productAttr", res.data.productAttr);
that.$set(that, "productValue", res.data.productValue);
}
that.attr.defaultSku = res.data.defaultSku
that.attr.defaultSkuIndex = res.data.defaultSkuIndex
res.data.couponList['unusable']?.map(item => item.status = 2)
that.$set(that, 'couponList', res.data.couponList)
that.$set(that, "replyCount", res.data.replyCount);
that.$set(that, "replyChance", res.data.replyChance);
that.reply = res.data.reply ? [res.data.reply] : [];
that.$set(that, "reply", that.reply);
that.$set(that, "priceName", res.data.priceName);
that.$set(that, "tempName", res.data.tempName);
that.$set(that, "merBestProducts", res.data.merBestProducts);
that.posterData.image = that.storeInfo.image;
if (that.storeInfo.storeName.length > 30) {
that.posterData.title =
that.storeInfo.storeName.substring(0, 30) + "...";
} else {
that.posterData.title = that.storeInfo.storeName;
}
that.posterData.price = that.storeInfo.price;
that.posterData.code = that.storeInfo.codeBase;
that.systemStore = res.data.systemStore;
let good_list = res.data.goodList || [];
let goodArray = [];
let count = Math.ceil(good_list.length / 6);
for (let i = 0; i < count; i++) {
var list = good_list.slice(i * 6, 6);
if (list.length)
goodArray.push({
list: list
});
}
that.mapKay = res.data.mapKay;
that.$set(that, "goodList", goodArray);
that.DefaultSelect();
that.getCartCount();
//动态配置share
that.$set(that, "share", {
title: that.storeInfo.storeName,
path: '/pages/shop/GoodsCon/index?id=' + that.id,
imageUrl: that.storeInfo.image,
desc: '',
content: ''
});
})
.catch(err => {
uni.showToast({
title: err.msg || err.response.data.msg || err.response.data.message,
icon: "none",
duration: 2000
});
})
.finally(() => {
uni.hideLoading();
});
},
//默认选中属性;
DefaultSelect: function () {
let productAttr = this.attr.productAttr;
let value = [];
for (let i = 0; i < productAttr.length; i++) {
this.$set(productAttr[i], "index", this.attr.defaultSkuIndex[i]);
value.push(productAttr[i].attrValueArr[1]);
}
//sort();排序函数:数字-英文-汉字;
// let productSelect = this.productValue[value.sort().join(",")];
const skuKey = this.attr.defaultSku?.join(',')
let productSelect = this.productValue[skuKey]
if (productSelect && productAttr.length) {
this.$set(
this.attr.productSelect,
"store_name",
this.storeInfo.storeName
);
this.$set(this.attr.productSelect, "image", productSelect.image);
this.$set(this.attr.productSelect, "price", productSelect.price);
this.$set(this.attr.productSelect, "otPrice", productSelect.otPrice);
this.$set(this.attr.productSelect, "stock", productSelect.stock);
this.$set(this.attr.productSelect, "unique", productSelect.unique);
this.$set(this.attr.productSelect, "cart_num", 1);
// this.$set(this, "attrValue", value.sort().join(","));
this.$set(this, "attrValue", skuKey);
this.$set(this, "attrTxt", "已选择");
} else if (!productSelect && productAttr.length) {
this.$set(
this.attr.productSelect,
"store_name",
this.storeInfo.storeName
);
this.$set(this.attr.productSelect, "image", this.storeInfo.image);
this.$set(this.attr.productSelect, "price", this.storeInfo.price);
this.$set(this.attr.productSelect, "otPrice", this.storeInfo.otPrice);
this.$set(this.attr.productSelect, "stock", 0);
this.$set(this.attr.productSelect, "unique", "");
this.$set(this.attr.productSelect, "cart_num", 0);
this.$set(this, "attrValue", "");
this.$set(this, "attrTxt", "请选择");
} else if (!productSelect && !productAttr.length) {
this.$set(
this.attr.productSelect,
"store_name",
this.storeInfo.storeName
);
this.$set(this.attr.productSelect, "image", this.storeInfo.image);
this.$set(this.attr.productSelect, "price", this.storeInfo.price);
this.$set(this.attr.productSelect, "otPrice", this.storeInfo.otPrice);
this.$set(this.attr.productSelect, "stock", this.storeInfo.stock);
this.$set(
this.attr.productSelect,
"unique",
this.storeInfo.unique || ""
);
this.$set(this.attr.productSelect, "cart_num", 1);
this.$set(this, "attrValue", "");
this.$set(this, "attrTxt", "请选择");
}
},
//购物车;
ChangeCartNum: function (changeValue) {
//changeValue:是否 加|减
//获取当前变动属性
let productSelect = this.productValue[this.attrValue];
//如果没有属性,赋值给商品默认库存
if (productSelect === undefined && !this.attr.productAttr.length) {
productSelect = this.attr.productSelect;
}
//无属性值即库存为0;不存在加减;
if (productSelect === undefined) return;
let stock = productSelect.stock || 0;
let num = this.attr.productSelect;
if (changeValue) {
num.cart_num++;
if (num.cart_num > stock) {
this.$set(this.attr.productSelect, "cart_num", stock);
this.$set(this, "cart_num", stock);
} else {
this.$set(this.attr.productSelect, "cart_num", num.cart_num);
this.$set(this, "cart_num", num.cart_num);
}
} else {
num.cart_num--;
if (num.cart_num < 1) {
this.$set(this.attr.productSelect, "cart_num", 1);
this.$set(this, "cart_num", 1);
} else {
this.$set(this.attr.productSelect, "cart_num", num.cart_num);
this.$set(this, "cart_num", num.cart_num);
}
}
},
//将父级向子集多次传送的函数合二为一;
changeFun: function (opt) {
if (typeof opt !== "object") opt = {};
let action = opt.action || "";
let value = opt.value === undefined ? "" : opt.value;
this[action] && this[action](value);
},
//打开属性插件;
selecAttrTap: function () {
this.attr.cartAttr = true;
this.isOpen = true;
},
changeattr: function (msg) {
// 修改了规格
this.attr.cartAttr = msg;
this.isOpen = false;
},
//选择属性;
ChangeAttr: function (res) {
// 修改了规格
let productSelect = this.productValue[res.value];
if (productSelect) {
this.attr.productAttr[res.indexw].index = res.indexn;
this.$set(this.attr.productSelect, "image", productSelect.image);
this.$set(this.attr.productSelect, "price", productSelect.price);
this.$set(this.attr.productSelect, "otPrice", productSelect.otPrice);
this.$set(this.attr.productSelect, "stock", productSelect.stock);
this.$set(this.attr.productSelect, "unique", productSelect.unique);
this.$set(this.attr.productSelect, "cart_num", 1);
this.$set(this, "attrValue", res.value);
this.$set(this, "attrTxt", "已选择");
} else {
this.$set(this.attr.productSelect, "image", this.storeInfo.image);
this.$set(this.attr.productSelect, "price", this.storeInfo.price);
this.$set(this.attr.productSelect, "otPrice", this.storeInfo.otPrice);
this.$set(this.attr.productSelect, "stock", 0);
this.$set(this.attr.productSelect, "unique", "");
this.$set(this.attr.productSelect, "cart_num", 0);
this.$set(this, "attrValue", "");
this.$set(this, "attrTxt", "请选择");
}
},
// 点击加入购物车按钮
joinCart: function () {
if (this.attr.productSelect.stock === 0) return;
//0=加入购物车
this.goCat(0);
},
//立即购买;
tapBuy: function () {
if (this.attr.productSelect.stock === 0) return;
// 1=直接购买
this.goCat(1);
},
// 加入购物车;
goCat: function (news) {
let that = this,
productSelect = that.productValue[this.attrValue];
//打开属性
if (that.attrValue) {
//默认选中了属性,但是没有打开过属性弹窗还是自动打开让用户查看默认选中的属性
that.attr.cartAttr = !that.isOpen ? true : false;
} else {
if (that.isOpen) that.attr.cartAttr = true;
else that.attr.cartAttr = !that.attr.cartAttr;
}
//只有关闭属性弹窗时进行加入购物车
if (that.attr.cartAttr === true && that.isOpen === false) {
return (that.isOpen = true);
}
//如果有属性,没有选择,提示用户选择
if (
(that.attr.productAttr.length &&
productSelect === undefined &&
that.isOpen === true) || productSelect.stock === 0
) {
uni.showToast({
title: "产品库存不足,请选择其他商品",
icon: "none",
duration: 5000
});
return;
}
let q = {
productId: that.id,
cartNum: that.attr.productSelect.cart_num,
new: news,
uniqueId: that.attr.productSelect !== undefined ?
that.attr.productSelect.unique : ""
};
// v4 新增活动ID
switch (this.source) {
case "pre":
q.preSaleId = Number(this.activityId)
break;
case "kill":
q.secKillId = Number(this.activityId)
break;
case "day":
q.dailyGoodsId = Number(this.activityId)
break;
}
postCartAdd(q)
.then(function (res) {
that.isOpen = false;
that.attr.cartAttr = false;
if (news) {
that.$yrouter.push({
path: "/pages/order/OrderSubmission/index",
query: {
id: res.data.cartId
}
});
} else {
uni.showToast({
title: "添加购物车成功",
icon: "success",
duration: 2000,
complete: () => {
that.getCartCount(true);
}
});
}
})
.catch(error => {
that.isOpen = false;
uni.showToast({
title: error.msg,
icon: "none",
duration: 5000
});
});
},
//获取购物车数量
getCartCount: function (isAnima) {
let that = this;
const isLogin = that.isLogin;
if (isLogin) {
getCartCount({
numType: 0
}).then(res => {
that.CartCount = res.data.count;
//加入购物车后重置属性
if (isAnima) {
that.animated = true;
setTimeout(function () {
that.animated = false;
}, 500);
}
});
}
},
listenerActionSheet: function () {
if (isWeixin() === true) {
this.weixinStatus = true;
}
this.posters = true;
},
listenerActionClose: function () {
this.posters = false;
},
// v9-2
changeCoupons() {
this.show = !this.show
},
async checkFavorite() {
const res = await checkProduct(this.id, this.uniqueId)
if (res.success) this.isFavorite = res.data.hasFavorite
},
async doneFavorite() {
if (this.isFavorite) {
const res = await removeProduct(this.id, this.uniqueId)
if (res.success) this.isFavorite = false
} else {
const res = await addProduct(this.id, this.uniqueId)
if (res.success) this.isFavorite = true
}
}
}
};
</script>
<style scoped lang="less">
@import "@/assets/css/goods.less";
// wenwan add
.bg-white {
background-color: white;
}
.wenwan-info {
margin: 0 32rpx;
padding: 16rpx 0 24rpx;
border-top: 1rpx solid #F0F0F0;
color: #666666;
font-size: 24rpx;
line-height: 36rpx;
}
.shop-info {
margin-top: 24rpx;
padding: 26rpx 32rpx 32rpx;
background-color: #fff;
font-size: 24rpx;
line-height: 34rpx;
.title {
margin-bottom: 20rpx;
padding-bottom: 16rpx;
border-bottom: 1rpx solid #F0F0F0;
}
.icon-shop {
width: 32rpx;
height: 32rpx;
margin-right: 10rpx;
}
.tip {
color: #666666;
}
.cover {
width: 80rpx;
height: 80rpx;
border-radius: 8rpx;
margin-right: 16rpx;
}
.name {
color: #333333;
font-weight: bold;
}
.distance {
color: #0DC5C5;
font-size: 20rpx;
line-height: 30rpx;
}
.address {
width: 520rpx;
color: #999999;
font-size: 20rpx;
line-height: 30rpx;
}
.icon-pos {
width: 24rpx;
height: 24rpx;
}
}
// v4 add
.spe-section {
.spe-line-1 {
padding: 20rpx 0;
font-size: 32rpx;
line-height: 48rpx;
color: #333333;
.icon-spe {
width: 66rpx;
height: 38rpx;
margin-right: 10rpx;
}
}
.spe-line-2 {
.price {
font-size: 32rpx;
line-height: 48rpx;
color: #FF564A;
}
.vip-price-tag {
margin-left: 30rpx;
}
}
}
.pre-section {
.pre-line-1 {
padding: 20rpx 0;
.surplus {
height: 40rpx;
line-height: 40rpx;
margin-right: 10rpx;
box-sizing: border-box;
border: 1rpx solid #FD685D;
font-size: 24rpx;
.red-grid {
width: 58rpx;
background: #FD685D;
color: #fff;
font-size: 22rpx;
}
.white-grid {
padding: 0 10rpx;
color: #333;
}
}
}
.pre-line-2 {
.label-vip {
width: 40rpx;
height: 24rpx;
margin-right: 6rpx;
}
.price {
font-size: 32rpx;
line-height: 48rpx;
color: #FF564A;
}
.date-box {
box-sizing: border-box;
margin-left: 20rpx;
padding-left: 14rpx;
border-left: 2rpx solid #DBDBDB;
font-size: 24rpx;
line-height: 1;
.post-grid {
color: #ED0F0F;
}
.stop-grid {
margin-left: 10rpx;
color: #999;
}
}
}
}
.kill-section {
.kill-line-1 {
padding: 20rpx 0;
font-size: 32rpx;
line-height: 48rpx;
color: #333333;
}
.kill-line-2 {
.label-vip {
width: 40rpx;
height: 24rpx;
margin-right: 6rpx;
}
.price {
font-size: 32rpx;
line-height: 48rpx;
color: #FF564A;
}
.count-box {
margin-left: 70rpx;
line-height: 38rpx;
color: #ED0F0F;
font-size: 26rpx;
.gray {
color: #333;
font-size: 22rpx;
}
}
}
}
.day-section {
.day-line-1 {
padding: 20rpx 0;
font-size: 32rpx;
line-height: 48rpx;
color: #333333;
.icon-day {
width: 96rpx;
height: 38rpx;
margin-right: 10rpx;
}
}
.day-line-2 {
.label-vip {
width: 40rpx;
height: 24rpx;
margin-right: 6rpx;
}
.price {
font-size: 32rpx;
line-height: 48rpx;
color: #FF564A;
}
.count-box {
margin-left: 70rpx;
line-height: 49rpx;
color: #FD685D;
font-size: 28rpx;
}
}
}
.geoPage {
position: fixed;
width: 100%;
height: 100%;
top: 0;
z-index: 10000;
}
.vline {
width: 0px !important;
height: 36rpx;
position: absolute;
border-left: 1px solid rgba(255, 255, 255, 0.6);
top: 20rpx;
left: 50%;
}
.product-con .footer .bnt {
position: relative;
background: linear-gradient(139deg, rgba(255, 149, 141, 1) 0%, rgba(255, 92, 138, 1) 100%);
border-radius: 50rpx;
.btn-car {
width: 200rpx;
height: 60rpx;
line-height: 60rpx;
box-sizing: border-box;
margin-right: 20rpx;
border: 2rpx solid #FF564A;
border-radius: 30rpx;
color: #FF564A;
}
.btn-car-disabled {
border: 2rpx solid #707070;
color: #707070;
}
.btn-buy {
width: 200rpx;
height: 60rpx;
line-height: 60rpx;
border-radius: 30rpx;
background: #FF564A;
color: #FFFFFF;
}
.btn-buy-disabled {
background: #9D9D9D;
}
}
.cus-btn {
width: 100%;
height: 100%;
position: absolute;
top: 0;
right: 0;
background-color: transparent !important;
}
.cus-btn:hover {
color: transparent !important;
background-color: transparent !important;
}
.cus-btn::after {
border: none !important;
background-color: transparent !important;
}
.pink-dot {
width: 24rpx;
height: 24rpx;
background: rgba(255, 86, 74, 0.4);
border-radius: 50%;
position: absolute;
z-index: 0;
bottom: 24rpx;
right: -12rpx;
}
.vip-price-tag {
font-size: 12*2rpx;
color: #0DC5C5;
border: 1px solid #0DC5C5;
border-radius: 2*2rpx;
padding: 0.02rem 0.08rem 0.02rem 0.08rem;
margin-left: 0.24rem;
}
.product-con .product-intro .conter {
background-color: #fff;
width: auto;
}
.product-con .wrapper {
position: relative;
background-color: #F6F6F6;
z-index: 1;
border-radius: 12rpx;
}
.product-con .store-info {
margin-top: 0.2 * 100rpx;
background-color: #fff;
}
.product-con .store-info .title {
padding: 0 0.3 * 100rpx;
font-size: 0.28 * 100rpx;
color: #282828;
height: 0.8 * 100rpx;
line-height: 0.8 * 100rpx;
border-bottom: 0.01 * 100rpx solid #f5f5f5;
}
.product-con .store-info .info {
padding: 0 0.3 * 100rpx;
height: 1.26 * 100rpx;
}
.product-con .store-info .info .picTxt {
width: 100%;
display: flex;
align-items: center;
}
.product-con .store-info .info .picTxt .pictrue {
width: 0.76 * 100rpx;
height: 0.76 * 100rpx;
margin-right: 0.2 * 100rpx;
}
.product-con .store-info .info .picTxt .pictrue image {
width: 100%;
height: 100%;
border-radius: 0.06 * 100rpx;
}
.product-con .store-info .info .picTxt .text {
flex: 1;
}
.product-con .store-info .info .picTxt .text .name {
font-size: 0.3 * 100rpx;
color: #282828;
}
.product-con .store-info .info .picTxt .text .address {
font-size: 0.24 * 100rpx;
color: #666;
margin-top: 0.03 * 100rpx;
}
.product-con .store-info .info .picTxt .text .address .iconfont {
color: #707070;
font-size: 0.18 * 100rpx;
margin-left: 0.1 * 100rpx;
}
.product-con .store-info .info .picTxt .addressBox {
display: flex;
flex-direction: column;
align-items: flex-end;
}
.product-con .store-info .info .picTxt .addressBox .iconfont {
font-size: 0.4 * 100rpx;
}
.product-con .store-info .info .picTxt .addressBox .addressTxt {
font-size: 0.24 * 100rpx;
color: #eb3729;
}
.product-con .store-info .praise {
font-size: 0.28 * 100rpx;
color: #808080;
}
.product-con .store-info .praise .iconfont {
font-size: 0.28 * 100rpx;
}
.product-con .superior {
background-color: #fff;
margin-top: 0.2 * 100rpx;
}
.product-con .superior .title {
height: 0.98 * 100rpx;
}
.product-con .superior .title image {
width: 0.3 * 100rpx;
height: 0.3 * 100rpx;
}
.product-con .superior .title .titleTxt {
margin: 0 0.2 * 100rpx;
font-size: 0.3 * 100rpx;
background-image: linear-gradient(to right, #f57a37 0%, #f21b07 100%);
background-image: -webkit-linear-gradient(to right, #f57a37 0%, #f21b07 100%);
background-image: -moz-linear-gradient(to right, #f57a37 0%, #f21b07 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.product-con .superior .slider-banner {
width: 6.9 * 100rpx;
margin: 0 auto;
padding-bottom: 0.2 * 100rpx;
}
.product-con .superior .slider-banner .list {
width: 100%;
padding-bottom: 0.2 * 100rpx;
}
.product-con .superior .slider-banner .list .item {
width: 2.15 * 100rpx;
margin: 0 0.22 * 100rpx 0.3 * 100rpx 0;
font-size: 0.26 * 100rpx;
}
.product-con .superior .slider-banner .list .item:nth-of-type(3n) {
margin-right: 0;
}
.product-con .superior .slider-banner .list .item .pictrue {
width: 100%;
height: 2.15 * 100rpx;
}
.product-con .superior .slider-banner .list .item .pictrue image {
width: 100%;
height: 100%;
border-radius: 0.06 * 100rpx;
}
.product-con .superior .slider-banner .list .item .name {
color: #282828;
margin-top: 0.12 * 100rpx;
}
.product-con .superior .slider-banner .swiper-pagination-bullet {
background-color: #999;
}
.product-con .superior .slider-banner .swiper-pagination-bullet-active {
background-color: #e93323;
}
.mask {
-webkit-filter: blur(2px);
-moz-filter: blur(2px);
-ms-filter: blur(2px);
filter: blur(2px);
}
.footer .icon-shoucang1 {
color: #eb3729;
}
.product-con .product-intro .conter view {
width: 100% !important;
}
.product-con .footer .item .iconfont.icon-gouwuche1 .num {
right: -15rpx !important;
}
.generate-posters {
width: 100%;
height: 1.7 * 100rpx;
background-color: #fff;
position: fixed;
left: 0;
bottom: 0;
z-index: 99;
transform: translate3d(0, 100%, 0);
-webkit-transform: translate3d(0, 100%, 0);
-ms-transform: translate3d(0, 100%, 0);
-moz-transform: translate3d(0, 100%, 0);
-o-transform: translate3d(0, 100%, 0);
transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
-webkit-transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
-moz-transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
-o-transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
}
.generate-posters.on {
transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-o-transform: translate3d(0, 0, 0);
}
.generate-posters .item {
flex: 50%;
-webkit-flex: 50%;
-ms-flex: 50%;
text-align: center;
}
.generate-posters .item .iconfont {
font-size: 0.8 * 100rpx;
color: #5eae72;
}
.generate-posters .item .iconfont.icon-haibao {
color: #5391f1;
}
.noscroll {
height: 100%;
overflow: hidden;
}
.goods-detail-title {
margin-left: 32rpx;
font-size: 32rpx;
color: #080F1A;
font-weight: bold;
}
.product-info {
margin: 32rpx;
padding-top: 40rpx;
padding-bottom: 40rpx;
background-color: #fff;
border-radius: 12rpx;
}
.product-info-item {
padding-top: 20rpx;
padding-bottom: 20rpx;
border-bottom: 1px solid #EBECF0;
flex-wrap: nowrap;
}
.product-item-title {
color: #8B8F99;
font-size: 28rpx;
margin-left: 40rpx;
flex-shrink: 0;
margin-right: 40rpx;
}
.product-item-value {
color: #080F1A;
font-size: 28rpx;
margin-right: 40rpx;
}
</style>