mobile/pages/product/category.vue
@@ -1,5 +1,5 @@
<template>
   <view class="category-wrap"  :data-theme='theme()' :class="theme() || ''">
   <view class="category-wrap" :data-theme='theme()' :class="theme() || ''">
      <!-- #ifdef APP-PLUS -->
      <header-bar></header-bar>
      <!-- #endif -->
@@ -45,7 +45,7 @@
               </view>
            </scroll-view>
         </view>
         <!--一级分类 列表-->
         <view class="cotegory-type cotegory-type-3" v-if="show_type==40">
            <view class="category-tab">
@@ -57,10 +57,12 @@
               </scroll-view>
            </view>
            <view class="category-content pr">
               <scroll-view scroll-y="true" class="scroll-Y scroll-3" :style="'height:'+scrollviewHigh+'px;'">
               <scroll-view scroll-y="true" @scrolltolower="scrolltolowerList" class="scroll-Y scroll-3"
                  :style="'height:'+scrollviewHigh+'px;'">
                  <view class="shop_body">
                     <view class="shop_body_l_item" :class="index==productData.length-1?'noborder':''" v-for="(item,index) in productData"
                      :key="index" @click="gotoList2(item.product_id)" v-if="index_open_city==0 || (index_open_city==1 && isInArray2(city_supplier_ids,item.shop_supplier_id))">
                     <view class="shop_body_l_item" :class="index==productData.length-1?'noborder':''"
                        v-for="(item,index) in productData" :key="index" @click="gotoList2(item.product_id)"
                        v-if="index_open_city==0 || (index_open_city==1 && isInArray2(city_supplier_ids,item.shop_supplier_id))">
                        <view>
                           <image :src="item.product_image" mode=""></image>
                        </view>
@@ -68,12 +70,15 @@
                           <view class="shop_body_l_item_info_title gray3 f32">{{item.product_name}}</view>
                           <view class="d-b-c pb10">
                              <view class="shop_body_l_item_info_price">
                                 <view class="f24 shop_red">¥<text class="f32 fb">{{item.product_price}}</text></view>
                                 <view class="f24 shop_red" v-if="item.is_price_negotiable">价格面议</view>
                                 <view class="f24 shop_red" v-else>¥<text
                                       class="f32 fb">{{item.product_price}}</text></view>
                              </view>
                              <!-- 购物车操作组件 -->
                              <view class="cart-action">
                                 <!-- 多规格商品显示选择规格按钮 -->
                                 <view class="spec-select-btn" v-if="item.spec_type === 20" @click.stop="showSpecPopup(item,index)">
                                 <view class="spec-select-btn" v-if="item.spec_type === 20"
                                    @click.stop="showSpecPopup(item,index)">
                                    <text>选择规格</text>
                                    <!-- 购物车数量徽章 -->
                                    <view class="cart-badge" v-if="(item.cart && item.cart.total_num > 0)">
@@ -82,7 +87,9 @@
                                 </view>
                                 <!-- 单规格商品显示购物车操作 -->
                                 <template v-else>
                                    <view class="cart-btn-add" v-if="!item.cart.total_num || item.cart.total_num <= 0" @click.stop="addToCart(item,index)">
                                    <view class="cart-btn-add"
                                       v-if="!item.cart.total_num || item.cart.total_num <= 0"
                                       @click.stop="handleCartItemAction(item,index)">
                                       <text class="icon iconfont icon-jia"></text>
                                    </view>
                                    <view class="cart-number-controller" v-else>
@@ -100,7 +107,7 @@
                                 <view class="shop_body_l_item_info_others_sales">累计成交:{{item.product_sales}}笔</view>
                              </view> -->
                           </view>
                        </view>
                     </view>
                  </view>
@@ -109,6 +116,7 @@
                     <text class="iconfont icon-wushuju"></text>
                     <text class="cont">亲,暂无相关记录哦</text>
                  </view>
                  <uni-load-more v-else :loadingType="loadingType"></uni-load-more>
               </scroll-view>
            </view>
         </view>
@@ -140,7 +148,7 @@
      </view>
      <tabBar></tabBar>
      <request-loading :loadding='isloadding'></request-loading>
      <!-- 规格选择弹窗 -->
      <view class="spec-popup" :class="specPopupVisible ? 'visible' : ''" @touchmove.stop.prevent="">
         <view class="popup-mask" @click="closeSpecPopup"></view>
@@ -158,24 +166,22 @@
                  </view>
               </view>
            </view>
            <view class="spec-section" v-if="selectedProduct.spec_type === 20 && selectedProduct.specData">
               <view class="spec-group" v-for="(specGroup, groupIndex) in selectedProduct.specData.spec_attr" :key="groupIndex">
               <view class="spec-group" v-for="(specGroup, groupIndex) in selectedProduct.specData.spec_attr"
                  :key="groupIndex">
                  <view class="spec-group-name">{{ specGroup.group_name }}</view>
                  <view class="spec-options">
                     <view
                        class="spec-option"
                     <view class="spec-option"
                        :class="{ active: selectedSpecs[groupIndex] === specItem.item_id }"
                        v-for="(specItem, itemIndex) in specGroup.spec_items"
                        :key="itemIndex"
                        @click="selectSpec(groupIndex, specItem.item_id)"
                     >
                        v-for="(specItem, itemIndex) in specGroup.spec_items" :key="itemIndex"
                        @click="selectSpec(groupIndex, specItem.item_id)">
                        {{ specItem.spec_value }}
                     </view>
                  </view>
               </view>
            </view>
            <view class="quantity-section">
               <view class="quantity-label">数量</view>
               <view class="quantity-controller">
@@ -183,12 +189,13 @@
                     <text class="icon iconfont icon-jian"></text>
                  </view>
                  <view class="quantity-display">{{ quantity }}</view>
                  <view class="quantity-btn" :class="{ disabled: quantity >= currentStock }" @click="increaseQuantity">
                  <view class="quantity-btn" :class="{ disabled: quantity >= currentStock }"
                     @click="increaseQuantity">
                     <text class="icon iconfont icon-jia"></text>
                  </view>
               </view>
            </view>
            <view class="action-buttons">
               <button class="add-cart-btn" @click="confirmAddToCart">加入购物车</button>
            </view>
@@ -198,8 +205,11 @@
</template>
<script>
   import uniLoadMore from "@/components/uni-load-more.vue";
   export default {
      components: {},
      components: {
         uniLoadMore
      },
      data() {
         return {
            isloadding: true,
@@ -216,50 +226,64 @@
            childlist: [],
            /*当前选中的分类*/
            select_index: 0,
            productData:[],
            catename:'',
            productData: [],
            catename: '',
            /*底部加载*/
            loading: true,
            index_open_city:0,
            city_supplier_ids:[],
            /*没有更多*/
            no_more: false,
            index_open_city: 0,
            city_supplier_ids: [],
            // 购物车相关数据
            cartData: {}, // 存储各商品在购物车中的数量
            // 规格弹窗相关数据
            specPopupVisible: false,
            selectedProduct: null,
            selectedSpecs: [],
            quantity: 1
            quantity: 1,
            page: 1,
            last_page: 1,
            category_id: 0,
            params: {
               page: 1,
               category_id: 0,
               search: '',
               sortType: '',
               sortPrice: 0,
               list_rows: 10,
            },
         };
      },
      computed: {
         selectedSpecText() {
            if (!this.selectedProduct || !this.selectedProduct.specData) return '请选择规格';
            const selectedNames = this.selectedSpecs
               .map((specId, index) => {
                  const specGroup = this.selectedProduct.specData.spec_attr[index];
                  if (!specGroup) return '';
                  const selectedItem = specGroup.spec_items.find(item => item.item_id === specId);
                  return selectedItem ? selectedItem.spec_value : '';
               })
               .filter(name => name !== '');
            return selectedNames.length > 0 ? `已选: "${selectedNames.join(' ')}"` : '请选择规格';
         },
         // 根据选中的规格获取当前SKU
         currentSku() {
            if (!this.selectedProduct || !this.selectedProduct.sku || this.selectedSpecs.includes(null) || this.selectedSpecs.includes(undefined)) {
            if (!this.selectedProduct || !this.selectedProduct.sku || this.selectedSpecs.includes(null) || this
               .selectedSpecs.includes(undefined)) {
               return null;
            }
            const specSkuId = this.selectedSpecs.join('_');
            return this.selectedProduct.sku.find(sku => sku.spec_sku_id === specSkuId);
         },
         // 获取当前选中规格的价格
         currentPrice() {
            if (this.currentSku) {
@@ -267,7 +291,7 @@
            }
            return this.selectedProduct ? this.selectedProduct.product_price : '0.00';
         },
         // 获取当前选中规格的库存
         currentStock() {
            if (this.currentSku) {
@@ -275,14 +299,24 @@
            }
            return this.selectedProduct ? this.selectedProduct.product_stock : 0;
         },
         /*加载中状态*/
         loadingType() {
            if (this.isloadding) {
               return 1;
            } else {
               if (this.listData.length != 0 && this.no_more) {
                  return 2;
               } else {
                  return 0;
               }
            }
         }
      },
      mounted() {
         this.init();
         this.getData();
      },
      onShow(){
      onShow() {
         this.getData();
         this.getTabBarLinks();
      },
@@ -302,14 +336,14 @@
               }
            });
         },
         isInArray2(arr,value){
            value=parseInt(value);
             var index = arr.indexOf(value);
             if(index >= 0){
                 return true;
             }
             return false;
         isInArray2(arr, value) {
            value = parseInt(value);
            var index = arr.indexOf(value);
            if (index >= 0) {
               return true;
            }
            return false;
         },
         /*判断是否有图片*/
@@ -327,25 +361,32 @@
            _this.select_index = 0;
            var city_supplier_ids = '';
            if(uni.getStorageSync('citySupplierRes')){
               let resData=uni.getStorageSync('citySupplierRes');
               _this.city_supplier_ids=resData.supplier_ids;
            if (uni.getStorageSync('citySupplierRes')) {
               let resData = uni.getStorageSync('citySupplierRes');
               _this.city_supplier_ids = resData.supplier_ids;
               city_supplier_ids = _this.city_supplier_ids.join(",")
            }
            _this.isloadding = true;
            _this._get('product.category/index', {city_supplier_ids:city_supplier_ids}, function(res) {
            _this._get('product.category/index', {
               city_supplier_ids: city_supplier_ids
            }, function(res) {
               _this.listData = res.data.list;
               _this.show_type = res.data.template.category_style;
               if(_this.listData.length>0){
               if (_this.listData.length > 0) {
                  if (_this.listData[0].child) {
                     _this.childlist = _this.listData[0].child;
                  }
                  _this.category_id = _this.listData[0]['category_id'];
               }
               _this.catename = _this.listData[0].name;
               _this.background = res.data.background;
               _this.productData=res.data.productList.data;
               _this.index_open_city=res.data.store.index_open_city;
               _this.productData = res.data.productList.data;
               _this.index_open_city = res.data.store.index_open_city;
               _this.isloadding = false;
               _this.last_page = res.data.productList.last_page;
               if (_this.last_page <= 1) {
                  _this.no_more = true;
               }
            });
         },
@@ -358,18 +399,23 @@
         },
         /*获取商品数据*/
         getProductData(e) {
            if (this.select_index != e) {
               this.page = 1
            }
            this.select_index = e;
            this.productData=[];
            this.productData = [];
            let self = this;
            var city_supplier_ids = '';
            if(uni.getStorageSync('citySupplierRes')){
               let resData=uni.getStorageSync('citySupplierRes');
               self.city_supplier_ids=resData.supplier_ids;
            if (uni.getStorageSync('citySupplierRes')) {
               let resData = uni.getStorageSync('citySupplierRes');
               self.city_supplier_ids = resData.supplier_ids;
               city_supplier_ids = self.city_supplier_ids.join(",")
            }
            let page = 1;
            let page = self.page;;
            let list_rows = 10;
            let category_id =this.listData[e].category_id;
            let category_id = this.listData[e].category_id;
            this.category_id = category_id
            this.no_more = false;
            let search = '';
            let sortType = '';
            let sortPrice = 0;
@@ -381,11 +427,15 @@
               sortType: sortType,
               sortPrice: sortPrice,
               list_rows: list_rows,
               city_supplier_ids:city_supplier_ids
               city_supplier_ids: city_supplier_ids
            }, function(res) {
               self.isloadding = false;
               self.productData = res.data.list.data;
               self.index_open_city=res.data.store.index_open_city;
               self.last_page = res.data.list.last_page;
               self.index_open_city = res.data.store.index_open_city;
               if (self.last_page <= 1) {
                  self.no_more = true;
               }
            });
         },
         /*跳转产品列表*/
@@ -403,6 +453,25 @@
               '&search=' + search +
               '&sortPrice=' + sortPrice);
         },
         scrolltolowerList() {
            var self = this;
            if (self.page < self.last_page) {
               self.page++
               self.isloadding = true;
               var params = self.params;
               params.category_id = self.category_id;
               params.page = self.page;
               self._get('product.product/lists', params, function(res) {
                  self.isloadding = false;
                  self.productData = self.productData.concat(res.data.list.data);
                  if (self.page >= self.last_page) {
                     self.no_more = true;
                     return;
                  }
               });
            }
         },
         wxGetUserInfo: function(res) {
            if (!res.detail.iv) {
@@ -413,7 +482,7 @@
               return false;
            }
         },
         /*跳转搜索页面*/
         gotoSearch() {
            this.gotoPage('/pages/product/search/search');
@@ -428,35 +497,57 @@
               path: '/pages/product/category?' + self.getShareUrlParams()
            };
         },
         // 添加到购物车或显示规格选择
         addToCartOrShowSpec(product,index) {
         addToCartOrShowSpec(product, index) {
            if (product.spec_type === 20) {
               // 多规格商品,显示规格选择弹窗
               this.showSpecPopup(product);
            } else {
               // 单规格商品,直接添加到购物车
               this.directlyAddToCart(product,index);
               this.directlyAddToCart(product, index);
            }
         },
         // 处理购物车操作 - 价格面议商品特殊处理
         handleCartItemAction(product, index) {
            // 如果是价格面议商品,提示联系客服
            if (product.is_price_negotiable) {
               uni.showModal({
                  title: '温馨提示',
                  content: '该商品为价格面议商品,请联系客服咨询具体价格',
                  confirmText: '联系客服',
                  cancelText: '取消',
                  success: (res) => {
                     if (res.confirm) {
                        // 跳转到商品详情页联系客服
                        this.gotoList2(product.product_id);
                     }
                  }
               });
            } else {
               // 非价格面议商品,正常添加到购物车
               this.directlyAddToCart(product, index);
            }
         },
         
         // 添加到购物车(单规格商品)
         addToCart(product,index) {
            this.directlyAddToCart(product,index);
         addToCart(product, index) {
            this.directlyAddToCart(product, index);
         },
         // 直接添加到购物车(单规格商品)
         directlyAddToCart(product,index) {
         directlyAddToCart(product, index) {
            this._post('order.cart/add', {
               product_id: product.product_id,
               total_num: 1,
               spec_sku_id: 0
            }, (res) => {
               if (res.code === 1) {
                  if(!product.cart){
                     product.cart={
                        total_num:0
                  if (!product.cart) {
                     product.cart = {
                        total_num: 0
                     }
                  }
                  // 更新商品的购物车数量
@@ -470,12 +561,12 @@
               }
            });
         },
         // 显示规格选择弹窗
         showSpecPopup(product) {
            this.selectedProduct = product;
            this.quantity = 1;
            let url=''
            let url = ''
            //#ifdef H5
            if (this.isWeixin()) {
               url = window.location.href;
@@ -484,35 +575,36 @@
            // 获取商品规格数据
            this._get('product.product/detail', {
               product_id: product.product_id,
               url:url,
               url: url,
               visitcode: this.getVisitcode()
            }, (res) => {
               if (res.code === 1) {
               // 使用正确的路径获取规格数据
               let specData = res.data.detail.product_multi_spec || res.data.detail;
               this.$set(this.selectedProduct, 'specData', specData);
               // 同时设置SKU数据
               if (res.data.detail.sku) {
                  this.$set(this.selectedProduct, 'sku', res.data.detail.sku);
               }
               console.log(this.selectedSpecs);
                  // 使用正确的路径获取规格数据
                  let specData = res.data.detail.product_multi_spec || res.data.detail;
                  this.$set(this.selectedProduct, 'specData', specData);
                  // 同时设置SKU数据
                  if (res.data.detail.sku) {
                     this.$set(this.selectedProduct, 'sku', res.data.detail.sku);
                  }
                  console.log(this.selectedSpecs);
                  // 初始化选中规格数组
               if (specData && specData.spec_attr) {
                  this.selectedSpecs = specData.spec_attr.map(specGroup => {
                     return specGroup.spec_items && specGroup.spec_items.length > 0 ? specGroup.spec_items[0].item_id : null;
                  });
                  this.specPopupVisible = true;
               } else {
                  uni.showToast({
                     title: '获取商品规格失败',
                     icon: 'none'
                  });
                  return;
               }
                  if (specData && specData.spec_attr) {
                     this.selectedSpecs = specData.spec_attr.map(specGroup => {
                        return specGroup.spec_items && specGroup.spec_items.length > 0 ? specGroup
                           .spec_items[0].item_id : null;
                     });
                     this.specPopupVisible = true;
                  } else {
                     uni.showToast({
                        title: '获取商品规格失败',
                        icon: 'none'
                     });
                     return;
                  }
               } else {
                  uni.showToast({
                     title: '获取商品规格失败',
@@ -521,34 +613,34 @@
               }
            });
         },
         // 关闭规格选择弹窗
         closeSpecPopup() {
            this.specPopupVisible = false;
            this.selectedProduct = null;
            this.selectedSpecs = [];
         },
         // 选择规格
         selectSpec(groupIndex, itemId) {
            // 使用 Vue.set 确保响应式更新
            this.$set(this.selectedSpecs, groupIndex, itemId);
         },
         // 增加数量
         increaseQuantity() {
            if (this.quantity < this.currentStock) {
               this.quantity++;
            }
         },
         // 减少数量
         decreaseQuantity() {
            if (this.quantity > 1) {
               this.quantity--;
            }
         },
         // 确认添加到购物车
         confirmAddToCart() {
            // 检查是否选择了所有规格
@@ -559,30 +651,31 @@
               });
               return;
            }
            // 构造规格SKU ID
            const specSkuId = this.selectedSpecs.join('_');
            this._post('order.cart/add', {
               product_id: this.selectedProduct.product_id,
               total_num: this.quantity,
               spec_sku_id: specSkuId?specSkuId:0
               spec_sku_id: specSkuId ? specSkuId : 0
            }, (res) => {
               if (res.code === 1) {
                  // 更新商品的购物车数量
                  const product = this.productData.find(p => p.product_id === this.selectedProduct.product_id);
                  const product = this.productData.find(p => p.product_id === this.selectedProduct
                     .product_id);
                  if (product) {
                     if(!product.cart){
                        product.cart={
                           total_num:0
                     if (!product.cart) {
                        product.cart = {
                           total_num: 0
                        }
                     }
                     product.cart.total_num++;
                  }
                  // 关闭弹窗
                  this.closeSpecPopup();
                  uni.showToast({
                     title: '已添加到购物车',
                     icon: 'success'
@@ -595,9 +688,9 @@
               }
            });
         },
         // 增加购物车商品数量
         increaseCart(product,index) {
         increaseCart(product, index) {
            this._post('order.cart/add', {
               product_id: product.product_id,
               total_num: 1,
@@ -614,18 +707,18 @@
               }
            });
         },
         // 减少购物车商品数量
         decreaseCart(product,index) {
         decreaseCart(product, index) {
            if (product.cart.total_num <= 1) {
               // 如果数量为1,执行删除操作
               this._post('order.cart/delete', {
                  product_id: product.product_id,
                  cart_id: product.cart.cart_id,
                  spec_sku_id:product.product_sku.spec_sku_id
                  spec_sku_id: product.product_sku.spec_sku_id
               }, (res) => {
                  if (res.code === 1) {
                     this.productData[index].cart.total_num=0;
                     this.productData[index].cart.total_num = 0;
                  } else {
                     uni.showToast({
                        title: res.msg,
@@ -637,7 +730,7 @@
               // 否则减少数量
               this._post('order.cart/sub', {
                  product_id: product.product_id,
                  spec_sku_id:product.product_sku.spec_sku_id
                  spec_sku_id: product.product_sku.spec_sku_id
               }, (res) => {
                  if (res.code === 1) {
                     product.cart.total_num--;
@@ -800,18 +893,20 @@
      background: #ffffff;
      border-radius: 12px;
   }
   .catename{
   .catename {
      padding-top: 10rpx;
      line-height: 60rpx;
      border-bottom: 1rpx solid #D9D9D9;
   }
   .shop_body {
      width: 100%;
      background-color: #ffffff;
      padding: 0rpx 20rpx;
      box-sizing: border-box;
   }
   .shop_body_l_item {
      // width: 90%;
      // height: 250rpx;
@@ -823,16 +918,16 @@
      padding: 40rpx 0;
      box-sizing: border-box;
      border-bottom: 1rpx solid #D9D9D9;
   }
   .shop_body_l_item image {
      width: 150rpx;
      height: 150rpx;
      border-radius: 12rpx;
      background-color: rgba(0, 0, 0, 0.1);
   }
   .shop_body_l_item_info {
      // width: 70%;
      // height: 100%;
@@ -844,7 +939,7 @@
      box-sizing: border-box;
      position: relative;
   }
   .shop_body_l_item_info_title {
      display: -webkit-box;
      -webkit-box-orient: vertical;
@@ -855,23 +950,23 @@
      word-break: break-all;
      overflow: hidden;
   }
   .shop_body_l_item_info_price {
      display: flex;
      align-items: flex-end;
   }
   .shop_body_l_item_info_price view {
      margin-right: 15rpx;
   }
   .shop_body_l_item_info_others {
      // width: 100%;
      height: 30rpx;
      display: flex;
      justify-content: space-between;
   }
   .shop_body_l_item_info_others_activity {
      width: 150rpx;
      height: 30rpx;
@@ -883,11 +978,11 @@
      text-align: center;
      box-sizing: border-box;
   }
   .shop_body_l_item_info_others_sales {
      color: #333333;
   }
   .shop_body2 {
      width: 100%;
      display: flex;
@@ -895,7 +990,7 @@
      flex-wrap: wrap;
      background-color: #f2f2f2;
   }
   .shop_body_t_item {
      width: 345rpx;
      // margin: 0 2.5%;
@@ -905,17 +1000,17 @@
      background-color: white;
      border-radius: 12rpx;
   }
   .collect text {
      color: #FFFFFF;
   }
   .shop_body_t_item image {
      width: 100%;
      height: 337.5rpx;
      background-color: rgba(0, 0, 0, 0.1);
   }
   .shop_body_t_item_info {
      // height: 182.5rpx;
      display: flex;
@@ -924,7 +1019,7 @@
      padding: 20rpx;
      box-sizing: border-box;
   }
   .shop_body_t_item_info_title {
      display: -webkit-box;
      -webkit-box-orient: vertical;
@@ -936,55 +1031,56 @@
      overflow: hidden;
      margin-bottom: 30rpx;
   }
   .shop_body_t_item_info_price {
      display: flex;
      align-items: flex-end;
   }
   .shop_body_t_item_info_others {
      display: flex;
      justify-content: space-between;
      margin-bottom: 8rpx;
   }
   .shop_body_t_item_info_others_activity {}
   .shop_body_t_item_info_others_sales {
      color: #999999;
   }
   .huaxianjia {
      text-decoration: line-through;
      color: #999;
      margin-left: 5rpx;
   }
   .shop_red {
      color: #F6220C;
   }
   .inner-tab .item .icon-sanjiao2 {
      font-size: 13rpx;
   }
   .inner-tab .item .icon-sanjiao1 {
      font-size: 13rpx;
   }
   .noborder {
      border: none;
   }
   /* 购物车操作样式 */
   .cart-action {
      /* position: absolute;
      right: 0;
      bottom: 0; */
   }
   .cart-btn-add, .cart-btn-sub {
   .cart-btn-add,
   .cart-btn-sub {
      width: 48rpx;
      height: 48rpx;
      border-radius: 50%;
@@ -995,7 +1091,7 @@
      color: white;
      font-size: 24rpx;
   }
   .spec-select-btn {
      padding: 2rpx 4rpx;
      background: #ff6b6b;
@@ -1009,22 +1105,22 @@
      height: 48rpx;
      position: relative;
   }
   .cart-btn-sub {
      background: #f0f0f0;
      color: #666;
   }
   .cart-number {
      margin: 0 10rpx;
      font-size: 28rpx;
   }
   .cart-number-controller {
      display: flex;
      align-items: center;
   }
   /* 规格选择弹窗样式 */
   .spec-popup {
      position: fixed;
@@ -1037,12 +1133,12 @@
      opacity: 0;
      transition: all 0.3s ease;
   }
   .spec-popup.visible {
      visibility: visible;
      opacity: 1;
   }
   .popup-mask {
      position: absolute;
      top: 0;
@@ -1051,7 +1147,7 @@
      bottom: 0;
      background: rgba(0, 0, 0, 0.6);
   }
   .popup-content {
      position: absolute;
      bottom: 0;
@@ -1066,47 +1162,47 @@
      max-height: 80%;
      overflow-y: auto;
   }
   .spec-popup.visible .popup-content {
      transform: translateY(0);
   }
   .popup-header {
      display: flex;
      position: relative;
      padding-right: 60rpx;
      margin-bottom: 30rpx;
   }
   .popup-header image {
      width: 160rpx;
      height: 160rpx;
      border-radius: 10rpx;
   }
   .popup-header-info {
      margin-left: 20rpx;
      flex: 1;
   }
   .price {
      font-size: 36rpx;
      color: #ff6b6b;
      font-weight: bold;
   }
   .stock {
      font-size: 24rpx;
      color: #999;
      margin-top: 10rpx;
   }
   .selected-spec {
      font-size: 24rpx;
      color: #666;
      margin-top: 10rpx;
   }
   .popup-header-right {
      position: absolute;
      right: 0;
@@ -1115,7 +1211,7 @@
      align-items: center;
      gap: 20rpx;
   }
   .cart-badge {
      position: absolute;
      top: -12rpx;
@@ -1133,13 +1229,13 @@
      padding: 0 6rpx;
      z-index: 10;
   }
   .cart-count {
      color: white;
      font-size: 20rpx;
      line-height: 1;
   }
   .close-btn {
      width: 50rpx;
      height: 50rpx;
@@ -1148,26 +1244,26 @@
      justify-content: center;
      color: #999;
   }
   .spec-section {
      margin-bottom: 30rpx;
   }
   .spec-group {
      margin-bottom: 30rpx;
   }
   .spec-group-name {
      font-size: 28rpx;
      font-weight: bold;
      margin-bottom: 20rpx;
   }
   .spec-options {
      display: flex;
      flex-wrap: wrap;
   }
   .spec-option {
      padding: 10rpx 20rpx;
      border: 1rpx solid #ddd;
@@ -1176,28 +1272,28 @@
      margin-bottom: 20rpx;
      font-size: 26rpx;
   }
   .spec-option.active {
      border-color: #ff6b6b;
      color: #ff6b6b;
   }
   .quantity-section {
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-bottom: 30rpx;
   }
   .quantity-label {
      font-size: 28rpx;
   }
   .quantity-controller {
      display: flex;
      align-items: center;
   }
   .quantity-btn {
      width: 50rpx;
      height: 50rpx;
@@ -1208,22 +1304,22 @@
      justify-content: center;
      font-size: 24rpx;
   }
   .quantity-btn.disabled {
      opacity: 0.5;
   }
   .quantity-display {
      margin: 0 20rpx;
      font-size: 28rpx;
      min-width: 60rpx;
      text-align: center;
   }
   .action-buttons {
      text-align: center;
   }
   .add-cart-btn {
      width: 100%;
      height: 80rpx;