Browse Source

上传文件至 'packageGoods/pages'

linwenxin 4 months ago
parent
commit
59a44dd8af

+ 455 - 0
packageGoods/pages/activity.vue

@@ -0,0 +1,455 @@
+<template>
+  <view
+    class="app-container"
+    :style="
+      'background:' + (pageConfig[2] && hasData ? pageConfig[2] : '#F5F5F5')
+    "
+  >
+    <view class="banner-container" v-if="pageConfig[1]">
+      <image :src="pageConfig[1]" mode="widthFix"></image>
+    </view>
+
+    <view class="top-container">
+      <view class="tab">
+        <view
+          class="item"
+          :class="screenType === 0 ? 'current' : ''"
+          @tap="changeScreen(0)"
+          >综合</view
+        >
+        <view
+          class="item"
+          :class="screenType === 1 ? 'current' : ''"
+          @tap="changeScreen(1)"
+          >销量</view
+        >
+        <view
+          class="item"
+          :class="screenType === 2 || screenType === 3 ? 'current' : ''"
+          @tap="changeScreen(2)"
+          >价格
+          <image
+            src="@/static/icon/price_1.png"
+            v-if="screenType === 2"
+          ></image>
+          <image
+            src="@/static/icon/price_2.png"
+            v-if="screenType === 3"
+          ></image>
+          <image
+            src="@/static/icon/price_0.png"
+            v-if="screenType != 2 && screenType != 3"
+          ></image>
+        </view>
+        <view
+          class="item"
+          :class="screenType === 4 ? 'current' : ''"
+          @tap="changeScreen(4)"
+          >上架时间</view
+        >
+      </view>
+      <view class="icon">
+        <image
+          src="@/static/icon/show_1.png"
+          v-if="showType == 1"
+          @tap="showType = 2"
+        ></image>
+        <image
+          src="@/static/icon/show_2.png"
+          v-if="showType == 2"
+          @tap="showType = 1"
+        ></image>
+      </view>
+    </view>
+
+    <view class="goods-waterfall-list" v-show="showType == 1">
+      <view class="left">
+        <block v-for="(item, index) in goodsList" :key="index">
+          <view
+            class="item"
+            v-if="index % 2 == 0"
+            @tap="toGoodsDetail(item.goodsId)"
+          >
+            <view class="image">
+              <image :src="item.imgUrl" mode="aspectFill" class="img"></image>
+              <image
+                :src="item.logo"
+                mode="aspectFill"
+                class="water"
+                v-if="item.isShowWater"
+              ></image>
+            </view>
+            <view class="content">
+              <view class="title ellipsis-2">{{ item.goodsName }}</view>
+              <view class="tags" v-if="item.tags1 && item.tags1.length > 0">
+                <view class="it" v-for="(it, idx) in item.tags1" :key="idx">{{
+                  it
+                }}</view>
+              </view>
+              <view class="price">
+                <view class="price-1">¥{{ item.goodsPrice | numToFixed }}</view>
+                <view class="price-2"
+                  >¥{{ item.orgGoodsPrice | numToFixed }}</view
+                >
+              </view>
+              <view class="tags2" v-if="item.tags2 && item.tags2.length > 0">
+                <view class="it" v-for="(it, idx) in item.tags2" :key="idx">{{
+                  it
+                }}</view>
+              </view>
+              <view class="text">销量:{{ item.soldNum }}</view>
+            </view>
+          </view>
+        </block>
+      </view>
+      <view class="right">
+        <block v-for="(item, index) in goodsList" :key="index">
+          <view
+            class="item"
+            v-if="index % 2 == 1"
+            @tap="toGoodsDetail(item.goodsId)"
+          >
+            <view class="image">
+              <image :src="item.imgUrl" mode="aspectFill" class="img"></image>
+              <image
+                :src="item.logo"
+                mode="aspectFill"
+                class="water"
+                v-if="item.isShowWater"
+              ></image>
+            </view>
+            <view class="content">
+              <view class="title ellipsis-2">{{ item.goodsName }}</view>
+              <view class="tags" v-if="item.tags1 && item.tags1.length > 0">
+                <view class="it" v-for="(it, idx) in item.tags1" :key="idx">{{
+                  it
+                }}</view>
+              </view>
+              <view class="price">
+                <view class="price-1">¥{{ item.goodsPrice | numToFixed }}</view>
+                <view class="price-2"
+                  >¥{{ item.orgGoodsPrice | numToFixed }}</view
+                >
+              </view>
+              <view class="tags2" v-if="item.tags2 && item.tags2.length > 0">
+                <view class="it" v-for="(it, idx) in item.tags2" :key="idx">{{
+                  it
+                }}</view>
+              </view>
+              <view class="text">销量:{{ item.soldNum }}</view>
+            </view>
+          </view>
+        </block>
+      </view>
+    </view>
+
+    <view class="goods-row-list" v-show="showType == 2">
+      <block v-for="(item, index) in goodsList" :key="index">
+        <view class="item" @tap="toGoodsDetail(item.goodsId)">
+          <view class="image">
+            <image :src="item.imgUrl" mode="aspectFill" class="img"></image>
+            <image
+              :src="item.logo"
+              mode="aspectFill"
+              class="water"
+              v-if="item.isShowWater"
+            ></image>
+          </view>
+          <view class="right">
+            <view>
+              <view class="title ellipsis-2">{{ item.goodsName }}</view>
+              <view class="tags" v-if="item.tags1 && item.tags1.length > 0">
+                <view class="it" v-for="(it, idx) in item.tags1" :key="idx">{{
+                  it
+                }}</view>
+              </view>
+            </view>
+            <view>
+              <view class="bottom">
+                <view class="price">
+                  <view class="price-1"
+                    >¥{{ item.goodsPrice | numToFixed }}</view
+                  >
+                  <view class="price-2"
+                    >¥{{ item.orgGoodsPrice | numToFixed }}</view
+                  >
+                </view>
+                <view class="text">销量:{{ item.soldNum }}</view>
+              </view>
+            </view>
+          </view>
+        </view>
+      </block>
+    </view>
+
+    <no-data v-if="!goodsList.length" :showText="'暂无商品'"></no-data>
+    <loading-text
+      v-if="goodsList.length"
+      :loading="loading"
+      :noMore="noMore"
+    ></loading-text>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      type: null,
+      screenType: '',
+      goodsList: [],
+      pageNum: 1,
+      pageSize: 8,
+      noMore: false,
+      loading: false,
+      showType: 1,
+      hasData: false,
+    };
+  },
+
+  computed: {
+    pageConfig() {
+      const templateInfo = uni.getStorageSync('templateInfo');
+      const MAP = {
+        2: [
+          '首页弹窗',
+          templateInfo.popupHeadImage,
+          templateInfo.popupBackgroundColor,
+        ],
+        3: [
+          '活动专区1',
+          templateInfo.active1HeadImage,
+          templateInfo.active1BackgroundColor,
+        ],
+        4: [
+          '活动专区2左侧',
+          templateInfo.active2LeftHeadImage,
+          templateInfo.active2LeftBackgroundColor,
+        ],
+        5: [
+          '活动专区2右侧',
+          templateInfo.active2RightHeadImage,
+          templateInfo.active2RightBackgroundColor,
+        ],
+        6: [
+          '专场专区1',
+          templateInfo.only1HeadImage,
+          templateInfo.only1BackgroundColor,
+        ],
+        7: [
+          '专场专区2',
+          templateInfo.only2HeadImage,
+          templateInfo.only2BackgroundColor,
+        ],
+        8: [
+          '专场专区3',
+          templateInfo.only3HeadImage,
+          templateInfo.only3BackgroundColor,
+        ],
+        9: [
+          '专场专区4',
+          templateInfo.only4HeadImage,
+          templateInfo.only4BackgroundColor,
+        ],
+        10: [
+          '专题精选1',
+          templateInfo.topics1HeadImage,
+          templateInfo.topics1BackgroundColor,
+        ],
+        11: [
+          '专题精选2',
+          templateInfo.topics2HeadImage,
+          templateInfo.topics2BackgroundColor,
+        ],
+        12: [
+          '专题精选3',
+          templateInfo.topics3HeadImage,
+          templateInfo.topics3BackgroundColor,
+        ],
+        13: [
+          '底部广告图',
+          templateInfo.bottomBannerHeadImage,
+          templateInfo.bottomBannerBackgroundColor,
+        ],
+      };
+      console.log(this.type ? MAP[this.type] : ['', '', '']);
+      return this.type ? MAP[this.type] : ['', '', ''];
+    },
+    cuStyle() {
+      return `height:${this.CustomBar - this.StatusBar}px; padding-top:${
+        this.StatusBar
+      }px;`;
+    },
+  },
+
+  onShow() {
+    uni.$on('hanbleShare', () => {});
+  },
+
+  onHide() {
+    uni.$off('hanbleShare');
+  },
+
+  onLoad({ type }) {
+    // uni.setNavigationBarTitle({
+    //   title: cname
+    // })
+    this.type = type;
+    this.getGoodsList();
+  },
+
+  // 下拉刷新
+  onPullDownRefresh() {
+    this.pageNum = 1;
+    this.getGoodsList();
+  },
+
+  // 上拉加载
+  onReachBottom() {
+    this.getGoodsList(1);
+  },
+
+  methods: {
+    // 获取商品列表
+    getGoodsList(loadMore) {
+      if (this.noMore && loadMore) return;
+      this.noMore = false;
+      if (!loadMore) {
+        this.pageNum = 1;
+      } else {
+        this.loading = true;
+      }
+      this.$axios({
+        url: '/renovation/goods/list',
+        method: 'get',
+        params: {
+          pageNo: this.pageNum,
+          pageSize: this.pageSize,
+          type: this.type,
+          objId: uni.getStorageSync('templateInfo').companyWechatTemplateId,
+          sort: this.screenType,
+        },
+        isLoading: !loadMore,
+      }).then((res) => {
+        res.data.records.forEach((item) => {
+          if (item.logo && item.logoStartTime) {
+            item.isShowWater = this.$compareTime(
+              item.logoStartTime,
+              item.logoEndTime
+            );
+          } else {
+            item.isShowWater = false;
+          }
+        });
+        let _list = res.data.records;
+        let pageTotal = res.data.pages;
+        if (this.pageNum >= pageTotal) {
+          this.noMore = true;
+        }
+        if (_list.length) {
+          this.pageNum += 1;
+        }
+        if (loadMore) {
+          this.goodsList = this.goodsList.concat(_list);
+          this.loading = false;
+        } else {
+          this.goodsList = _list;
+        }
+        if (this.goodsList.length > 0) {
+          this.hasData = true;
+        } else {
+          this.hasData = false;
+        }
+
+        uni.stopPullDownRefresh();
+      });
+    },
+
+    // 切换筛选类型
+    changeScreen(type) {
+      if (type != 2) {
+        if (this.screenType !== type) {
+          this.screenType = type;
+        } else {
+          this.screenType = '';
+        }
+      } else {
+        if (this.screenType != 2 && this.screenType != 3) {
+          this.screenType = 2;
+        } else if (this.screenType == 2) {
+          this.screenType = 3;
+        } else {
+          this.screenType = '';
+        }
+      }
+      this.pageNum = 1;
+      this.getGoodsList();
+    },
+
+    toGoodsDetail(id) {
+      uni.navigateTo({
+        url: '/packageGoods/pages/detail?id=' + id,
+      });
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.app-container {
+  box-sizing: border-box;
+  &.noBg {
+    background: #f4f2f2 !important;
+  }
+}
+.banner-container {
+  image {
+    width: 100%;
+    display: block;
+  }
+}
+.top-container {
+  position: sticky;
+  top: 0;
+  left: 0;
+  z-index: 99;
+  width: 100%;
+  background: #ffffff;
+  display: flex;
+  padding: 0 20rpx;
+  align-items: center;
+  box-sizing: border-box;
+  .tab {
+    flex: 1;
+    display: flex;
+    padding: 0 80rpx 0 30rpx;
+    box-sizing: border-box;
+    justify-content: space-between;
+    .item {
+      height: 88rpx;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      font-size: 30rpx;
+      color: #666666;
+      &.current {
+        color: #ff3f42;
+      }
+      image {
+        width: 18rpx;
+        height: 30rpx;
+        display: block;
+        margin-left: 10rpx;
+      }
+    }
+  }
+  .icon {
+    padding-right: 10rpx;
+    image {
+      width: 36rpx;
+      height: 36rpx;
+      display: block;
+    }
+  }
+}
+</style>

+ 233 - 0
packageGoods/pages/coupon.vue

@@ -0,0 +1,233 @@
+<template>
+	<view class="app-container">
+		<view class="list-container">
+			<block v-for="(item, index) in couponList" :key='index'>
+				<view class="item" @tap="chooseCoupon(index, item.useableFlag)">
+					<view class="bg">
+						<image src="@/static/mine/coupon/bg_0.png" v-if="!item.useableFlag"></image>
+						<image src="@/static/mine/coupon/bg_1.png" v-if="item.useableFlag"></image>
+					</view>
+					<view class="content">
+						<view class="left">
+							<view class="price">{{item.couponValue}}<text>元</text></view>
+							<view class="text" v-if="item.couponType == 'SATISFY'">满{{item.orderAmount}}可用</view>
+						</view>
+						<view class="right">
+							<view class="main">
+								<view class="row1 ellipsis-2">{{item.couponName}}</view>
+								<view class="row2">
+									<view class="date">
+										<view>使用时间:</view>
+										<view>{{item.activeStartTime | dateToYYmmdd2}}-{{item.activeEndTime | dateToYYmmdd2}}</view>
+									</view>
+									<view class="button2" v-if="!item.useableFlag">不可用</view>
+									<view class="button" v-if="item.useableFlag">使用</view>
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</block>
+		</view>
+		<no-data v-if="!couponList.length" :showText="'暂无可用优惠券'"></no-data>
+		
+		<view class="bottom-container">
+			<view class="button" @tap="noUseCoupon">不使用优惠券</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {mapState} from 'vuex';
+	import EventBus from '@/utils/eventbus.js';
+	
+	export default {
+		data() {
+			return {
+				couponList: [],
+				orderAmount: 0,
+				goodsIds: [],
+			}
+		},
+		
+		computed:{
+			...mapState(['userInfo', 'isLogin', 'userId'])
+		},
+		
+		onLoad({orderAmount, goodsIds}) {
+			this.orderAmount = orderAmount;
+			this.goodsIds = JSON.parse(goodsIds);
+			this.getCouponList();
+		},
+		
+		methods: {
+			getCouponList() {
+				this.$axios({
+					url: '/coupon/list/useable',
+					method: 'get',
+					params: {
+						orderAmount: this.orderAmount,
+						goodsSpecIds: this.goodsIds.join(','),
+						userId: this.userId
+					},
+					isLoading: 1
+				}).then(res => {
+					this.couponList = res.data;
+				})
+			},
+			
+			// 选择优惠券
+			chooseCoupon(index, canUse) {
+				if(!canUse) {
+					return this.$toast('该优惠券不可用');
+				}
+				EventBus.$emit('chooseCoupon', this.couponList[index]);
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			
+			// 不使用优惠券
+			noUseCoupon() {
+				uni.$emit('chooseCoupon', '');
+				uni.navigateBack({
+					delta: 1
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.app-container {
+		background: #F4F2F2;
+		padding: 20rpx 20rpx 120rpx;
+		box-sizing: border-box;
+	}
+	.list-container {
+		.item {
+			position: relative;
+			margin-bottom: 20rpx;
+			.bg {
+				image {
+					width: 710rpx;
+					height: 160rpx;
+					display: block;
+				}
+			}
+			.content {
+				position: absolute;
+				left: 0;
+				top: 0;
+				width: 710rpx;
+				height: 160rpx;
+				display: flex;
+				align-items: center;
+				.left {
+					width: 240rpx;
+					display: flex;
+					align-items: center;
+					justify-content: center;
+					flex-direction: column;
+					.price {
+						font-size: 60rpx;
+						color: #FFFFFF;
+						text {
+							font-size: 28rpx;
+							margin-top: 20rpx;
+						}
+					}
+					.text {
+						color: #FFFFFF;
+						font-size: 28rpx;
+					}
+				}
+				.right {
+					display: flex;
+					align-items: center;
+					justify-content: space-between;
+					padding: 0 20rpx;
+					width: 470rpx;
+					height: 160rpx;
+					box-sizing: border-box;
+					.main {
+						width: 430rpx;
+						height: 160rpx;
+						padding: 16rpx 0;
+						box-sizing: border-box;
+						display: flex;
+						flex-direction: column;
+						justify-content: space-between;
+						.row1 {
+							font-size: 28rpx;
+							line-height: 32rpx;
+						}
+						.row2 {
+							display: flex;
+							justify-content: space-between;
+							align-items: center;
+							.date {
+								font-size: 24rpx;
+								color: #999999;
+								line-height: 28rpx;
+							}
+							.button {
+								width: 100rpx;
+								height: 40rpx;
+								text-align: center;
+								line-height: 40rpx;
+								border-radius: 40rpx;
+								border: 1px solid #FF3F42;
+								font-size: 24rpx;
+								color: #FF3F42;
+								flex-shrink: 0;
+							}
+							.button2 {
+								width: 100rpx;
+								height: 40rpx;
+								text-align: center;
+								line-height: 40rpx;
+								border-radius: 40rpx;
+								border: 1px solid #b0b0b0;
+								font-size: 24rpx;
+								color: #999999;
+								flex-shrink: 0;
+							}
+						}
+					}
+					.tag {
+						position: absolute;
+						right: 20rpx;
+						top: 10rpx;
+						image {
+							width: 80rpx;
+							height: 80rpx;
+						}
+					}
+				}
+			}
+		}
+	}
+	.bottom-container {
+		position: fixed;
+		bottom: 0;
+		left: 0;
+		width: 100%;
+		padding: 0 20rpx;
+		box-sizing: border-box;
+		background: #FFFFFF;
+		display: flex;
+		align-items: center;
+		height: 100rpx;
+		.button {
+			width: 100%;
+			height: 68rpx;
+			line-height: 68rpx;
+			border-radius: 68rpx;
+			text-align: center;
+			font-size: 28rpx;
+			color: #666666;
+			border: 1px solid #B0B0B0;
+		}
+	}
+</style>

+ 2075 - 0
packageGoods/pages/detail.vue

@@ -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>

+ 365 - 0
packageGoods/pages/evaluate.vue

@@ -0,0 +1,365 @@
+<template>
+  <view class="app-container">
+    <view class="top-container" v-if="dataList.length">
+      <view class="top">
+        <view class="left">
+          <text>综合评分</text
+          ><uni-rate
+            :size="18"
+            :margin="4"
+            :value="5"
+            color="#fff"
+            active-color="#FE781F"
+            :readonly="true"
+          />
+        </view>
+        <view class="right">{{ countDetail.goodRate }}%好评</view>
+      </view>
+      <view class="tabs">
+        <view
+          class="item"
+          :class="currentTab === '' ? 'current' : ''"
+          @tap="changeTabs('')"
+          >全部</view
+        >
+        <block v-for="(item, index) in countDetail.tagCountList" :key="index">
+          <view
+            class="item"
+            :class="currentTab === item.tag ? 'current' : ''"
+            @tap="changeTabs(item.tag)"
+            >{{ item.tag }}({{ item.total }})</view
+          >
+        </block>
+      </view>
+    </view>
+
+    <view class="list-container">
+      <view class="item" v-for="(item, index) in dataList" :key="index">
+        <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" :key="idx">{{
+            it
+          }}</view>
+        </view>
+        <!-- <view class="tagss">
+					<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"
+            :key="idx"
+            :src="it"
+            @tap="previewEvaluateImage(it, item.imgs)"
+          ></image>
+        </view>
+      </view>
+    </view>
+    <no-data v-if="!dataList.length" :showText="'暂无记录'"></no-data>
+    <loading-text
+      v-if="dataList.length"
+      :loading="loading"
+      :noMore="noMore"
+    ></loading-text>
+  </view>
+</template>
+
+<script>
+import { mapState } from 'vuex';
+
+export default {
+  data() {
+    return {
+      imageUrl: this.$imageUrl,
+      configInfo: uni.getStorageSync('configInfo'),
+      goodsId: null,
+      countDetail: {},
+      dataList: [],
+      total: 0,
+      pageNum: 1,
+      pageSize: 10,
+      noMore: false,
+      loading: false,
+      currentTab: '',
+    };
+  },
+
+  computed: {
+    ...mapState(['userInfo', 'isLogin', 'userId']),
+  },
+
+  onLoad({ goodsId }) {
+    this.goodsId = goodsId;
+    this.getList();
+    this.getCount();
+  },
+
+  // 下拉刷新
+  onPullDownRefresh() {
+    this.pageNum = 1;
+    this.getList();
+    this.getCount();
+  },
+
+  // 上拉加载
+  onReachBottom() {
+    this.getList(1);
+  },
+
+  methods: {
+    // 获取统计
+    getCount() {
+      this.$axios({
+        url: '/order/comment/goods/count',
+        method: 'get',
+        params: {
+          goodsId: this.goodsId,
+        },
+      }).then((res) => {
+        this.countDetail = res.data;
+      });
+    },
+
+    // 获取列表
+    getList(loadMore) {
+      if (this.noMore && loadMore) return;
+      this.noMore = false;
+      if (!loadMore) {
+        this.pageNum = 1;
+      } else {
+        this.loading = true;
+      }
+      this.$axios({
+        url: '/order/comment/goods',
+        method: 'get',
+        params: {
+          pageNo: this.pageNum,
+          pageSize: this.pageSize,
+          goodsId: this.goodsId,
+          tag: this.currentTab,
+        },
+        isLoading: !loadMore,
+      }).then((res) => {
+        let _list = res.data.records;
+        let pageTotal = res.data.pages;
+        if (this.pageNum >= pageTotal) {
+          this.noMore = true;
+        }
+        if (_list.length) {
+          this.pageNum += 1;
+        }
+        if (loadMore) {
+          this.dataList = this.dataList.concat(_list);
+          this.loading = false;
+        } else {
+          this.dataList = _list;
+        }
+        this.total = res.data.total || 0;
+
+        uni.stopPullDownRefresh();
+      });
+    },
+
+    changeTabs(tag) {
+      this.currentTab = tag;
+      this.pageNum = 1;
+      this.getList();
+    },
+
+    // 预览评价图片
+    previewEvaluateImage(url, imgs) {
+      uni.previewImage({
+        urls: imgs,
+        current: url,
+      });
+    },
+  },
+};
+</script>
+
+<style lang="scss">
+.app-container {
+  background: #f4f2f2;
+  box-sizing: border-box;
+}
+.top-container {
+  background: #ffffff;
+  padding: 20rpx;
+  margin-bottom: 20rpx;
+  .top {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    .left {
+      display: flex;
+      align-items: center;
+      font-size: 28rpx;
+      color: #333333;
+      margin-top: 5rpx;
+      & > text {
+        margin-right: 14rpx;
+      }
+    }
+    .right {
+      font-size: 24rpx;
+      color: #666666;
+    }
+  }
+  .tabs {
+    display: flex;
+    overflow-x: scroll;
+    .item {
+      flex-shrink: 0;
+      height: 52rpx;
+      line-height: 52rpx;
+      border-radius: 52rpx;
+      padding: 0 25rpx;
+      border: 1px solid #eaeaea;
+      color: #333333;
+      font-size: 24rpx;
+      margin-right: 16rpx;
+      margin-top: 16rpx;
+      &.current {
+        border: 1px solid #fe781f;
+        background: #fe781f;
+        color: #ffffff;
+      }
+    }
+  }
+}
+.list-container {
+  padding: 0 20rpx;
+  background: #ffffff;
+  .item {
+    padding: 20rpx 0;
+    border-bottom: 1px solid #eaeaea;
+    &:last-child {
+      border-bottom: none;
+    }
+    .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: 300rpx;
+        }
+      }
+      .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;
+      }
+    }
+    .tagss {
+      display: flex;
+      flex-wrap: wrap;
+      margin-top: 14rpx;
+      .it {
+        font-size: 24rpx;
+        color: #fe781f;
+        margin-right: 6rpx;
+      }
+    }
+    .content {
+      font-size: 28rpx;
+      color: #333333;
+      margin-top: 14rpx;
+    }
+    .images {
+      display: flex;
+      flex-wrap: wrap;
+      image {
+        width: 140rpx;
+        height: 140rpx;
+        margin-right: 20rpx;
+        margin-top: 20rpx;
+      }
+    }
+  }
+}
+</style>

+ 310 - 0
packageGoods/pages/list.vue

@@ -0,0 +1,310 @@
+<template>
+  <view class="app-container">
+    <view class="top-container">
+      <view
+        class="item"
+        :class="screenType === 0 ? 'current' : ''"
+        @tap="changeScreen(0)"
+        >综合</view
+      >
+      <view
+        class="item"
+        :class="screenType === 1 ? 'current' : ''"
+        @tap="changeScreen(1)"
+        >销量</view
+      >
+      <view
+        class="item"
+        :class="screenType === 2 || screenType === 3 ? 'current' : ''"
+        @tap="changeScreen(2)"
+        >价格
+        <image src="@/static/icon/price_1.png" v-if="screenType === 2"></image>
+        <image src="@/static/icon/price_2.png" v-if="screenType === 3"></image>
+        <image
+          src="@/static/icon/price_0.png"
+          v-if="screenType != 2 && screenType != 3"
+        ></image>
+      </view>
+      <view
+        class="item"
+        :class="screenType === 4 ? 'current' : ''"
+        @tap="changeScreen(4)"
+        >上新</view
+      >
+    </view>
+    <view class="list-container">
+      <block v-for="(item, index) in goodsList" :key="index">
+        <view class="item" @tap="toGoodsDetail(item.goodsId)">
+          <view class="image">
+            <image :src="item.imgUrl" mode="aspectFill" class="img"></image>
+            <image
+              :src="item.logo"
+              mode="aspectFill"
+              class="water"
+              v-if="item.isShowWater"
+            ></image>
+          </view>
+          <view class="content">
+            <view class="title ellipsis-2">{{ item.goodsName }}</view>
+            <view class="bottom">
+              <view class="price">
+                <view class="price-1">¥{{ item.goodsPrice | numToFixed }}</view>
+                <view class="price-2"
+                  >¥{{ item.orgGoodsPrice | numToFixed }}</view
+                >
+              </view>
+              <view class="btn"
+                ><image src="@/static/icon/cart.png" mode="aspectFill"></image
+              ></view>
+            </view>
+          </view>
+        </view>
+      </block>
+    </view>
+    <no-data v-if="!goodsList.length" :showText="'暂无商品'"></no-data>
+    <loading-text
+      v-if="goodsList.length"
+      :loading="loading"
+      :noMore="noMore"
+    ></loading-text>
+
+    <!-- <drag-button :isDock="true" :customBar="true" ref="dragButton"></drag-button> -->
+  </view>
+</template>
+
+<script>
+// import dragButton from '@/components/drag-button.vue';
+
+export default {
+  // components:{
+  // 	dragButton
+  // },
+  data() {
+    return {
+      cid: '',
+      screenType: '',
+      goodsList: [],
+      pageNum: 1,
+      pageSize: 8,
+      noMore: false,
+      loading: false,
+    };
+  },
+
+  onShow() {
+    // this.$refs.dragButton.init();
+  },
+
+  onLoad({ cid, cname }) {
+    uni.setNavigationBarTitle({
+      title: cname,
+    });
+    this.cid = cid;
+    this.getGoodsList();
+  },
+
+  // 下拉刷新
+  onPullDownRefresh() {
+    this.pageNum = 1;
+    this.getGoodsList();
+  },
+
+  // 上拉加载
+  onReachBottom() {
+    this.getGoodsList(1);
+  },
+
+  methods: {
+    // 切换筛选类型
+    changeScreen(type) {
+      if (type != 2) {
+        if (this.screenType !== type) {
+          this.screenType = type;
+        } else {
+          this.screenType = '';
+        }
+      } else {
+        if (this.screenType != 2 && this.screenType != 3) {
+          this.screenType = 2;
+        } else if (this.screenType == 2) {
+          this.screenType = 3;
+        } else {
+          this.screenType = '';
+        }
+      }
+      this.pageNum = 1;
+      this.getGoodsList();
+    },
+
+    // 获取商品列表
+    getGoodsList(loadMore) {
+      if (this.noMore && loadMore) return;
+      this.noMore = false;
+      if (!loadMore) {
+        this.pageNum = 1;
+      } else {
+        this.loading = true;
+      }
+      this.$axios({
+        url: '/goods/list/sort/page',
+        method: 'get',
+        params: {
+          pageNum: this.pageNum,
+          pageSize: this.pageSize,
+          categoryId: this.cid,
+          sort: this.screenType,
+        },
+        isLoading: !loadMore,
+      }).then((res) => {
+        res.data.records.forEach((item) => {
+          if (item.logo && item.logoStartTime) {
+            item.isShowWater = this.$compareTime(
+              item.logoStartTime,
+              item.logoEndTime
+            );
+          } else {
+            item.isShowWater = false;
+          }
+        });
+        let _list = res.data.records;
+        let pageTotal = res.data.pages;
+        if (this.pageNum >= pageTotal) {
+          this.noMore = true;
+        }
+        if (_list.length) {
+          this.pageNum += 1;
+        }
+        if (loadMore) {
+          this.goodsList = this.goodsList.concat(_list);
+          this.loading = false;
+        } else {
+          this.goodsList = _list;
+        }
+
+        uni.stopPullDownRefresh();
+      });
+    },
+
+    toGoodsDetail(id) {
+      uni.navigateTo({
+        url: '/packageGoods/pages/detail?id=' + id,
+      });
+    },
+  },
+};
+</script>
+
+<style lang="scss">
+.app-container {
+  background: #f4f2f2;
+  padding-top: 88rpx;
+  box-sizing: border-box;
+}
+.top-container {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  background: #ffffff;
+  display: flex;
+  .item {
+    width: 25%;
+    height: 88rpx;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 30rpx;
+    color: #666666;
+    &.current {
+      color: #ff3f42;
+    }
+    image {
+      width: 20rpx;
+      height: 30rpx;
+      display: block;
+      margin-left: 10rpx;
+    }
+  }
+}
+.list-container {
+  display: flex;
+  flex-wrap: wrap;
+  padding: 20rpx;
+  .item {
+    width: 348rpx;
+    background: #ffffff;
+    margin-right: 14rpx;
+    margin-bottom: 20rpx;
+    border-radius: 20rpx;
+    overflow: hidden;
+    &:nth-child(2n) {
+      margin-right: 0;
+    }
+    .image {
+      width: 348rpx;
+      height: 348rpx;
+      flex-shrink: 0;
+      position: relative;
+      .img {
+        width: 348rpx;
+        height: 348rpx;
+        display: block;
+      }
+      .water {
+        width: 348rpx;
+        height: 348rpx;
+        display: block;
+        position: absolute;
+        left: 0;
+        top: 0;
+        z-index: 1;
+      }
+    }
+    .content {
+      padding: 15rpx 20rpx;
+      .title {
+        font-size: 30rpx;
+        color: #333333;
+        line-height: 36rpx;
+        font-weight: 600;
+        height: 72rpx;
+      }
+      .bottom {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-top: 10rpx;
+        .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;
+        }
+        .btn {
+          width: 60rpx;
+          height: 60rpx;
+          background: #fe781f;
+          border-radius: 50%;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          image {
+            width: 41rpx;
+            height: 36rpx;
+            display: block;
+          }
+        }
+      }
+    }
+  }
+}
+</style>