绿满眶商城微信小程序-uniapp
zxl
2025-06-19 c9928dd4f6d25e2339ea1400f59ec58674a927a7
pages/commodity-square/commoditySquare.vue
New file
@@ -0,0 +1,330 @@
<template>
   <view class="container">
      <input type="text" v-show="false" v-model="flushDom" />
      <view class="commoditySquare">
         <view class="left" style="width: 310rpx;">
            <view class="commoditySquareItem" v-for="(item,index) in goodsList1"
               @click="goToGoodsInfo('goodsList1',item.id)">
               <video :src="item.goodsVideo" v-if="item.goodsVideo " v-show="item.show" :initial-time="0"
                  :controls="false" object-fit="contain" :show-play-btn="false" :show-center-play-btn="false"
                  @loadedmetadata="getvideoInfo($event,'goodsList1',index)" :ref="'video'+item.id"
                  :style="{width:item.width,height:item.height}"></video>
               <image :src="item.thumbnail" v-if="item.goodsVideo ==null  || item.goodsVideo == ''"
                  mode="aspectFill" class="goodsImg">
               </image>
               <view class="goodsInfo">
                  <view class="">{{item.goodsName}}</view>
                  <view class="priceInfo">
                     <view class="">¥{{item.price}}</view>
                     <view class="">已售: {{item.buyCount}}</view>
                  </view>
               </view>
            </view>
         </view>
         <view class="right" style="width: 310rpx;">
            <view class="commoditySquareItem" v-for="(item,index) in goodsList2"
               @click="goToGoodsInfo('goodsList2',item.id)">
               <video :src="item.goodsVideo" v-if="item.goodsVideo " v-show="item.show" :initial-time="0"
                  :controls="false" object-fit="contain" :show-play-btn="false" :show-center-play-btn="false"
                  @loadedmetadata="getvideoInfo($event,'goodsList2',index)" :ref="'video'+item.id"
                  :style="{width:item.width,height:item.height}"></video>
               <image :src="item.thumbnail" v-if="item.goodsVideo ==null || item.goodsVideo == ''"
                  mode="aspectFill" class="goodsImg">
               </image>
               <view class="goodsInfo">
                  <view class="">{{item.goodsName}}</view>
                  <view class="priceInfo">
                     <view class="">¥{{item.price}}</view>
                     <view class="">已售: {{item.buyCount}}</view>
                  </view>
               </view>
            </view>
         </view>
         <view class="openShowLeft" @click="showDrawer('showLeft')" v-if="!showLeft">
            <uni-icons type="right" size="30"></uni-icons>
         </view>
         <uni-drawer ref="showLeft" mode="left" width="120" @change="change($event,'showLeft')"
            class="navigationLeft">
            <view class="typeNavigation">
               <view class="typeNavigationItem" :class="{typeNavigationItemCheck:currentCategort ==item.id}"
                  @click="chooseCategory(item.id)" v-for="item in categoryList" :key="item.id">
                  {{item.name}}
               </view>
            </view>
         </uni-drawer>
      </view>
      <view style="display: flex;align-items: center;justify-content: center;margin-top: 20rpx;" v-if="canLoadMore">
         没有更多数据了.................</view>
      <custom-tabbar bgColor="#ffffff" selected="shop"></custom-tabbar>
   </view>
</template>
<script>
   import {
      getCategoryList,
      getGoodsList
   } from "@/api/goods.js";
   import {
      getSTSToken
   } from '@/api/common.js'
   export default {
      data() {
         return {
            //是否显示打开左侧弹窗
            showLeft: false,
            //商品导航分类
            categoryList: [],
            //当前选中的分类
            currentCategort: '',
            //显示没有数据
            canLoadMore: false,
            //最大页数
            maxPages: 0,
            //刷新dom使用
            flushDom: '',
            //查询商品需要的参数
            getGoodsParam: {
               keyword: '',
               pageSize: 12,
               pageNumber: 1,
               categoryId: null,
            },
            //商品双列显示
            goodsList1: [],
            goodsList2: [],
         }
      },
      methods: {
         confirm() {},
         // 打开窗口
         showDrawer(e) {
            this.$refs[e].open()
         },
         // 关闭窗口
         closeDrawer(e) {
            this.$refs[e].close()
         },
         // 抽屉状态发生变化触发
         change(e, type) {
            this[type] = e
         },
         getvideoInfo(e, arrName, index) {
            const wight = e.detail.width;
            const height = e.detail.height;
            this[arrName][index].width = 310 + 'rpx';
            //计算宽高比
            const videoHeight = 310 / (wight / height)
            this[arrName][index].height = Math.floor(videoHeight) + 'rpx';
            this[arrName][index].show = true;
            console.log(this[arrName][index].width, this[arrName][index].height)
            this.flushDom = new Date();
         },
         goToGoodsInfo(arrName, id) {
            const item = this[arrName].find(item => id === item.id);
            uni.navigateTo({
               url: `/pages/product/goods?id=${item.id}&goodsId=${item.goodsId}`
            });
         },
         //获取分类导航栏
         async loadCategoryList() {
            let list = await getCategoryList(0);
            this.categoryList = list.data.result
         },
         async chooseCategory(id) {
            if (this.currentCategort === id) return
            this.canLoadMore = false;
            this.currentCategort = id
            this.getGoodsParam.categoryId = id
            this.getGoodsParam.keyword = ''
            this.getGoodsParam.pageNumber = 1
            const goodsList = await getGoodsList(this.getGoodsParam);
            const sts = await getSTSToken();
            const stsUrl = sts.data.data.endpoint
            // 处理数据
            goodsList.data.result.records.forEach(item => {
               if (item.thumbnail !== '' && item.thumbnail !== null && item.thumbnail.indexOf('http') ===
                  -1) {
                  item.thumbnail = stsUrl + '/' + item.thumbnail
               }
               if (item.goodsVideo !== '' && item.goodsVideo !== null && item.goodsVideo.indexOf(
                     'http') === -1) {
                  item.goodsVideo = stsUrl + '/' + item.goodsVideo
               }
            })
            //平分给两个数组
            const middle = Math.ceil(goodsList.data.result.records.length / 2);
            this.goodsList1 = goodsList.data.result.records.slice(0, middle);
            this.goodsList2 = goodsList.data.result.records.slice(middle);
            this.maxPages = goodsList.data.result.pages
            console.log(this.maxPages)
         }
      },
      onShow() {
         this.showDrawer('showLeft')
      },
      async onLoad() {
         await this.loadCategoryList();
         this.getGoodsParam.pageNumber = 1
         this.getGoodsParam.categoryId = ""
         this.getGoodsParam.keyword = ""
         const goodsList = await getGoodsList(this.getGoodsParam);
         const sts = await getSTSToken();
         const stsUrl = sts.data.data.endpoint
         // 处理数据
         goodsList.data.result.records.forEach(item => {
            if (item.thumbnail !== '' && item.thumbnail !== null && item.thumbnail.indexOf('http') ===
               -1) {
               item.thumbnail = stsUrl + '/' + item.thumbnail
            }
            if (item.goodsVideo !== '' && item.goodsVideo !== null && item.goodsVideo.indexOf(
                  'http') === -1) {
               item.goodsVideo = stsUrl + '/' + item.goodsVideo
            }
         })
         //平分给两个数组
         const middle = Math.ceil(goodsList.data.result.records.length / 2);
         this.goodsList1 = goodsList.data.result.records.slice(0, middle);
         this.goodsList2 = goodsList.data.result.records.slice(middle);
         this.maxPages = goodsList.data.result.pages
         console.log(this.maxPages)
      },
      async onReachBottom() {
         if (this.getGoodsParam.pageNumber < this.maxPages) {
            this.getGoodsParam.pageNumber++;
            const goodsList = await getGoodsList(this.getGoodsParam);
            const sts = await getSTSToken();
            const stsUrl = sts.data.data.endpoint
            // 处理数据
            goodsList.data.result.records.forEach(item => {
               if (item.thumbnail !== '' && item.thumbnail !== null && item.thumbnail.indexOf('http') ===
                  -1) {
                  item.thumbnail = stsUrl + '/' + item.thumbnail
               }
               if (item.goodsVideo !== '' && item.goodsVideo !== null && item.goodsVideo.indexOf(
                     'http') === -1) {
                  item.goodsVideo = stsUrl + '/' + item.goodsVideo
               }
            })
            //平分给两个数组
            const middle = Math.ceil(goodsList.data.result.records.length / 2);
            this.goodsList1 = [...this.goodsList1, ...goodsList.data.result.records.slice(0, middle)];
            this.goodsList2 = [...this.goodsList2, ...goodsList.data.result.records.slice(middle)];
            this.maxPages = goodsList.data.result.pages
         } else {
            this.canLoadMore = true;
         }
      }
   }
</script>
<style lang="scss" scoped>
   .container {
      width: 750rpx;
      padding-bottom: 64rpx;
   }
   .commoditySquare {
      width: 750rpx;
      position: relative;
      box-sizing: border-box;
      display: flex;
      justify-content: space-around;
   }
   .left {
      box-sizing: border-box;
   }
   .right {
      box-sizing: border-box;
   }
   .goodsImg {
      width: 300rpx;
      height: 300rpx;
      padding-bottom: 10rpx;
   }
   .commoditySquareItem {
      // border: 1rpx solid #b6dbba;
      border-radius: 12rpx;
      box-sizing: border-box;
      padding: 0 32rpx;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
   }
   .commoditySquareItem:nth-child(n+1) {
      margin-top: 32rpx;
   }
   .openShowLeft {
      position: fixed;
      top: 30rpx;
      left: 0;
   }
   .navigationLeft {
      position: relative;
      background-color: #fcfcfc;
      // opacity: 0.5;
      box-sizing: border-box;
   }
   .scroll-view {
      /* #ifndef APP-NVUE */
      width: 100%;
      height: 100%;
      /* #endif */
      flex: 1
   }
   .priceInfo {
      margin-top: 10rpx;
      display: flex;
      justify-content: space-around;
   }
   // 处理抽屉内容滚动
   .scroll-view-box {
      flex: 1;
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
   }
   .typeNavigation {
      padding: 10rpx;
      position: relative;
   }
   .typeNavigationItem {
      padding: 24rpx;
      font-size: 28rpx;
      color: black;
      margin-top: 10rpx;
      border-radius: 12rpx;
      border: 1rpx solid gray;
   }
   .typeNavigationItemCheck {
      background-color: #42b993;
      color: #fff;
      border: 0;
   }
   .closeShowLeft {
      position: absolute;
      top: 20rpx;
      right: 0;
   }
</style>