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

2040 lines
64 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 !== 'pre' && source !== 'day' && source !== 'kill' && source !== 'spe'">
<view>
<view class="share acea-row row-between row-middle" style="flex-wrap: nowrap;margin-top: 0;">
<view class="money font-color-lightred acea-row v12-align-center">
<view>
<text class="v12-font-22 v12-red-text"></text>
<text class=" v12-primary-text v12-font-44 v12-red-text">{{ attr.productSelect.price }}</text>
<text class="v12-ml-2 v12-font-weight-300 v12-font-22" style="color: #BBBBBB; text-decoration: line-through;"></text>
<text class="v12-mr-2 v12-font-weight-300 v12-font-22" style="color: #BBBBBB; text-decoration: line-through;">{{ attr.productSelect.otPrice }}</text>
<text v-if="storeInfo.vipPrice && storeInfo.vipPrice > 0" class="v12-white-text v12-red v12-font-22 v12-radius-40 v12-px-1 v12-font-weight-400">会员价</text>
</view>
</view>
<view style="flex-shrink:0;" class="acea-row row-middle share-btn" @click="listenerActionSheet">
<image :src="webUrl+'/20210806121714655368.png'" mode="" style="width: 36rpx;height: 36rpx;"></image>
</view>
</view>
<view class="v12-mt-1 v12-mb-3">
<view
v-if="couponListLimit2ToShow.length > 0"
class="cell flex jc-between ai-center"
@click="changeCoupons()"
>
<view class="v12-justify-start">
<view
v-for="(item, index) in couponListLimit2ToShow"
:key="index"
class="v12-mr-2"
>
<view class="v12-align-center" v-if="index < 2">
<view class="v12-primary-text v12-primary-border v12-radius-6 v12-font-22 v12-px-1"></view>
<view class="v12-primary-text v12-primary-border v12-radius-6 v12-font-22 v12-px-1">{{ item.couponTitle }}</view>
</view>
</view>
</view>
<view class="value value2 v12-font-24 v12-primary-text">
更多优惠
<uni-icons type="right" size="14" color="#707070"></uni-icons>
</view>
</view>
</view>
</view>
<view class="introduce bold">{{ storeInfo.storeName }}</view>
<rich-text class="subInfo" :nodes="storeInfo.storeInfo" v-if="storeInfo.storeInfo"/>
</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>
<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" :showTab="false" :currentPrice="storeInfo.price" />
</u-popup>
<!-- v9 优惠券结束 -->
<!-- v6服务项目开始 -->
<view class="service-section goods-section" v-if="storeInfo && storeInfo.isTickets!=1">
<!-- <view
v-if="couponListLimit2ToShow.length > 0"
class="cell flex jc-between ai-center"
@click="changeCoupons()"
>
<view
v-for="(item, index) in couponListLimit2ToShow"
:key="index"
class="coupon-label tc"
>
{{ item.couponTitle }}
</view>
<view class="value value2">
优惠详情
<uni-icons type="right" size="13" color="#707070"></uni-icons>
</view>
</view> -->
<view class="cell flex jc-between ai-center" @click="toQualifications">
<view class="flex ai-center">
<view class="after-title v12-dark-text v12-font-28 v12-align-center">
<image class="logo" :src="webUrl+'/orderIcon/资质认证.png'" mode="" style="margin-right:0; width: 32rpx; height:32rpx"/>
<text class="v12-ml-1 v12-font-28">资质</text>
</view>
<view class="title v12-secondary-dark-text">{{ storeInfo.merName }}</view>
</view>
<view class="value v12-justify-end v12-align-center">
<!-- <text class=" v12-dark1-text v12-font-24">库存{{ attr.productSelect.stock }}</text> -->
<uni-icons type="right" size="16" 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 v12-dark-text v12-font-28 v12-align-center">
<image class="logo" :src="webUrl+'/orderIcon/items.png'" mode="" style="margin-right:0; width: 32rpx; height:32rpx"/>
<text class="v12-ml-1 v12-font-28">选择</text>
</view>
<view class="title attr-bg v12-primary-text one-t">{{ attrValue }}</view>
</view>
<view class="value v12-justify-end v12-align-center">
<text class=" v12-dark1-text v12-font-24">库存{{ attr.productSelect.stock }}</text>
<uni-icons type="right" size="16" color="#707070"></uni-icons>
</view>
</view>
<view class="cell flex jc-between ai-center">
<view class="flex v12-align-start">
<view class="after-title v12-dark-text v12-font-28 v12-align-center">
<image class="logo" :src="webUrl+'/orderIcon/car.png'" mode="" style="margin-right:0; width: 32rpx; height:32rpx"/>
<text class="v12-ml-1 v12-font-28">送至</text>
</view>
<view class="title " v-if="postAddress">
<view class="address-wrap">
<image class="logo" :src="webUrl+'/orderIcon/地址.png'" mode="" style="margin-right:0; width: 32rpx; height:32rpx"/>
<text class="v12-font-28 v12-secondary-dark-text">{{ postAddress }}</text>
</view>
<view class="sub-title flex ai-end" style="margin-top: 0;" >
<view class="v12-font-20 v12-dark1-text address-wrap">
<image class="logo" :src="webUrl+'/orderIcon/地址.png'" mode="" style="margin-right:0; width: 32rpx; height:32rpx; opacity: 0;"/>
<text v-if="storeInfo.isFastPost == 1">预计48小时内发货</text>
<text v-if="storeInfo.isFastPost == 2">预计72小时内发货</text>
<text v-if="storeInfo.isFastPost == 0">{{ "预计发货时间:" + storeInfo.postTime }}</text>
</view>
</view>
</view>
<view class="title v12-font-28 v12-secondary-dark-text" @click="getAddress" v-else>无法获取定位信息点击重新授权定位</view>
</view>
</view>
<view class="cell flex jc-between ai-center">
<view class="flex ai-center">
<view class="after-title v12-dark-text v12-font-28 v12-align-center">
<image class="logo" :src="webUrl+'/orderIcon/快递.png'" mode="" style="margin-right:0; width: 28rpx; height:28rpx"/>
<text class="v12-ml-1 v12-font-28">快递</text>
</view>
<view class="title v12-secondary-dark-text v12-font-28">{{ storeInfo.postage === 0 ? "免运费" : `¥${storeInfo.postage}` }}</view>
</view>
<!-- <view class="value red">销量{{ storeInfo.sales }}</view> -->
</view>
<!-- v-if="storeInfo.guarantee" -->
<view class="cell flex jc-between ai-center" v-if="storeInfo.guarantee" @click="showService">
<view class="flex v12-align-start" >
<view class="after-title flex-0 v12-dark-text v12-font-28 v12-align-center">
<image class="logo" :src="webUrl+'/orderIcon/服务.png'" mode="" style="margin-right:0; width: 32rpx; height:32rpx"/>
<text class="v12-ml-1 v12-font-28">服务</text>
</view>
<!-- <view class="title v12-secondary-dark-text v12-font-28">{{ storeInfo.guarantee }}</view> -->
<rich-text class='title v12-secondary-dark-text v12-font-28' :nodes="storeInfo.guarantee" />
</view>
</view>
</view>
<!-- v6服务项目结束 -->
<view class="store-section goods-section" v-if="systemStore">
<view class="flex jc-between ai-center">
<view class="title bold flex ai-center">
<view>
<image class="logo" :src="systemStore.image" mode="" style="width: 72rpx; height:72rpx"/>
</view>
{{ systemStore.name }}
</view>
<view
class=" v12-btn v12-primary v12-white-text v12-primary-border v12-font-24"
style="height: 42rpx; line-height:42rpx"
@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="v12-justify-between">
<view class="price bold">{{ item.price }}</view>
<view class="">
<image class="logo" :src="webUrl+'/orderIcon/组 355.png'" mode="" style="margin-right:0; width: 28rpx; height:28rpx"/>
</view>
</view>
</view>
</view>
</view>
<!-- 门店信息结束 -->
<!-- 用户评价开始 -->
<!-- v-if="replyCount" -->
<view class="userEvaluation" v-if="replyCount" >
<view class="title acea-row row-between-wrapper">
<view>
<text class="v12-font-weight-500 v12-dark-text">商品评价</text>
<text class="v12-ml-2 v12-dark1-text">({{ replyCount }})</text>
</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="v12-justify-center">
<view style="width: 50%;">
<u-divider text="商品详情" lineColor="#666" textColor="#666" :hairline="false"></u-divider>
</view>
</view>
<!-- v6产品参数开始 -->
<view
class="param-section goods-section"
v-if="Object.entries(storeInfo.exPropertiesData).length>0 && storeInfo.isTickets!==1"
>
<view class="v12-font-24 v12-dark-text v12-font-weight-500">产品参数</view>
<view class="table">
<view
v-for="(item,index) in storeInfo.exPropertiesData.slice(0, exSliceEnd)"
:key="index"
class="row flex ai-center"
>
<view class="title tc">
<view class="title-cont v12-font-24 v12-text-center">
{{ item.key }}
</view>
</view>
<view class="value tc v12-font-weight-500">
<view class="value-cont v12-font-24 v12-text-center">
{{ item.value }}
</view>
</view>
</view>
<view
v-if="storeInfo.exPropertiesData.length > 3"
class="row btn tc v12-font-22"
style="color:#666"
@click="changeExEnd"
>
<uni-icons
:type="exSliceEnd === 3 ? 'bottom' : 'top'"
size="14"
color="#666666"
></uni-icons>
点击{{ exSliceEnd === 3 ? '展开查看' : '折叠' }}更多参数
</view>
</view>
</view>
<!-- v6产品参数结束 -->
<!-- 商品详情开始 -->
<view class="product-intro" style="margin-top: 24rpx">
<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 v12-primary" 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 v12-primary-text v12-primary-border"
:class="{
'btn-car-disabled': (attr.productSelect.stock === 0 && attr.cartAttr) || storeInfo.stock === 0
}"
@click="joinCart"
>
加入购物车
</view>
<view
class="btn-buy"
:class="{
'btn-buy-disabled': (attr.productSelect.stock === 0 && attr.cartAttr) || storeInfo.stock === 0
}"
@click="tapBuy"
>
立即购买
</view>
</view>
</view>
<ProductWindow
v-if="productValueArr.length > 0"
:attr="attr"
:product-value-arr="productValueArr"
:cartNum="cart_num"
@changeFun="changeFun"
/>
<ServiceWin ref="serviceWin" :info="storeInfo.guarantee" />
<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 ServiceWin from '@/components/ServiceWin'
import {
getCartCount,
getProductCode,
getProductDetail,
postCartAdd,
getProductSkuBySelected
} 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'
import { pageListenMixins } from '@/mixins/pageListenMixins'
export default {
name: 'GoodsCon',
components: {
CountDown,
ProductConSwiper,
UserEvaluation,
ProductWindow,
StorePoster,
ShareInfo,
CouponsPopup,
ServiceWin
},
mixins: [pageListenMixins],
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,
productValueArr: [],
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,
pageKeyId: '',
couponListLimit2ToShow: [],
qualifications: []
}
},
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(options) {
// test data
console.log("getLaunchOptionsSync", uni.getLaunchOptionsSync())
console.log("getEnterOptionsSync", uni.getEnterOptionsSync())
uni.removeStorageSync('couponId')
const from = options.from
const id = options.id
switch (from) {
// 特产
case 'techan':
this.pageKeyId = `product_from_goods_productId_${id}`
break
// 地标好物
case 'landmark':
this.pageKeyId = `product_from_landmarkGoods_productId_${id}`
break
// 节日
case 'gift':
this.pageKeyId = `product_from_appContentFestival_productId_${id}`
break
// 时令尝鲜
case 'season':
this.pageKeyId = `product_from_seasonalFood_productId_${id}`
break
// 秒杀
case 'kill':
this.pageKeyId = `seckillProduct_seckillId_${options.activityId}`
break
// 文玩
case 'wenwan':
this.pageKeyId = `product_from_wenwan_productId_${id}`
break
// 非遗文化
case 'ich':
this.pageKeyId = `product_from_ich_productId_${id}`
break
// 康养食材
case 'wellness':
this.pageKeyId = `product_from_wellnessFood_productId_${id}`
break
// 千县
case 'famous':
this.pageKeyId = `product_from_countyFamous_productId_${id}`
break
default:
this.pageKeyId = `product_from_common_productId_${id}`
break
}
const 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 {
const obj = uni.getEnterOptionsSync()
if (options.scene != null || obj.query.scene != null) {
const 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) {
const urlSpread = parseInt(url.spread);
if (!Number.isNaN(urlSpread)) {
//绑定上级
userBindParent({
spread: urlSpread
}).catch(err => {
}).finally(() => {
})
}
}
this.productCon()
this.fetchCompanyDatea()
switch (this.source) {
case "pre":
this.getPreInfo()
break
case "kill":
this.getKillInfo()
break
case "day":
this.getDayInfo()
break
}
},
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: {
showService() {
this.$refs.serviceWin.show = true
},
toQualifications() {
const merInfo = {
name: this.storeInfo.merName,
qualifications: this.qualifications
}
uni.navigateTo({
url: '/pages/shop/GoodsCon/qualifications?mer=' + JSON.stringify(merInfo)
})
},
goRoom() {
const params = {
goodsId: this.productId,
goodsName: this.attr.productSelect.store_name,
skuStr: this.attrValue,
price: this.attr.productSelect.price,
seckillId: this.activityId,
cover: this.attr.productSelect.image,
goodsData: '',
seckillData: ''
}
uni.navigateTo({
url: `/pkg_common/views/room?id=${this.storeInfo.merId}&name=${this.storeInfo.merName}&params=${JSON.stringify(params)}`
})
},
goodsDetail(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) {
const 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 }) => {
const now = new Date().getTime();
const 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 }) => {
const stopTime = data.storeInfo.stopTime
const 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 }) => {
const stopTime = data.stopTime
const 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.productValueArr = []
for (const key in data.productValue) {
this.productValueArr.push({
attrItemkey: key,
...data.productValue[key]
})
}
this.DefaultSelect()
},
fetchCompanyDatea() {
const 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)
},
goShoppingCart() {
this.$yrouter.switchTab('/pages/cart')
},
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(data) {
this.$yrouter.push({
path: '/pages/map/index',
query: data
})
},
setShareInfoStatus() {
this.shareInfoStatus = !this.shareInfoStatus
this.posters = false
},
shareCode() {
const that = this
getProductCode(that.id).then(res => {
that.posterData.code = res.data.code
that.listenerActionSheet()
})
},
setPosterImageStatus() {
this.posterImageStatus = !this.posterImageStatus
this.posters = false
},
// 产品详情接口
productCon() {
const from = this.location
if (this.$deviceType == 'app') {
from.from = 'app'
}
if (this.source === 'kill') {
from.seckillId = this.activityId
}
uni.showLoading({
title: '加载中',
mask: true
})
getProductDetail(this.id, from).then(res => {
const { data } = res
this.$set(this, 'storeInfo', data.storeInfo)
this.isWenwan = data.isWenwan
this.qualifications = data.qualifications || []
// 给 attr 赋值,将请求回来的规格赋值给 attr
if (this.source !== 'pre' && this.source !== 'day' && this.source !== 'kill' && this.source !== 'spe') {
this.$set(this.attr, 'productAttr', data.productAttr)
this.productValueArr = []
for (const key in data.productValue) {
this.productValueArr.push({
attrItemkey: key,
...data.productValue[key]
})
}
// 初始化认为所有的规格都是可以选的
this.attr.productAttr.map(item => {
item.attrValue.map(subItem => {
subItem.canUsed = true
})
})
}
this.attr.defaultSku = data.defaultSku
this.attr.defaultSkuIndex = data.defaultSkuIndex
// data.couponList['unusable']?.map(item => item.status = 2)
this.$set(this, 'couponList', data.couponList)
const usableList = data.couponList.usable
if (usableList.length > 0) {
const tempType = {}
const tempTypeArr = []
usableList.map(usableItem => {
if (!tempType[usableItem.type + '']) {
tempType[usableItem.type + ''] = 1
tempTypeArr.push(usableItem)
}
})
if (tempTypeArr.length >= 2) {
this.couponListLimit2ToShow = [tempTypeArr[0], tempTypeArr[1]]
} else {
this.couponListLimit2ToShow = [tempTypeArr[0]]
}
}
this.$set(this, 'replyCount', data.replyCount)
this.$set(this, 'replyChance', data.replyChance)
this.reply = data.reply ? [data.reply] : []
this.$set(this, 'reply', this.reply)
this.$set(this, 'priceName', data.priceName)
this.$set(this, 'tempName', data.tempName)
this.$set(this, 'merBestProducts', data.merBestProducts)
this.posterData.image = this.storeInfo.image
if (this.storeInfo.storeName.length > 30) {
this.posterData.title = this.storeInfo.storeName.substring(0, 30) + '...'
} else {
this.posterData.title = this.storeInfo.storeName
}
this.posterData.price = this.storeInfo.price
this.posterData.code = this.storeInfo.codeBase
this.systemStore = data.systemStore
const good_list = data.goodList || []
const goodArray = []
const count = Math.ceil(good_list.length / 6)
for (let i = 0; i < count; i++) {
const list = good_list.slice(i * 6, 6)
if (list.length) {
goodArray.push({
list: list
})
}
}
this.mapKay = data.mapKay
this.$set(this, 'goodList', goodArray)
this.DefaultSelect()
this.getCartCount()
// 动态配置share
this.$set(this, 'share', {
title: this.storeInfo.storeName,
path: '/pages/shop/GoodsCon/index?id=' + this.id,
imageUrl: this.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()
})
},
getAttrItemData(attr) {
let result = {}
this.productValueArr.map(item => {
if (item.attrItemkey === attr) {
result = item
}
})
return result
},
// 默认选中属性
DefaultSelect() {
const productAttr = this.attr.productAttr
for (let i = 0; i < productAttr.length; i++) {
this.$set(productAttr[i], "index", this.attr.defaultSkuIndex[i])
}
const skuKey = (this.attr.defaultSku || []).join(',')
if (!skuKey) {
return
}
const productSelect = this.getAttrItemData(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', '已选择')
this.getSkuActiveStatus(skuKey)
} 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(changeValue) {
// changeValue:是否 加|减
// 获取当前变动属性
const productSelect = this.getAttrItemData(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) {
if(stock < 1) {
this.$set(this.attr.productSelect, 'cart_num', 1)
this.$set(this, 'cart_num', 1)
} else {
this.$set(this.attr.productSelect, 'cart_num', stock)
this.$set(this, 'cart_num', stock)
}
} else {
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)
}
}
} 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(opt) {
if (typeof opt !== 'object') opt = {}
let action = opt.action || ''
let value = opt.value === undefined ? '' : opt.value
this.cart_num = 1
this[action] && this[action](value)
},
// 打开属性插件
selecAttrTap() {
this.attr.cartAttr = true
this.isOpen = true
},
changeattr(msg) {
// 修改了规格
this.attr.cartAttr = msg
this.isOpen = false
},
// 选择属性
ChangeAttr(res) {
const value = res.value
// 修改了规格
let productSelect = this.getAttrItemData(value)
if (productSelect) {
this.attr.productAttr[res.index].index = res.subIndex
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)
this.$set(this, 'attrTxt', '已选择')
this.getSkuActiveStatus(value)
} 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', '请选择')
}
},
// 获取规格组是否能点击(右上角是否有缺货标识)
getSkuActiveStatus(selectedSku) {
getProductSkuBySelected(this.id, { selectedSku }).then(res => {
const { success, data } = res
if (success) {
for (const key in data) {
if (data[key]) {
this.attr.productAttr.map(item => {
if (item.attrName === key) {
item.attrValue.map(subItem => {
data[key].map(dataItem => {
if (dataItem.sku === subItem.attr) {
subItem.canUsed = dataItem.canUsed
}
})
})
}
})
}
}
}
})
},
// 点击加入购物车按钮
joinCart() {
if ((this.attr.productSelect.stock === 0 && this.attr.cartAttr) || this.storeInfo.stock === 0) {
return
}
// 0=加入购物车
this.goCat(0)
},
// 立即购买
tapBuy() {
if ((this.attr.productSelect.stock === 0 && this.attr.cartAttr) || this.storeInfo.stock === 0) {
return
}
// 1=直接购买
this.goCat(1)
},
// 加入购物车
goCat(news) {
const that = this
const productSelect = this.getAttrItemData(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
}
const 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) {
const 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() {
if (isWeixin() === true) {
this.weixinStatus = true
}
this.posters = true
},
listenerActionClose() {
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;
}
.share-btn{
flex-shrink: 0;
padding: 10rpx;
border: 1px solid #ddd;
border-radius: 50%;
position: fixed;
background: #fff;
right: 20rpx;
bottom: 100px;
z-index: 1;
}
.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: #C52733;
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;
}
.attr-bg{
background: rgba(197,39,51,0.1);
padding: 0rpx 5px;
height: 42rpx;
line-height: 42rpx;
border-radius: 12rpx;
max-width: 360rpx;
}
.address-wrap{
display: flex;
align-items: flex-end;
}
</style>