|
@@ -0,0 +1,2075 @@
|
|
|
+<template>
|
|
|
+ <view class="app-container">
|
|
|
+ <view class="recommender-container" v-if="isGroupbuyGoods && !isHeadUser">
|
|
|
+ <view class="content">
|
|
|
+ <image :src="detail.groupPic"></image>
|
|
|
+ <view class="name ellipsis">{{ detail.groupUserName }}</view>
|
|
|
+ <view>向你推荐</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- <no-data v-if="!isLoaded" :showText="'加载中'"></no-data> -->
|
|
|
+ <no-data v-if="isLoaded && noData" :showText="'该商品已失效'"></no-data>
|
|
|
+ <block v-if="isLoaded && !noData">
|
|
|
+ <view class="swiper-container">
|
|
|
+ <swiper @change="changeBanner">
|
|
|
+ <swiper-item v-if="detail.vedio">
|
|
|
+ <video id="video1" :src="detail.vedio" @play="playVideo" @pause="pauseVideo" controls loop
|
|
|
+ :enable-progress-gesture="false" :muted="isFixedVideo"></video>
|
|
|
+ </swiper-item>
|
|
|
+ <block v-for="(item, index) in bannerList" :key="index" v-if="bannerList.length > 0">
|
|
|
+ <swiper-item>
|
|
|
+ <!-- <image :src="item.url" mode="aspectFill" @tap="previewImage(item.url)" ></image> -->
|
|
|
+ <view class="image" @tap="previewImage(item.url)">
|
|
|
+ <image :src="item.url" mode="aspectFill" class="img"></image>
|
|
|
+ <image :src="detail.logo" mode="aspectFill" class="water"
|
|
|
+ v-if="isShowWater && index == 0"></image>
|
|
|
+ </view>
|
|
|
+ </swiper-item>
|
|
|
+ </block>
|
|
|
+ </swiper>
|
|
|
+ <view class="nums" v-show="(detail.vedio && bannerCurrent != 0) || !detail.vedio">
|
|
|
+ {{ bannerCurrent + 1 }}/{{
|
|
|
+ bannerList.length + (detail.vedio ? 1 : 0)
|
|
|
+ }}
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="video-container" :class="isFixedVideo ? 'isFixed' : ''">
|
|
|
+ <view class="content">
|
|
|
+ <view class="close" @tap="closeFixedVideo">
|
|
|
+ <image src="@/static/icon/close.png"></image>
|
|
|
+ </view>
|
|
|
+ <video id="video2" :src="detail.vedio" @error="videoErrorCallback" controls loop
|
|
|
+ :enable-progress-gesture="false"></video>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="seckill-container" v-if="isSeckillGoods">
|
|
|
+ <view class="price">
|
|
|
+ <view class="price-1">¥{{ detail.goodsPrice | numToFixed }}</view>
|
|
|
+ <view class="price-2">¥{{ detail.orgGoodsPrice | numToFixed }}</view>
|
|
|
+ </view>
|
|
|
+ <view class="right">
|
|
|
+ <text>距结束还剩:</text>
|
|
|
+ <view class="time">
|
|
|
+ <text>{{ countdownTime[0] }}</text>时<text>{{ countdownTime[1] }}</text>分<text>{{ countdownTime[2] }}</text>秒
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="clock">
|
|
|
+ <image src="@/static/icon/clock.png"></image>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="main-container">
|
|
|
+ <view class="title">{{ detail.goodsName }}</view>
|
|
|
+ <view class="des">{{
|
|
|
+ detail.describeText ? detail.describeText : ''
|
|
|
+ }}</view>
|
|
|
+ <view class="stock">
|
|
|
+ <block v-if="!isSeckillGoods">
|
|
|
+ <view class="left">
|
|
|
+ <text>剩余{{ detail.stock }}件</text>
|
|
|
+ </view>
|
|
|
+ </block>
|
|
|
+ <block v-if="isSeckillGoods">
|
|
|
+ <view class="left">
|
|
|
+ <text>剩余{{ detail.secStockNum }}件</text>
|
|
|
+ <view class="progress-box">
|
|
|
+ <progress :percent="(detail.secStockNum / detail.limitBuy) * 100" activeColor="#FF3F42"
|
|
|
+ active stroke-width="6" />
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="right" @tap="isOpen = !isOpen" v-if="
|
|
|
+ (isServiceUser && !isGroupbuyGoods) ||
|
|
|
+ (isHeadUser && isGroupbuyGoods)
|
|
|
+ ">
|
|
|
+ <text>{{ isOpen ? '收起' : '展开' }}</text>
|
|
|
+ <image :src="
|
|
|
+ isOpen
|
|
|
+ ? '../../static/icon/arrow_2.png'
|
|
|
+ : '../../static/icon/arrow_1.png'
|
|
|
+ "></image>
|
|
|
+ </view>
|
|
|
+ </block>
|
|
|
+ </view>
|
|
|
+ <view class="price" v-if="!isSeckillGoods">
|
|
|
+ <view class="left">
|
|
|
+ <view class="price-1">¥{{ detail.goodsPrice | numToFixed }}</view>
|
|
|
+ <view class="price-2">¥{{ detail.orgGoodsPrice | numToFixed }}</view>
|
|
|
+ </view>
|
|
|
+ <view class="right" @tap="isOpen = !isOpen" v-if="
|
|
|
+ (isServiceUser && !isGroupbuyGoods) ||
|
|
|
+ (isHeadUser && isGroupbuyGoods)
|
|
|
+ ">
|
|
|
+ <text>{{ isOpen ? '收起' : '展开' }}</text>
|
|
|
+ <image :src="
|
|
|
+ isOpen
|
|
|
+ ? '../../static/icon/arrow_2.png'
|
|
|
+ : '../../static/icon/arrow_1.png'
|
|
|
+ "></image>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="bottom" v-if="isOpen">
|
|
|
+ <view v-if="isHeadUser && isGroupbuyGoods">团长分佣金额</view>
|
|
|
+ <view v-else>分享可获得收益</view>
|
|
|
+ <view>¥{{ commission | numToFixed
|
|
|
+ }}{{ detail.goodsSpecs.length > 1 ? '起' : '' }}</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="line-container">
|
|
|
+ <view v-if="
|
|
|
+ accountInfo.miniProgram &&
|
|
|
+ accountInfo.miniProgram.appId !== 'wxf89d330c7b0e718d'
|
|
|
+ ">运费:包邮</view>
|
|
|
+ <view>销量:<text>{{ detail.soldNum }}</text></view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="evaluate-container" v-if="evaluateList.length">
|
|
|
+ <view class="title">商品评价</view>
|
|
|
+ <view class="list">
|
|
|
+ <view class="item" :class="evaluateList.length === 1 ? 'onlyOne' : ''"
|
|
|
+ v-for="(item, index) in evaluateList">
|
|
|
+ <view class="top">
|
|
|
+ <view class="user">
|
|
|
+ <image :src="item.avatar" mode="aspectFill" v-if="item.avatar.indexOf('http') >= 0">
|
|
|
+ </image>
|
|
|
+ <image :src="imageUrl + item.avatar" mode="aspectFill" v-else></image>
|
|
|
+ <view class="name ellipsis">{{ item.userName }}</view>
|
|
|
+ </view>
|
|
|
+ <view class="date">{{ item.createTime }}</view>
|
|
|
+ </view>
|
|
|
+ <view class="rate">
|
|
|
+ <view class="it"><text>商品质量</text><uni-rate :size="14" :margin="4"
|
|
|
+ :value="item.commentGoods" color="#fff" active-color="#FE781F" :readonly="true" />
|
|
|
+ </view>
|
|
|
+ <view class="it"><text>服务质量</text><uni-rate :size="14" :margin="4"
|
|
|
+ :value="item.commentService" color="#fff" active-color="#FE781F" :readonly="true" />
|
|
|
+ </view>
|
|
|
+ <view class="it"><text>配送质量</text><uni-rate :size="14" :margin="4"
|
|
|
+ :value="item.commentExpress" color="#fff" active-color="#FE781F" :readonly="true" />
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="tags">
|
|
|
+ <view class="it" v-for="(it, idx) in item.tags">{{ it }}</view>
|
|
|
+ </view>
|
|
|
+ <view class="content">{{ item.content }}</view>
|
|
|
+ <view class="images" v-if="item.imgs && item.imgs.length > 0">
|
|
|
+ <image v-for="(it, idx) in item.imgs" :src="it" @tap="previewEvaluateImage(it, item.imgs)">
|
|
|
+ </image>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="more">
|
|
|
+ <view class="btn" @tap="toAllEvaluate">查看全部评价</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="detail-container">
|
|
|
+ <view class="title">商品详情</view>
|
|
|
+ <view class="content" v-if="detail.pubCommonTemplate">
|
|
|
+ <u-parse :content="detail.pubCommonTemplate.content"></u-parse>
|
|
|
+ </view>
|
|
|
+ <view class="content" v-if="detail.commonTemplate">
|
|
|
+ <u-parse :content="detail.commonTemplate.content"></u-parse>
|
|
|
+ </view>
|
|
|
+ <view class="content">
|
|
|
+ <u-parse :content="detail.content"></u-parse>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="bottom-container">
|
|
|
+ <view class="left">
|
|
|
+ <view class="item" @tap="clickShare">
|
|
|
+ <image src="@/static/icon/share.png"></image>
|
|
|
+ <text>分享</text>
|
|
|
+ </view>
|
|
|
+ <view class="item" @tap="handleCollect" v-if="!isGroupbuyGoods && !isPackageGoods">
|
|
|
+ <block v-if="detail.favorite">
|
|
|
+ <image src="@/static/icon/collect2.png"></image>
|
|
|
+ <text>已收藏</text>
|
|
|
+ </block>
|
|
|
+ <block v-else>
|
|
|
+ <image src="@/static/icon/collect.png"></image>
|
|
|
+ <text>收藏</text>
|
|
|
+ </block>
|
|
|
+ </view>
|
|
|
+ <view class="item" @tap="toCart">
|
|
|
+ <image src="@/static/icon/cart2.png"></image>
|
|
|
+ <text>购物车</text>
|
|
|
+ <view class="dot" v-if="cartCount > 0">{{
|
|
|
+ cartCount <= 99 ? cartCount : '99+'
|
|
|
+ }}</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="right" v-if="!isSeckillGoods && !isGroupbuyGoods && !isPackageGoods">
|
|
|
+ <view class="button cart" @tap="clickCartOrBuy(1)">加入购物车</view>
|
|
|
+ <view class="button buy" @tap="clickCartOrBuy(2)">立即购买</view>
|
|
|
+ </view>
|
|
|
+ <view class="right" v-if="!isSeckillGoods && isGroupbuyGoods">
|
|
|
+ <view class="button cart" @tap="clickCartOrBuy(1)">加入购物车</view>
|
|
|
+ <view class="button buy" @tap="clickCartOrBuy(4)">立即拼团</view>
|
|
|
+ </view>
|
|
|
+ <view class="right" v-if="isSeckillGoods">
|
|
|
+ <view class="button cart" @tap="clickCartOrBuy(1)">加入购物车</view>
|
|
|
+ <view class="button buy" @tap="clickCartOrBuy(3)">马上抢购</view>
|
|
|
+ </view>
|
|
|
+ <view class="right" v-if="isPackageGoods">
|
|
|
+ <view class="button buy" @tap="clickPackageBuy()">立即购买</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <u-popup :round="10" :closeable="true" :show="isBuyDialog" @close="isBuyDialog = false">
|
|
|
+ <view class="cart-container">
|
|
|
+ <view class="main">
|
|
|
+ <image :src="specList[specCurrent].imgUrl"></image>
|
|
|
+ <view class="right">
|
|
|
+ <view class="title ellipsis-2">{{ detail.goodsName }}</view>
|
|
|
+ <block v-if="isGroupbuyGoods">
|
|
|
+ <view class="price">
|
|
|
+ <view class="price-1">¥{{ specList[specCurrent].price }}</view>
|
|
|
+ <view class="price-2">¥{{ specList[specCurrent].orgPrice }}</view>
|
|
|
+ </view>
|
|
|
+ <view class="stock">剩余{{ specList[specCurrent].stockNum }}件</view>
|
|
|
+ </block>
|
|
|
+ <block v-else-if="isSeckillGoods">
|
|
|
+ <view class="price">
|
|
|
+ <view class="price-1">¥{{ specList[specCurrent].secPrice }}</view>
|
|
|
+ <view class="price-2">¥{{ specList[specCurrent].price }}</view>
|
|
|
+ </view>
|
|
|
+ <view class="stock">剩余{{ detail.secStockNum }}件</view>
|
|
|
+ </block>
|
|
|
+ <block v-else>
|
|
|
+ <view class="price">
|
|
|
+ <view class="price-1">¥{{ specList[specCurrent].price }}</view>
|
|
|
+ <view class="price-2">¥{{ detail.orgGoodsPrice }}</view>
|
|
|
+ </view>
|
|
|
+ <view class="stock">剩余{{ specList[specCurrent].stockNum }}件</view>
|
|
|
+ </block>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="attr">
|
|
|
+ <view class="title">已选属性</view>
|
|
|
+ <view class="list">
|
|
|
+ <block v-for="(item, index) in specList" :key="index">
|
|
|
+ <view class="item" @tap="changeSpec(index)"
|
|
|
+ :class="specCurrent == index ? 'current' : ''">{{ item.name }}-{{ item.specValue }}
|
|
|
+ </view>
|
|
|
+ </block>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="num">
|
|
|
+ <view class="title">购买数量</view>
|
|
|
+ <u-number-box v-model="buyNum" :min="1" :buttonSize="26" iconStyle="font-size: 12px;">
|
|
|
+ </u-number-box>
|
|
|
+ </view>
|
|
|
+ <view class="button" v-if="dialogType == 1" @tap="addToCart">加入购物车</view>
|
|
|
+ <view class="button" v-if="dialogType == 2" @tap="nowBuy">立即购买</view>
|
|
|
+ <view class="button" v-if="dialogType == 3" @tap="rushBuy">马上抢购</view>
|
|
|
+ <view class="button" v-if="dialogType == 4" @tap="nowBuy">马上拼团</view>
|
|
|
+ </view>
|
|
|
+ </u-popup>
|
|
|
+
|
|
|
+ <u-popup :round="10" :closeable="false" :show="isShareDialog" @close="isShareDialog = false">
|
|
|
+ <view class="sharelist-container">
|
|
|
+ <button class="item" open-type="share" @tap="isShareDialog = false">
|
|
|
+ <image src="@/static/icon/wechat.png"></image>
|
|
|
+ <text>分享给微信好友</text>
|
|
|
+ </button>
|
|
|
+
|
|
|
+ <view class="item" @tap="markImage">
|
|
|
+ <image src="@/static/icon/image.png"></image>
|
|
|
+ <text>生成图片分享</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </u-popup>
|
|
|
+
|
|
|
+ <view class="global-mask" v-show="isShowCanvas" @tap="closeCanvas"></view>
|
|
|
+ <view class="canvas-container" v-show="isShowCanvas">
|
|
|
+ <view class="content">
|
|
|
+ <canvas style="width: 300px; height: 520px" canvas-id="myCanvas" id="myCanvas"></canvas>
|
|
|
+ </view>
|
|
|
+ <view class="button"><text @tap="saveImage">保存图片</text></view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <u-popup :round="10" :closeable="true" :show="isPackageDialog" @close="isPackageDialog = false">
|
|
|
+ <view class="package-container">
|
|
|
+ <view class="main">
|
|
|
+ <view class="group" v-for="(item, index) in packageList" :key="index">
|
|
|
+ <view class="title">请选择商品{{ item.num }}件</view>
|
|
|
+ <view class="goods-list">
|
|
|
+ <view class="item" v-for="(it, idx) in item.goodsList" :key="idx">
|
|
|
+ <image :src="it.imgUrl"></image>
|
|
|
+ <view class="right">
|
|
|
+ <view class="name ellipsis-2">{{ it.goodsName }}</view>
|
|
|
+ <view class="des">{{ it.specValue }}</view>
|
|
|
+ <view class="bottom">
|
|
|
+ <view class="price">
|
|
|
+ <view class="price-1">¥{{ it.price | numToFixed }}</view>
|
|
|
+ <view class="price-2">¥{{ it.orgPrice | numToFixed }}</view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <u-number-box v-model="it.num" :min="0" :max="it.limitNum" :buttonSize="26"
|
|
|
+ iconStyle="font-size: 12px;">
|
|
|
+ </u-number-box>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="button" @tap="packageBuy()">立即购买</view>
|
|
|
+ </view>
|
|
|
+ </u-popup>
|
|
|
+
|
|
|
+ <u-popup :round="10" :show="isShowPhoneDialog">
|
|
|
+ <view class="phone-dialog">
|
|
|
+ <view class="content">
|
|
|
+ <view>申请获取以下权限</view>
|
|
|
+ <text>获得你的公开信息(手机号码)</text>
|
|
|
+ </view>
|
|
|
+ <view class="btn">
|
|
|
+ <button @tap="isShowPhoneDialog = false">取消</button>
|
|
|
+ <button type="primary" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">
|
|
|
+ 确定授权
|
|
|
+ </button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </u-popup>
|
|
|
+ </block>
|
|
|
+
|
|
|
+ <canvas style="
|
|
|
+ width: 800px;
|
|
|
+ height: 800px;
|
|
|
+ z-index: -1;
|
|
|
+ position: fixed;
|
|
|
+ bottom: -1000px;
|
|
|
+ right: -1000px;
|
|
|
+ " canvas-id="myCanvas22" id="myCanvas22"></canvas>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ import {
|
|
|
+ mapState
|
|
|
+ } from 'vuex';
|
|
|
+ import {
|
|
|
+ base64src
|
|
|
+ } from '@/utils/base.js';
|
|
|
+ import {
|
|
|
+ appId
|
|
|
+ } from '@/utils/config.js';
|
|
|
+ import {
|
|
|
+ uploadImg
|
|
|
+ } from '@/api/axios.js';
|
|
|
+ export default {
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ isShowPhoneDialog: false,
|
|
|
+ imageUrl: this.$imageUrl,
|
|
|
+ configInfo: uni.getStorageSync('configInfo'),
|
|
|
+ isLoaded: false,
|
|
|
+ noData: true,
|
|
|
+ goodsId: null, // 商品id
|
|
|
+ detail: {}, // 商品详情
|
|
|
+ commission: 0, // 分佣金额
|
|
|
+ bannerList: [], // 轮播图列表
|
|
|
+ bannerCurrent: 0, // 轮播图当前值
|
|
|
+ specList: [], // 规格列表
|
|
|
+ specCurrent: 0, // 规格当前值
|
|
|
+ isOpen: false, // 是否展开
|
|
|
+ isBuyDialog: false, // 是否显示购买/加入购物车弹窗
|
|
|
+ dialogType: 1, // 弹窗类型: 1加入购物车,2立即购买,3秒杀抢购
|
|
|
+ isShareDialog: false, // 是否显示分享弹窗
|
|
|
+ isShowCanvas: false, // 是否显示海报弹窗
|
|
|
+ buyNum: 1, // 购买/加入购物车 数量
|
|
|
+ isSeckillGoods: false, // 是否秒杀商品
|
|
|
+ isGroupbuyGoods: false, // 是否团购商品
|
|
|
+ isPackageGoods: false, // 是否套购商品
|
|
|
+ isPackageDialog: false, // 是否显示套购购买弹窗
|
|
|
+ packageList: [], // 套购选择列表
|
|
|
+ cartCount: 0, // 购物车内商品数
|
|
|
+ isFinishCanvas: false, // 是否已完成海报
|
|
|
+ codeUrl: '', // 商品码
|
|
|
+ videoContext1: '', // 视频对象
|
|
|
+ videoContext2: '', // 视频对象
|
|
|
+ isFixedVideo: false, // 是否显示视频弹窗
|
|
|
+ isPlayVideo: false, // 视频是否播放中
|
|
|
+ isCloseMyself: false, // 是否亲自关闭视频弹窗
|
|
|
+ countdownTime: '', // 倒计时
|
|
|
+ endHour: 0, // 倒计时结束时间
|
|
|
+ evaluateList: [],
|
|
|
+ isShowWater: false,
|
|
|
+ accountInfo: {},
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ ...mapState(['userInfo', 'isLogin', 'userId']),
|
|
|
+
|
|
|
+ isHeadUser() {
|
|
|
+ // 是否团长
|
|
|
+ return this.userInfo.promotionGroupLeader;
|
|
|
+ },
|
|
|
+ isServiceUser() {
|
|
|
+ // 是否业务员
|
|
|
+ return this.userInfo.type === 'SERVICE';
|
|
|
+ },
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ countdownTime() {
|
|
|
+ if (
|
|
|
+ this.countdownTime[0] == 0 &&
|
|
|
+ this.countdownTime[1] == 0 &&
|
|
|
+ this.countdownTime[2] == 0
|
|
|
+ ) {
|
|
|
+ this.getDetail();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ onPageScroll(res) {
|
|
|
+ if (
|
|
|
+ res.scrollTop > 300 &&
|
|
|
+ this.isPlayVideo &&
|
|
|
+ !this.isCloseMyself &&
|
|
|
+ this.detail.vedio
|
|
|
+ ) {
|
|
|
+ this.isFixedVideo = true;
|
|
|
+ this.videoContext2.play();
|
|
|
+ } else {
|
|
|
+ this.isFixedVideo = false;
|
|
|
+ this.videoContext2.pause();
|
|
|
+ }
|
|
|
+ if (res.scrollTop < 300) {
|
|
|
+ this.isCloseMyself = false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onLoad({
|
|
|
+ id
|
|
|
+ }) {
|
|
|
+ this.accountInfo = uni.getAccountInfoSync();
|
|
|
+ this.goodsId = id;
|
|
|
+ this.getDetail();
|
|
|
+ this.getEvaluateList();
|
|
|
+ this.getCartCount();
|
|
|
+ uni.showLoading({
|
|
|
+ title: '加载中',
|
|
|
+ });
|
|
|
+ },
|
|
|
+ onShow() {
|
|
|
+ this.isBuyDialog = false;
|
|
|
+ },
|
|
|
+ onReady() {
|
|
|
+ this.videoContext1 = uni.createVideoContext('video1');
|
|
|
+ this.videoContext2 = uni.createVideoContext('video2');
|
|
|
+ },
|
|
|
+ async onShareAppMessage(options) {
|
|
|
+ if (options && options.from == 'button') {
|
|
|
+ // 来自页面内的转发按钮
|
|
|
+ } else {
|
|
|
+ // 点击微信右上角的分享按钮
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ title: '分享商品「' + this.detail.goodsName + '」',
|
|
|
+ imageUrl: await this.markImage222(),
|
|
|
+ path: '/pages/index/index?goodsId=' +
|
|
|
+ this.goodsId +
|
|
|
+ '&serviceId=' +
|
|
|
+ this.userId,
|
|
|
+ query: {
|
|
|
+ // id: this.goodsId,
|
|
|
+ },
|
|
|
+ success: function(res) {
|
|
|
+ if (res.errMsg == 'shareAppMessage:ok') {
|
|
|
+ this.$successToast('分享完成');
|
|
|
+ }
|
|
|
+ },
|
|
|
+ };
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // 获取手机号
|
|
|
+ getPhoneNumber(e) {
|
|
|
+ if (e?.detail?.iv && e?.detail?.encryptedData) {
|
|
|
+ this.$axios({
|
|
|
+ url: '/user/mobile/grant',
|
|
|
+ params: {
|
|
|
+ userId: this.userId,
|
|
|
+ iv: e.detail.iv,
|
|
|
+ encryptedData: e.detail.encryptedData,
|
|
|
+ },
|
|
|
+ }).then((res) => {
|
|
|
+ uni.setStorageSync('token', res.data.token);
|
|
|
+ uni.setStorageSync('isActiveLogout', false);
|
|
|
+ this.isShowPhoneDialog = false;
|
|
|
+ this.$getUserInfo();
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 获取详情
|
|
|
+ getDetail() {
|
|
|
+ this.$axios({
|
|
|
+ url: '/goods/detail',
|
|
|
+ method: 'get',
|
|
|
+ params: {
|
|
|
+ goodsId: this.goodsId,
|
|
|
+ userId: this.userId,
|
|
|
+ },
|
|
|
+ })
|
|
|
+ .then((res) => {
|
|
|
+ this.detail = res.data;
|
|
|
+ this.noData = false;
|
|
|
+ this.isLoaded = true;
|
|
|
+ // 团购
|
|
|
+ this.isGroupbuyGoods = res.data.promotionGroup;
|
|
|
+ // 秒杀
|
|
|
+ this.isSeckillGoods = res.data.secType;
|
|
|
+ this.endHour = res.data.endHour;
|
|
|
+ this.countTime();
|
|
|
+ // 套购
|
|
|
+ this.isPackageGoods = res.data.goodsType === 'PACKAGE';
|
|
|
+
|
|
|
+ this.bannerList = res.data.images;
|
|
|
+ this.specList = res.data.goodsSpecs;
|
|
|
+ this.specCurrent = 0;
|
|
|
+
|
|
|
+ if (!this.isPackageGoods) {
|
|
|
+ let commissionList = [];
|
|
|
+ this.specList.forEach((item, index) => {
|
|
|
+ item.price = item.price.toFixed(2);
|
|
|
+ item.orgPrice = item.orgPrice.toFixed(2);
|
|
|
+ commissionList.push(item.shareAmount);
|
|
|
+ });
|
|
|
+ this.commission = Math.min(...commissionList);
|
|
|
+ } else {
|
|
|
+ this.commission = res.data.shareAmount;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 水印
|
|
|
+ if (res.data.logo && res.data.logoStartTime) {
|
|
|
+ this.isShowWater = this.$compareTime(
|
|
|
+ res.data.logoStartTime,
|
|
|
+ res.data.logoEndTime
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ this.isShowWater = false;
|
|
|
+ }
|
|
|
+ this.markImage222(false);
|
|
|
+ })
|
|
|
+ .catch((res) => {
|
|
|
+ this.noData = true;
|
|
|
+ this.isLoaded = true;
|
|
|
+ })
|
|
|
+ .finally((res) => {
|
|
|
+ uni.hideLoading();
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 获取评价列表
|
|
|
+ getEvaluateList() {
|
|
|
+ this.$axios({
|
|
|
+ url: '/order/comment/goods',
|
|
|
+ method: 'get',
|
|
|
+ params: {
|
|
|
+ pageNo: 1,
|
|
|
+ pageSize: 5,
|
|
|
+ goodsId: this.goodsId,
|
|
|
+ },
|
|
|
+ }).then((res) => {
|
|
|
+ this.evaluateList = res.data.records;
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 查询结束时间
|
|
|
+ checkEndTime(val) {
|
|
|
+ let yy = new Date().getFullYear();
|
|
|
+ let mm = new Date().getMonth() + 1;
|
|
|
+ let dd = new Date().getDate();
|
|
|
+ // dd = val == 10 ? dd + 1 : dd;
|
|
|
+
|
|
|
+ // 每月有多少天
|
|
|
+ let days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
|
+ if ((yy % 4 == 0 && yy % 100 != 0) || yy % 400 == 0) {
|
|
|
+ days[1] = 29;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果结束时间=10(表示第二天10点),dd需加一天
|
|
|
+ if (val == 10) {
|
|
|
+ if (dd >= days[mm - 1]) {
|
|
|
+ mm = mm + 1;
|
|
|
+ } else {
|
|
|
+ dd = dd + 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let date = yy + '/' + mm + '/' + dd;
|
|
|
+ let dateTime = date + ' ' + val + ':00:00';
|
|
|
+ return dateTime;
|
|
|
+ },
|
|
|
+
|
|
|
+ // 计算倒计时
|
|
|
+ countTime() {
|
|
|
+ let endDateTime = this.checkEndTime(this.endHour);
|
|
|
+ var nowtime = new Date(), //获取当前时间
|
|
|
+ endtime = new Date(endDateTime); //定义结束时间
|
|
|
+ var lefttime = endtime.getTime() - nowtime.getTime(), //距离结束时间的毫秒数
|
|
|
+ hh = Math.floor(lefttime / (1000 * 60 * 60)), //计算小时数
|
|
|
+ mm = Math.floor((lefttime / (1000 * 60)) % 60), //计算分钟数
|
|
|
+ ss = Math.floor((lefttime / 1000) % 60); //计算秒数
|
|
|
+ function checkTime(i) {
|
|
|
+ if (i < 10) {
|
|
|
+ i = '0' + i;
|
|
|
+ }
|
|
|
+ return i;
|
|
|
+ }
|
|
|
+ setTimeout(() => {
|
|
|
+ this.countTime();
|
|
|
+ }, 1000);
|
|
|
+ this.countdownTime = [checkTime(hh), checkTime(mm), checkTime(ss)];
|
|
|
+ },
|
|
|
+
|
|
|
+ // 获取商品二维码
|
|
|
+ getGoodsCode(success) {
|
|
|
+ const that = this;
|
|
|
+ this.$axios({
|
|
|
+ url: '/goods/qrcode',
|
|
|
+ method: 'get',
|
|
|
+ params: {
|
|
|
+ goodsId: this.goodsId,
|
|
|
+ userId: this.userId,
|
|
|
+ },
|
|
|
+ }).then((res) => {
|
|
|
+ // this.codeUrl = 'data:image/jpeg;base64,' + res.data;
|
|
|
+ that.codeUrl = res.data;
|
|
|
+ console.log(this.codeUrl, typeof success);
|
|
|
+ if (typeof success === 'function') {
|
|
|
+ success();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 视频播放
|
|
|
+ playVideo(e) {
|
|
|
+ this.isPlayVideo = true;
|
|
|
+ },
|
|
|
+
|
|
|
+ // 视频暂停
|
|
|
+ pauseVideo(e) {
|
|
|
+ this.isPlayVideo = false;
|
|
|
+ },
|
|
|
+
|
|
|
+ // 关闭视频弹窗
|
|
|
+ closeFixedVideo() {
|
|
|
+ this.isFixedVideo = false;
|
|
|
+ this.isCloseMyself = true;
|
|
|
+ this.videoContext2.pause();
|
|
|
+ },
|
|
|
+
|
|
|
+ // 从个人信息获取购物车商品数量
|
|
|
+ getCartCount() {
|
|
|
+ this.$axios({
|
|
|
+ url: '/user/user/detail',
|
|
|
+ method: 'get',
|
|
|
+ params: {
|
|
|
+ userId: this.userId,
|
|
|
+ },
|
|
|
+ }).then((res) => {
|
|
|
+ this.cartCount = res.data.shoppingCartNums;
|
|
|
+
|
|
|
+ if (!res.data.openId) {
|
|
|
+ return uni.navigateTo({
|
|
|
+ url: '/pages/login/index?isNotOpenid=' + true,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 查看所有评价
|
|
|
+ toAllEvaluate() {
|
|
|
+ uni.navigateTo({
|
|
|
+ url: '/packageGoods/pages/evaluate?goodsId=' + this.goodsId,
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 收藏/取消收藏
|
|
|
+ handleCollect() {
|
|
|
+ if (!this.isLogin) {
|
|
|
+ return uni.navigateTo({
|
|
|
+ url: '/pages/login/index',
|
|
|
+ });
|
|
|
+ }
|
|
|
+ if (!this.detail.favorite) {
|
|
|
+ this.$axios({
|
|
|
+ url: '/goods/favorite/add',
|
|
|
+ params: {
|
|
|
+ goodsId: this.goodsId,
|
|
|
+ userId: this.userId,
|
|
|
+ },
|
|
|
+ }).then((res) => {
|
|
|
+ this.$successToast('收藏成功');
|
|
|
+ this.getDetail();
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.$axios({
|
|
|
+ url: '/goods/favorite/detail/del',
|
|
|
+ params: {
|
|
|
+ goodsId: this.goodsId,
|
|
|
+ userId: this.userId,
|
|
|
+ },
|
|
|
+ }).then((res) => {
|
|
|
+ this.$successToast('取消收藏成功');
|
|
|
+ this.getDetail();
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 切换图片
|
|
|
+ changeBanner(e) {
|
|
|
+ this.bannerCurrent = e.detail.current;
|
|
|
+ if (this.bannerCurrent > 0 && this.detail.vedio) {
|
|
|
+ this.videoContext1.pause();
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 预览图片
|
|
|
+ previewImage(url) {
|
|
|
+ let imgs = [];
|
|
|
+ this.bannerList.forEach((item, index) => {
|
|
|
+ imgs.push(item.url);
|
|
|
+ });
|
|
|
+ uni.previewImage({
|
|
|
+ urls: imgs,
|
|
|
+ current: url,
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 预览评价图片
|
|
|
+ previewEvaluateImage(url, imgs) {
|
|
|
+ uni.previewImage({
|
|
|
+ urls: imgs,
|
|
|
+ current: url,
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 点击分享
|
|
|
+ clickShare() {
|
|
|
+ if (!this.isLogin) {
|
|
|
+ return uni.navigateTo({
|
|
|
+ url: '/pages/login/index',
|
|
|
+ });
|
|
|
+ }
|
|
|
+ // this.getGoodsCode();
|
|
|
+ this.isShareDialog = true;
|
|
|
+ },
|
|
|
+
|
|
|
+ // 点击加入购物车/立即购买
|
|
|
+ clickCartOrBuy(type) {
|
|
|
+ if (!this.isLogin) {
|
|
|
+ return uni.navigateTo({
|
|
|
+ url: '/pages/login/index',
|
|
|
+ });
|
|
|
+ }
|
|
|
+ this.dialogType = type;
|
|
|
+ this.isBuyDialog = true;
|
|
|
+ },
|
|
|
+
|
|
|
+ // 切换规格
|
|
|
+ changeSpec(index) {
|
|
|
+ this.specCurrent = index;
|
|
|
+ },
|
|
|
+
|
|
|
+ // 加入购物车
|
|
|
+ addToCart() {
|
|
|
+ if (this.specList[this.specCurrent].stockNum == 0) {
|
|
|
+ return this.$toast('该规格库存不足');
|
|
|
+ }
|
|
|
+ this.$axios({
|
|
|
+ url: '/shpping/cart/add/one',
|
|
|
+ type: 'application/json',
|
|
|
+ params: {
|
|
|
+ userId: this.userId,
|
|
|
+ buyGoods: [{
|
|
|
+ goodsId: this.goodsId,
|
|
|
+ goodsSpecId: this.specList[this.specCurrent].goodsSpecId,
|
|
|
+ num: this.buyNum,
|
|
|
+ secKillId: this.detail.secKillId || '',
|
|
|
+ promotionGroupId: this.detail.promotionGroupId || '',
|
|
|
+ }, ],
|
|
|
+ },
|
|
|
+ isLoading: 1,
|
|
|
+ }).then((res) => {
|
|
|
+ this.$successToast('添加成功');
|
|
|
+ this.getCartCount();
|
|
|
+ this.isBuyDialog = false;
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 立即购买
|
|
|
+ nowBuy() {
|
|
|
+ if (this.specList[this.specCurrent].stockNum == 0) {
|
|
|
+ return this.$toast('该规格库存不足');
|
|
|
+ }
|
|
|
+ if (!this.userInfo.mobile) {
|
|
|
+ this.isShowPhoneDialog = true;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ let buyList = [{
|
|
|
+ goodsId: this.goodsId,
|
|
|
+ goodsSpecId: this.specList[this.specCurrent].goodsSpecId,
|
|
|
+ num: this.buyNum,
|
|
|
+ secKillId: this.detail.secKillId || '',
|
|
|
+ promotionGroupId: this.detail.promotionGroupId || '',
|
|
|
+ }, ];
|
|
|
+ let url = '/packageGoods/pages/order?buyList=' + JSON.stringify(buyList);
|
|
|
+ if (this.detail.promotionGroupId) {
|
|
|
+ url = url + '&groupbuyId=' + this.detail.promotionGroupId;
|
|
|
+ }
|
|
|
+ uni.navigateTo({
|
|
|
+ url,
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 马上抢购(秒杀)
|
|
|
+ rushBuy() {
|
|
|
+ if (this.detail.secStockNum == 0) {
|
|
|
+ return this.$toast('该规格库存不足');
|
|
|
+ }
|
|
|
+ if (!this.userInfo.mobile) {
|
|
|
+ this.isShowPhoneDialog = true;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.$axios({
|
|
|
+ url: '/goods/sec/kill/start',
|
|
|
+ method: 'post',
|
|
|
+ params: {
|
|
|
+ secKillId: this.detail.secKillId,
|
|
|
+ },
|
|
|
+ }).then((res) => {
|
|
|
+ if (res.data) {
|
|
|
+ let buyList = [{
|
|
|
+ goodsId: this.goodsId,
|
|
|
+ goodsSpecId: this.specList[this.specCurrent].goodsSpecId,
|
|
|
+ num: this.buyNum,
|
|
|
+ secKillId: this.detail.secKillId || '',
|
|
|
+ promotionGroupId: this.detail.promotionGroupId || '',
|
|
|
+ }, ];
|
|
|
+ uni.navigateTo({
|
|
|
+ url: '/packageGoods/pages/order?buyList=' +
|
|
|
+ JSON.stringify(buyList) +
|
|
|
+ '&secKillId=' +
|
|
|
+ this.detail.secKillId +
|
|
|
+ '&secKillSpecId=' +
|
|
|
+ this.detail.secKillSpecId +
|
|
|
+ '&secToken=' +
|
|
|
+ res.data,
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.$toast('活动异常');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 去购物车页面
|
|
|
+ toCart() {
|
|
|
+ uni.switchTab({
|
|
|
+ url: '/pages/cart/index',
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 打开套购购买弹窗
|
|
|
+ clickPackageBuy() {
|
|
|
+ this.packageList = [];
|
|
|
+ this.$axios({
|
|
|
+ url: '/goods/package/choice',
|
|
|
+ method: 'get',
|
|
|
+ params: {
|
|
|
+ goodsId: this.goodsId,
|
|
|
+ },
|
|
|
+ }).then((res) => {
|
|
|
+ let goodsList = res.data;
|
|
|
+ for (let i = 0; i < goodsList.length; i++) {
|
|
|
+ for (let j = 0; j < goodsList[i].length; j++) {
|
|
|
+ goodsList[i][j].num = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ let pops = this.detail.packagePop.split(':');
|
|
|
+ pops.forEach((item, index) => {
|
|
|
+ this.packageList.push({
|
|
|
+ num: item,
|
|
|
+ goodsList: goodsList[index],
|
|
|
+ });
|
|
|
+ });
|
|
|
+ console.log(this.packageList);
|
|
|
+ this.isPackageDialog = true;
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 套购购买
|
|
|
+ packageBuy() {
|
|
|
+ if (!this.userInfo.mobile) {
|
|
|
+ this.isShowPhoneDialog = true;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ let buyList = [];
|
|
|
+ for (let i = 0; i < this.packageList.length; i++) {
|
|
|
+ for (let j = 0; j < this.packageList[i].goodsList.length; j++) {
|
|
|
+ if (this.packageList[i].goodsList[j].num > 0) {
|
|
|
+ buyList.push({
|
|
|
+ goodsId: this.packageList[i].goodsList[j].goodsId,
|
|
|
+ goodsSpecId: this.packageList[i].goodsList[j].goodsSpecId,
|
|
|
+ popType: this.packageList[i].goodsList[j].type,
|
|
|
+ num: this.packageList[i].goodsList[j].num,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ uni.navigateTo({
|
|
|
+ url: '/packageGoods/pages/order?buyList=' +
|
|
|
+ JSON.stringify(buyList) +
|
|
|
+ '&packageId=' +
|
|
|
+ this.detail.goodsId,
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 分享
|
|
|
+ share() {
|
|
|
+ uni.share({
|
|
|
+ provider: 'weixin',
|
|
|
+ scene: 'WXSceneSession',
|
|
|
+ type: 5,
|
|
|
+ summary: '我正在使用HBuilderX开发uni-app,赶紧跟我一起来体验!',
|
|
|
+ success: function(res) {
|
|
|
+ console.log('success:' + JSON.stringify(res));
|
|
|
+ },
|
|
|
+ fail: function(err) {
|
|
|
+ console.log('fail:' + JSON.stringify(err));
|
|
|
+ },
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ async markImage222(bool = true) {
|
|
|
+ return new Promise((r) => {
|
|
|
+ if (
|
|
|
+ this.detail.logo &&
|
|
|
+ this.detail.imgUrl &&
|
|
|
+ this.$compareTime(this.detail.logoStartTime, this.detail.logoEndTime)
|
|
|
+ ) {
|
|
|
+ if (!!this.detail.mergeImage) {
|
|
|
+ r(this.detail.mergeImage);
|
|
|
+ } else {
|
|
|
+ if (bool) {
|
|
|
+ uni.showLoading({
|
|
|
+ title: '图片生成中',
|
|
|
+ });
|
|
|
+ }
|
|
|
+ this.getGoodsCode(() => {
|
|
|
+ let img = this.detail.imgUrl;
|
|
|
+ let logo = this.detail.logo;
|
|
|
+ var ctx = uni.createCanvasContext('myCanvas22');
|
|
|
+ ctx.rect(0, 0, 800, 800);
|
|
|
+ ctx.setFillStyle('#FFFFFF');
|
|
|
+ ctx.fill();
|
|
|
+ ctx.stroke();
|
|
|
+ uni.downloadFile({
|
|
|
+ url: img,
|
|
|
+ success: (res) => {
|
|
|
+ ctx.drawImage(res.tempFilePath, 0, 0, 800, 800);
|
|
|
+ uni.downloadFile({
|
|
|
+ url: logo,
|
|
|
+ success: (res2) => {
|
|
|
+ ctx.drawImage(res2
|
|
|
+ .tempFilePath, 0, 0,
|
|
|
+ 800, 800);
|
|
|
+ ctx.draw();
|
|
|
+ uni.canvasToTempFilePath({
|
|
|
+ x: 0,
|
|
|
+ y: 0,
|
|
|
+ width: 800,
|
|
|
+ height: 800,
|
|
|
+ canvasId: 'myCanvas22',
|
|
|
+ success: (
|
|
|
+ res33) => {
|
|
|
+ uploadImg({
|
|
|
+ path: res33
|
|
|
+ .tempFilePath,
|
|
|
+ })
|
|
|
+ .then((
|
|
|
+ data
|
|
|
+ ) => {
|
|
|
+ this.$axios({
|
|
|
+ url: '/goods/update/mergeImage',
|
|
|
+ method: 'post',
|
|
|
+ params: {
|
|
|
+ goodsId: this
|
|
|
+ .goodsId,
|
|
|
+ imgUrl: data
|
|
|
+ .url,
|
|
|
+ },
|
|
|
+ })
|
|
|
+ .then(
|
|
|
+ (
|
|
|
+ res
|
|
|
+ ) => {
|
|
|
+ if (
|
|
|
+ bool
|
|
|
+ ) {
|
|
|
+ uni
|
|
|
+ .hideLoading();
|
|
|
+ this
|
|
|
+ .getDetail();
|
|
|
+ }
|
|
|
+ r(res
|
|
|
+ .data
|
|
|
+ );
|
|
|
+ }
|
|
|
+ );
|
|
|
+ });
|
|
|
+ },
|
|
|
+ });
|
|
|
+ },
|
|
|
+ });
|
|
|
+ },
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ r(this.detail.imgUrl);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 生成图片
|
|
|
+ markImage() {
|
|
|
+ this.isShareDialog = false;
|
|
|
+ this.isShowCanvas = true;
|
|
|
+
|
|
|
+ if (this.isFinishCanvas) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ uni.showLoading({
|
|
|
+ title: '海报生成中',
|
|
|
+ });
|
|
|
+
|
|
|
+ // 调用获取二维图接口后执行匿名函数
|
|
|
+ this.getGoodsCode(() => {
|
|
|
+ let img = this.detail.imgUrl;
|
|
|
+ let logo = this.detail.logo;
|
|
|
+ let title = this.detail.goodsName;
|
|
|
+ let des = this.detail.describeText;
|
|
|
+ let price1 = this.detail.goodsPrice;
|
|
|
+ let price2 = this.detail.orgGoodsPrice;
|
|
|
+ let sales = this.detail.soldNum;
|
|
|
+ // let code = this.codeUrl;
|
|
|
+ // base64src(this.codeUrl , resCurrent => {
|
|
|
+ // code = resCurrent;
|
|
|
+ // })
|
|
|
+
|
|
|
+ var ctx = uni.createCanvasContext('myCanvas');
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param {Object} str 要绘制的字符串
|
|
|
+ * @param {Number} initX 绘制字符串起始x坐标
|
|
|
+ * @param {Number} initY 绘制字符串起始y坐标
|
|
|
+ * @param {Number} lineHeight 字行高
|
|
|
+ */
|
|
|
+ function canvasTextAutoLine(str, initX, initY, lineHeight) {
|
|
|
+ var lineWidth = 0;
|
|
|
+ var canvasWidth = 260;
|
|
|
+ var lastSubStrIndex = 0;
|
|
|
+ var lineNum = 0;
|
|
|
+ var state = true;
|
|
|
+ for (let i = 0; i < str.length; i++) {
|
|
|
+ lineWidth += ctx.measureText(str[i]).width;
|
|
|
+ if (lineWidth > canvasWidth && lineNum < 1) {
|
|
|
+ ctx.fillText(str.substring(lastSubStrIndex, i), initX, initY);
|
|
|
+ initY += lineHeight;
|
|
|
+ lineWidth = 0;
|
|
|
+ lastSubStrIndex = i;
|
|
|
+ lineNum++;
|
|
|
+ } else if (lineWidth > canvasWidth && lineNum < 2) {
|
|
|
+ ctx.fillText(
|
|
|
+ str.substring(lastSubStrIndex + 2, i) + '...',
|
|
|
+ initX,
|
|
|
+ initY
|
|
|
+ );
|
|
|
+ lineNum++;
|
|
|
+ state = false;
|
|
|
+ }
|
|
|
+ if (i == str.length - 1 && state) {
|
|
|
+ ctx.fillText(str.substring(lastSubStrIndex, i + 1), initX, initY);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 白色背景
|
|
|
+ ctx.rect(0, 0, 300, 520);
|
|
|
+ ctx.setFillStyle('#FFFFFF');
|
|
|
+ ctx.fill();
|
|
|
+ ctx.stroke();
|
|
|
+
|
|
|
+ // 商品名称
|
|
|
+ ctx.setFontSize(14);
|
|
|
+ ctx.setFillStyle('#333333');
|
|
|
+ canvasTextAutoLine(title, 20, 300, 18);
|
|
|
+
|
|
|
+ // 商品描述
|
|
|
+ if (des) {
|
|
|
+ ctx.setFontSize(12);
|
|
|
+ ctx.setFillStyle('#999999');
|
|
|
+ canvasTextAutoLine(des, 20, 336, 16);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 现价
|
|
|
+ ctx.setFontSize(16);
|
|
|
+ ctx.setFillStyle('#FF3F42');
|
|
|
+ ctx.fillText('¥' + price1, 20, 380);
|
|
|
+
|
|
|
+ // 原价
|
|
|
+ ctx.setFontSize(13);
|
|
|
+ ctx.setFillStyle('#666666');
|
|
|
+ ctx.fillText('¥' + price2, 20, 396);
|
|
|
+ ctx.setStrokeStyle('#666666');
|
|
|
+ ctx.moveTo(20, 392);
|
|
|
+ ctx.lineTo(ctx.measureText('¥' + price2).width + 20, 392);
|
|
|
+ ctx.stroke();
|
|
|
+
|
|
|
+ // 销量
|
|
|
+ ctx.setFontSize(12);
|
|
|
+ ctx.setFillStyle('#666666');
|
|
|
+ ctx.fillText(
|
|
|
+ '销量:' + sales,
|
|
|
+ 260 - ctx.measureText('销量:' + sales).width + 20,
|
|
|
+ 380
|
|
|
+ );
|
|
|
+
|
|
|
+ // 二维码
|
|
|
+ // ctx.drawImage(code, 110, 404, 80, 80)
|
|
|
+
|
|
|
+ // 提示
|
|
|
+ ctx.setFontSize(12);
|
|
|
+ ctx.setFillStyle('#FE781F');
|
|
|
+ ctx.fillText('打开微信扫描识别查看商品', 78, 500);
|
|
|
+ // 图片
|
|
|
+ uni.downloadFile({
|
|
|
+ url: img,
|
|
|
+ success: (res) => {
|
|
|
+ ctx.drawImage(res.tempFilePath, 20, 20, 260, 260);
|
|
|
+ // 二维码
|
|
|
+ uni.downloadFile({
|
|
|
+ url: this.codeUrl,
|
|
|
+ success: (res) => {
|
|
|
+ ctx.drawImage(res.tempFilePath, 110, 404, 80, 80);
|
|
|
+ if (this.isShowWater) {
|
|
|
+ uni.downloadFile({
|
|
|
+ url: logo,
|
|
|
+ success: (res2) => {
|
|
|
+ ctx.drawImage(res2
|
|
|
+ .tempFilePath, 20, 20,
|
|
|
+ 260, 260);
|
|
|
+ ctx.draw();
|
|
|
+ uni.hideLoading();
|
|
|
+ this.isFinishCanvas = true;
|
|
|
+ },
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ console.log('生成画布成功');
|
|
|
+ ctx.draw();
|
|
|
+ uni.hideLoading();
|
|
|
+ this.isFinishCanvas = true;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ });
|
|
|
+ },
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 保存图片
|
|
|
+ saveImage() {
|
|
|
+ let that = this;
|
|
|
+ uni.canvasToTempFilePath({
|
|
|
+ x: 0,
|
|
|
+ y: 0,
|
|
|
+ width: 300,
|
|
|
+ height: 520,
|
|
|
+ canvasId: 'myCanvas',
|
|
|
+ success: function(res) {
|
|
|
+ uni.saveImageToPhotosAlbum({
|
|
|
+ filePath: res.tempFilePath,
|
|
|
+ success: function() {
|
|
|
+ that.$successToast('保存成功');
|
|
|
+ },
|
|
|
+ });
|
|
|
+ },
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 关闭canvas
|
|
|
+ closeCanvas() {
|
|
|
+ this.isShowCanvas = false;
|
|
|
+ uni.hideLoading();
|
|
|
+ },
|
|
|
+ },
|
|
|
+ };
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+ .app-container {
|
|
|
+ background: #f4f2f2;
|
|
|
+ box-sizing: border-box;
|
|
|
+ padding-bottom: 100rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .recommender-container {
|
|
|
+ position: fixed;
|
|
|
+ top: 20rpx;
|
|
|
+ left: 0;
|
|
|
+ z-index: 99;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ width: 100%;
|
|
|
+
|
|
|
+ .content {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #ffffff;
|
|
|
+ background: rgba($color: #000000, $alpha: 0.8);
|
|
|
+ display: flex;
|
|
|
+ padding: 0 15rpx;
|
|
|
+ height: 60rpx;
|
|
|
+ border-radius: 60rpx;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ image {
|
|
|
+ width: 40rpx;
|
|
|
+ height: 40rpx;
|
|
|
+ display: block;
|
|
|
+ border-radius: 50%;
|
|
|
+ margin-right: 10rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .name {
|
|
|
+ max-width: 160rpx;
|
|
|
+ margin-right: 6rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .swiper-container {
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ swiper {
|
|
|
+ height: 750rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .image {
|
|
|
+ width: 750rpx;
|
|
|
+ height: 750rpx;
|
|
|
+ display: block;
|
|
|
+ margin: 0 auto;
|
|
|
+ overflow: hidden;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .img {
|
|
|
+ width: 750rpx;
|
|
|
+ height: 750rpx;
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
+
|
|
|
+ .water {
|
|
|
+ width: 750rpx;
|
|
|
+ height: 750rpx;
|
|
|
+ display: block;
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ z-index: 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // image {
|
|
|
+ // height: 750rpx;
|
|
|
+ // width: 750rpx;
|
|
|
+ // display: block;
|
|
|
+ // margin: 0 auto;
|
|
|
+ // overflow: hidden;
|
|
|
+ // }
|
|
|
+ video {
|
|
|
+ height: 750rpx;
|
|
|
+ width: 750rpx;
|
|
|
+ display: block;
|
|
|
+ margin: 0 auto;
|
|
|
+ overflow: hidden;
|
|
|
+ }
|
|
|
+
|
|
|
+ .nums {
|
|
|
+ position: absolute;
|
|
|
+ right: 20rpx;
|
|
|
+ bottom: 20rpx;
|
|
|
+ background: rgba($color: #000000, $alpha: 0.2);
|
|
|
+ border-radius: 8rpx;
|
|
|
+ line-height: 48rpx;
|
|
|
+ padding: 0 12rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #ffffff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .video-container {
|
|
|
+ position: fixed;
|
|
|
+ right: 20rpx;
|
|
|
+ bottom: 300rpx;
|
|
|
+ z-index: -99;
|
|
|
+
|
|
|
+ &.isFixed {
|
|
|
+ z-index: 99;
|
|
|
+ }
|
|
|
+
|
|
|
+ .content {
|
|
|
+ position: relative;
|
|
|
+ }
|
|
|
+
|
|
|
+ video {
|
|
|
+ height: 200rpx;
|
|
|
+ width: 375rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .close {
|
|
|
+ position: absolute;
|
|
|
+ right: 0;
|
|
|
+ top: 0;
|
|
|
+ z-index: 100;
|
|
|
+ background: rgba($color: #000000, $alpha: 0.4);
|
|
|
+ padding: 10rpx;
|
|
|
+
|
|
|
+ image {
|
|
|
+ width: 28rpx;
|
|
|
+ height: 28rpx;
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .seckill-container {
|
|
|
+ height: 120rpx;
|
|
|
+ background: linear-gradient(-90deg, rgba(255, 37, 118, 1) 0%, #ff5648 100%);
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ padding: 0 20rpx;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .clock {
|
|
|
+ position: absolute;
|
|
|
+ right: 220rpx;
|
|
|
+ top: 20rpx;
|
|
|
+
|
|
|
+ image {
|
|
|
+ width: 74rpx;
|
|
|
+ height: 72rpx;
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .price-1 {
|
|
|
+ font-size: 40rpx;
|
|
|
+ color: #ffffff;
|
|
|
+ line-height: 44rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .price-2 {
|
|
|
+ font-size: 28rpx;
|
|
|
+ line-height: 32rpx;
|
|
|
+ color: #dddddd;
|
|
|
+ text-decoration: line-through;
|
|
|
+ }
|
|
|
+
|
|
|
+ .right {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ text {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #ffffff;
|
|
|
+ }
|
|
|
+
|
|
|
+ .time {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #ffffff;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-top: 6rpx;
|
|
|
+
|
|
|
+ text {
|
|
|
+ width: 40rpx;
|
|
|
+ height: 40rpx;
|
|
|
+ background: #ffffff;
|
|
|
+ border-radius: 4rpx;
|
|
|
+ color: #ff2775;
|
|
|
+ font-size: 24rpx;
|
|
|
+ line-height: 40rpx;
|
|
|
+ text-align: center;
|
|
|
+ margin: 0 4rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .main-container {
|
|
|
+ background: #ffffff;
|
|
|
+ padding: 20rpx 20rpx 0;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ font-size: 32rpx;
|
|
|
+ color: #333333;
|
|
|
+ line-height: 40rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+
|
|
|
+ .des {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #999999;
|
|
|
+ line-height: 28rpx;
|
|
|
+ margin-top: 8rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .stock {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: flex-end;
|
|
|
+ margin-top: 20rpx;
|
|
|
+ padding-bottom: 20rpx;
|
|
|
+
|
|
|
+ .left {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ text {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #666666;
|
|
|
+ }
|
|
|
+
|
|
|
+ .progress-box {
|
|
|
+ width: 140rpx;
|
|
|
+ border-radius: 6px;
|
|
|
+ overflow: hidden;
|
|
|
+ margin-left: 10rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .right {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #999999;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ image {
|
|
|
+ width: 20rpx;
|
|
|
+ height: 20rpx;
|
|
|
+ display: block;
|
|
|
+ margin-left: 10rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .price {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: flex-end;
|
|
|
+ // margin-top: 10rpx;
|
|
|
+ padding-bottom: 20rpx;
|
|
|
+
|
|
|
+ .left {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ }
|
|
|
+
|
|
|
+ .price-1 {
|
|
|
+ font-size: 32rpx;
|
|
|
+ color: #ff3f42;
|
|
|
+ line-height: 36rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .price-2 {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #666666;
|
|
|
+ line-height: 30rpx;
|
|
|
+ text-decoration: line-through;
|
|
|
+ }
|
|
|
+
|
|
|
+ .right {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #999999;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ image {
|
|
|
+ width: 20rpx;
|
|
|
+ height: 20rpx;
|
|
|
+ display: block;
|
|
|
+ margin-left: 10rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .bottom {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ height: 76rpx;
|
|
|
+ border-top: 1px solid #eaeaea;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #666666;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .line-container {
|
|
|
+ background: #ffffff;
|
|
|
+ margin-top: 20rpx;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ height: 88rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333333;
|
|
|
+ padding: 0 20rpx;
|
|
|
+
|
|
|
+ text {
|
|
|
+ color: #fe781f;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .detail-container {
|
|
|
+ background: #ffffff;
|
|
|
+ margin-top: 20rpx;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ font-size: 32rpx;
|
|
|
+ color: #333333;
|
|
|
+ line-height: 88rpx;
|
|
|
+ text-align: center;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+
|
|
|
+ .content {
|
|
|
+ image {
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .evaluate-container {
|
|
|
+ background: #ffffff;
|
|
|
+ margin-top: 20rpx;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ font-size: 32rpx;
|
|
|
+ color: #333333;
|
|
|
+ line-height: 88rpx;
|
|
|
+ text-align: center;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+
|
|
|
+ .list {
|
|
|
+ display: flex;
|
|
|
+ overflow-x: scroll;
|
|
|
+ padding: 0 20rpx;
|
|
|
+
|
|
|
+ .item {
|
|
|
+ width: 650rpx;
|
|
|
+ padding-right: 30rpx;
|
|
|
+ flex-shrink: 0;
|
|
|
+
|
|
|
+ &:last-child {
|
|
|
+ padding-right: 20rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.onlyOne {
|
|
|
+ width: 710rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .top {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .user {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ image {
|
|
|
+ width: 80rpx;
|
|
|
+ height: 80rpx;
|
|
|
+ display: block;
|
|
|
+ border-radius: 50%;
|
|
|
+ margin-right: 20rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .name {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333333;
|
|
|
+ width: 250rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .date {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #999999;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .rate {
|
|
|
+ margin-top: 14rpx;
|
|
|
+
|
|
|
+ .it {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #666666;
|
|
|
+ margin-top: 5rpx;
|
|
|
+
|
|
|
+ &>text {
|
|
|
+ margin-right: 10rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .tags {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+
|
|
|
+ .it {
|
|
|
+ line-height: 44rpx;
|
|
|
+ padding: 0 15rpx;
|
|
|
+ border: 1px solid #eaeaea;
|
|
|
+ border-radius: 44rpx;
|
|
|
+ font-size: 24rpx;
|
|
|
+ margin-right: 14rpx;
|
|
|
+ margin-top: 14rpx;
|
|
|
+ color: #666666;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .content {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333333;
|
|
|
+ margin-top: 14rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .images {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ margin-top: 14rpx;
|
|
|
+
|
|
|
+ image {
|
|
|
+ width: 140rpx;
|
|
|
+ height: 140rpx;
|
|
|
+ margin-right: 20rpx;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .more {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ padding: 10rpx 0 30rpx;
|
|
|
+
|
|
|
+ .btn {
|
|
|
+ width: 220rpx;
|
|
|
+ height: 68rpx;
|
|
|
+ line-height: 68rpx;
|
|
|
+ text-align: center;
|
|
|
+ border-radius: 68rpx;
|
|
|
+ border: 1px solid #eaeaea;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #666666;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .bottom-container {
|
|
|
+ position: fixed;
|
|
|
+ bottom: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ box-sizing: border-box;
|
|
|
+ padding: 0 20rpx;
|
|
|
+ background: #ffffff;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ height: 100rpx;
|
|
|
+ border-top: 1px solid #eaeaea;
|
|
|
+
|
|
|
+ .left {
|
|
|
+ display: flex;
|
|
|
+ width: 280rpx;
|
|
|
+
|
|
|
+ .item {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ margin-right: 40rpx;
|
|
|
+ position: relative;
|
|
|
+ width: 66rpx;
|
|
|
+
|
|
|
+ &:last-child {
|
|
|
+ margin-right: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ image {
|
|
|
+ width: 40rpx;
|
|
|
+ height: 40rpx;
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
+
|
|
|
+ text {
|
|
|
+ font-size: 22rpx;
|
|
|
+ color: #333333;
|
|
|
+ margin-top: 4rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .dot {
|
|
|
+ position: absolute;
|
|
|
+ right: -4rpx;
|
|
|
+ top: -8rpx;
|
|
|
+ background: #ff3f42;
|
|
|
+ width: 32rpx;
|
|
|
+ height: 32rpx;
|
|
|
+ line-height: 32rpx;
|
|
|
+ text-align: center;
|
|
|
+ border-radius: 32rpx;
|
|
|
+ font-size: 20rpx;
|
|
|
+ color: #ffffff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .right {
|
|
|
+ display: flex;
|
|
|
+
|
|
|
+ .button {
|
|
|
+ width: 190rpx;
|
|
|
+ height: 80rpx;
|
|
|
+ line-height: 80rpx;
|
|
|
+ text-align: center;
|
|
|
+ border-radius: 80rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #ffffff;
|
|
|
+
|
|
|
+ &.cart {
|
|
|
+ background: #fe781f;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.buy {
|
|
|
+ background: #ff3f42;
|
|
|
+ margin-left: 10rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.sec {
|
|
|
+ background: linear-gradient(-90deg, #ff3f42 0%, #fe781f 100%);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .cart-container {
|
|
|
+ padding: 50rpx 20rpx 30rpx;
|
|
|
+
|
|
|
+ .main {
|
|
|
+ display: flex;
|
|
|
+ padding: 20rpx 0;
|
|
|
+ border-bottom: 1px solid #eaeaea;
|
|
|
+
|
|
|
+ image {
|
|
|
+ width: 200rpx;
|
|
|
+ height: 200rpx;
|
|
|
+ display: block;
|
|
|
+ flex-shrink: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .right {
|
|
|
+ margin-left: 26rpx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: space-between;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333333;
|
|
|
+ line-height: 36rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .price {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ }
|
|
|
+
|
|
|
+ .price-1 {
|
|
|
+ font-size: 32rpx;
|
|
|
+ color: #ff3f42;
|
|
|
+ line-height: 36rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .price-2 {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #666666;
|
|
|
+ line-height: 30rpx;
|
|
|
+ text-decoration: line-through;
|
|
|
+ }
|
|
|
+
|
|
|
+ .stock {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #999999;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .attr {
|
|
|
+ padding: 20rpx 0;
|
|
|
+ border-bottom: 1px solid #eaeaea;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333333;
|
|
|
+ }
|
|
|
+
|
|
|
+ .list {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+
|
|
|
+ .item {
|
|
|
+ margin-top: 16rpx;
|
|
|
+ padding: 10rpx 16rpx;
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #666666;
|
|
|
+ background: #f5f5f5;
|
|
|
+ border-radius: 5rpx;
|
|
|
+ margin-right: 16rpx;
|
|
|
+
|
|
|
+ &.current {
|
|
|
+ color: #ff3f42;
|
|
|
+ background: rgba($color: #ff3f42, $alpha: 0.2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .num {
|
|
|
+ padding: 20rpx 0;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333333;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .button {
|
|
|
+ text-align: center;
|
|
|
+ line-height: 74rpx;
|
|
|
+ border-radius: 74rpx;
|
|
|
+ background: linear-gradient(-90deg, #ff3f42 0%, #fe781f 100%);
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #ffffff;
|
|
|
+ margin-top: 20rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .package-container {
|
|
|
+ padding: 30rpx 20rpx;
|
|
|
+
|
|
|
+ .main {
|
|
|
+ max-height: 75vh;
|
|
|
+ overflow-y: scroll;
|
|
|
+
|
|
|
+ .group {
|
|
|
+ border-bottom: 1px solid #eaeaea;
|
|
|
+
|
|
|
+ &:last-child {
|
|
|
+ border: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .title {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #ff3f42;
|
|
|
+ line-height: 28rpx;
|
|
|
+ margin: 20rpx 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .goods-list {
|
|
|
+ .item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ background: #ffffff;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+
|
|
|
+ image {
|
|
|
+ width: 180rpx;
|
|
|
+ height: 180rpx;
|
|
|
+ display: block;
|
|
|
+ margin-right: 20rpx;
|
|
|
+ flex-shrink: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .right {
|
|
|
+ flex: 1;
|
|
|
+ height: 190rpx;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ flex-direction: column;
|
|
|
+
|
|
|
+ .name {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333333;
|
|
|
+ line-height: 36rpx;
|
|
|
+ height: 72rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .des {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #999999;
|
|
|
+ line-height: 36rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .bottom {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .price {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ }
|
|
|
+
|
|
|
+ .price-1 {
|
|
|
+ font-size: 32rpx;
|
|
|
+ color: #ff3f42;
|
|
|
+ line-height: 36rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .price-2 {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #666666;
|
|
|
+ line-height: 30rpx;
|
|
|
+ text-decoration: line-through;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .button {
|
|
|
+ text-align: center;
|
|
|
+ line-height: 74rpx;
|
|
|
+ border-radius: 74rpx;
|
|
|
+ background: linear-gradient(-90deg, #ff3f42 0%, #fe781f 100%);
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #ffffff;
|
|
|
+ margin-top: 20rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .sharelist-container {
|
|
|
+ padding: 30rpx 0;
|
|
|
+ display: flex;
|
|
|
+
|
|
|
+ button {
|
|
|
+ background: none;
|
|
|
+ border-radius: 0;
|
|
|
+
|
|
|
+ &::after {
|
|
|
+ border: none;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .item {
|
|
|
+ display: flex;
|
|
|
+ width: 50%;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ image {
|
|
|
+ width: 100rpx;
|
|
|
+ height: 100rpx;
|
|
|
+ display: block;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ text {
|
|
|
+ font-size: 28rpx;
|
|
|
+ line-height: 32rpx;
|
|
|
+ color: #333333;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .canvas-container {
|
|
|
+ position: fixed;
|
|
|
+ left: 50%;
|
|
|
+ top: 50%;
|
|
|
+ z-index: 999;
|
|
|
+ margin-left: -150px;
|
|
|
+ margin-top: -280px;
|
|
|
+
|
|
|
+ .button {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+
|
|
|
+ text {
|
|
|
+ display: block;
|
|
|
+ width: 280rpx;
|
|
|
+ height: 70rpx;
|
|
|
+ border-radius: 70rpx;
|
|
|
+ background: linear-gradient(-90deg, #ff3f42 0%, #fe781f 100%);
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #ffffff;
|
|
|
+ text-align: center;
|
|
|
+ line-height: 70rpx;
|
|
|
+ margin-top: 20rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .phone-dialog {
|
|
|
+ padding: 40rpx;
|
|
|
+ box-sizing: border-box;
|
|
|
+
|
|
|
+ .content {
|
|
|
+ margin-top: 30rpx;
|
|
|
+ margin-bottom: 30rpx;
|
|
|
+ line-height: 50rpx;
|
|
|
+
|
|
|
+ text {
|
|
|
+ color: #9d9d9d;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .btn {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ margin-top: 60rpx;
|
|
|
+
|
|
|
+ button::after {
|
|
|
+ border: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ button {
|
|
|
+ width: 180rpx;
|
|
|
+ height: 70rpx;
|
|
|
+ line-height: 70rpx;
|
|
|
+ margin: 0;
|
|
|
+ font-size: 28rpx;
|
|
|
+ margin: 0 30rpx;
|
|
|
+
|
|
|
+ &:first-child {
|
|
|
+ background: #f5f5f5;
|
|
|
+ color: #00ba5c;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+</style>
|