From 04102f7237efefa744090ed7c25f7b5d0807b679 Mon Sep 17 00:00:00 2001
From: quanwei <419654421@qq.com>
Date: Thu, 05 Feb 2026 18:11:57 +0800
Subject: [PATCH] 完成运营中心提现和运营中心权限管理
---
mobile/pages/product/category.vue | 820 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 755 insertions(+), 65 deletions(-)
diff --git a/mobile/pages/product/category.vue b/mobile/pages/product/category.vue
index 37f07ae..c66dea5 100644
--- a/mobile/pages/product/category.vue
+++ b/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,43 @@
<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">¥<text
+ class="f32 fb">{{item.product_price}}</text></view>
</view>
- <view class="shop_body_l_item_info_others f22">
+ <!-- 购物车操作组件 -->
+ <view class="cart-action">
+ <!-- 多规格商品显示选择规格按钮 -->
+ <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)">
+ <text class="cart-count">{{ item.cart.total_num || 0 }}</text>
+ </view>
+ </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)">
+ <text class="icon iconfont icon-jia"></text>
+ </view>
+ <view class="cart-number-controller" v-else>
+ <view class="cart-btn-sub" @click.stop="decreaseCart(item,index)">
+ <text class="icon iconfont icon-jian"></text>
+ </view>
+ <view class="cart-number">{{ item.cart.total_num }}</view>
+ <view class="cart-btn-add" @click.stop="increaseCart(item,index)">
+ <text class="icon iconfont icon-jia"></text>
+ </view>
+ </view>
+ </template>
+ </view>
+ <!-- <view class="shop_body_l_item_info_others f22">
<view class="shop_body_l_item_info_others_sales">累计成交:{{item.product_sales}}笔</view>
- </view>
+ </view> -->
</view>
+
</view>
</view>
</view>
@@ -82,6 +115,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>
@@ -113,12 +147,68 @@
</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>
+ <view class="popup-content" v-if="selectedProduct">
+ <view class="popup-header">
+ <image :src="selectedProduct.product_image" mode="aspectFit"></image>
+ <view class="popup-header-info">
+ <view class="price">¥{{ currentPrice }}</view>
+ <view class="stock">库存:{{ currentStock }}</view>
+ <view class="selected-spec">{{ selectedSpecText }}</view>
+ </view>
+ <view class="popup-header-right">
+ <view class="close-btn" @click="closeSpecPopup">
+ <text class="icon iconfont icon-guanbi"></text>
+ </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-name">{{ specGroup.group_name }}</view>
+ <view class="spec-options">
+ <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)">
+ {{ specItem.spec_value }}
+ </view>
+ </view>
+ </view>
+ </view>
+
+ <view class="quantity-section">
+ <view class="quantity-label">数量</view>
+ <view class="quantity-controller">
+ <view class="quantity-btn" :class="{ disabled: quantity <= 1 }" @click="decreaseQuantity">
+ <text class="icon iconfont icon-jian"></text>
+ </view>
+ <view class="quantity-display">{{ quantity }}</view>
+ <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>
+ </view>
+ </view>
</view>
</template>
<script>
+ import uniLoadMore from "@/components/uni-load-more.vue";
export default {
- components: {},
+ components: {
+ uniLoadMore
+ },
data() {
return {
isloadding: true,
@@ -135,19 +225,97 @@
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,
+ 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)) {
+ return null;
+ }
+
+ const specSkuId = this.selectedSpecs.join('_');
+ return this.selectedProduct.sku.find(sku => sku.spec_sku_id === specSkuId);
+ },
+
+ // 获取当前选中规格的价格
+ currentPrice() {
+ if (this.currentSku) {
+ return this.currentSku.product_price;
+ }
+ return this.selectedProduct ? this.selectedProduct.product_price : '0.00';
+ },
+
+ // 获取当前选中规格的库存
+ currentStock() {
+ if (this.currentSku) {
+ return this.currentSku.stock_num;
+ }
+ 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();
},
@@ -167,14 +335,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;
},
/*判断是否有图片*/
@@ -192,25 +360,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;
+ }
});
},
@@ -223,18 +398,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;
@@ -246,11 +426,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;
+ }
});
},
/*跳转产品列表*/
@@ -268,6 +452,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) {
@@ -278,7 +481,7 @@
return false;
}
},
-
+
/*跳转搜索页面*/
gotoSearch() {
this.gotoPage('/pages/product/search/search');
@@ -293,6 +496,231 @@
path: '/pages/product/category?' + self.getShareUrlParams()
};
},
+
+
+ // 添加到购物车或显示规格选择
+ addToCartOrShowSpec(product, index) {
+ if (product.spec_type === 20) {
+ // 多规格商品,显示规格选择弹窗
+ this.showSpecPopup(product);
+ } else {
+ // 单规格商品,直接添加到购物车
+ this.directlyAddToCart(product, index);
+ }
+ },
+
+ // 添加到购物车(单规格商品)
+ addToCart(product, index) {
+ this.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
+ }
+ }
+ // 更新商品的购物车数量
+ product.cart.total_num++;
+ this.productData[index].cart.total_num = product.cart.total_num;
+ } else {
+ uni.showToast({
+ title: res.msg,
+ icon: 'none'
+ });
+ }
+ });
+ },
+
+ // 显示规格选择弹窗
+ showSpecPopup(product) {
+ this.selectedProduct = product;
+ this.quantity = 1;
+ let url = ''
+ //#ifdef H5
+ if (this.isWeixin()) {
+ url = window.location.href;
+ }
+ //#endif
+ // 获取商品规格数据
+ this._get('product.product/detail', {
+ product_id: product.product_id,
+ 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);
+ // 初始化选中规格数组
+
+ 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: '获取商品规格失败',
+ icon: 'none'
+ });
+ }
+ });
+ },
+
+ // 关闭规格选择弹窗
+ 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() {
+ // 检查是否选择了所有规格
+ if (this.selectedSpecs.includes(null) || this.selectedSpecs.includes(undefined)) {
+ uni.showToast({
+ title: '请选择完整的商品规格',
+ icon: 'none'
+ });
+ 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
+ }, (res) => {
+ if (res.code === 1) {
+ // 更新商品的购物车数量
+ const product = this.productData.find(p => p.product_id === this.selectedProduct
+ .product_id);
+ if (product) {
+ if (!product.cart) {
+ product.cart = {
+ total_num: 0
+ }
+ }
+ product.cart.total_num++;
+ }
+
+ // 关闭弹窗
+ this.closeSpecPopup();
+
+ uni.showToast({
+ title: '已添加到购物车',
+ icon: 'success'
+ });
+ } else {
+ uni.showToast({
+ title: res.msg,
+ icon: 'none'
+ });
+ }
+ });
+ },
+
+ // 增加购物车商品数量
+ increaseCart(product, index) {
+ this._post('order.cart/add', {
+ product_id: product.product_id,
+ total_num: 1,
+ spec_sku_id: 0
+ }, (res) => {
+ if (res.code === 1) {
+ product.cart.total_num++;
+ this.productData[index].cart.total_num = product.cart.total_num;
+ } else {
+ uni.showToast({
+ title: res.msg,
+ icon: 'none'
+ });
+ }
+ });
+ },
+
+ // 减少购物车商品数量
+ 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
+ }, (res) => {
+ if (res.code === 1) {
+ this.productData[index].cart.total_num = 0;
+ } else {
+ uni.showToast({
+ title: res.msg,
+ icon: 'none'
+ });
+ }
+ });
+ } else {
+ // 否则减少数量
+ this._post('order.cart/sub', {
+ product_id: product.product_id,
+ spec_sku_id: product.product_sku.spec_sku_id
+ }, (res) => {
+ if (res.code === 1) {
+ product.cart.total_num--;
+ this.productData[index].cart.total_num = product.cart.total_num;
+ } else {
+ uni.showToast({
+ title: res.msg,
+ icon: 'none'
+ });
+ }
+ });
+ }
+ }
}
};
</script>
@@ -442,18 +870,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;
@@ -465,16 +895,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%;
@@ -484,8 +914,9 @@
flex-direction: column;
padding-left: 20rpx;
box-sizing: border-box;
+ position: relative;
}
-
+
.shop_body_l_item_info_title {
display: -webkit-box;
-webkit-box-orient: vertical;
@@ -496,23 +927,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;
@@ -524,11 +955,11 @@
text-align: center;
box-sizing: border-box;
}
-
+
.shop_body_l_item_info_others_sales {
color: #333333;
}
-
+
.shop_body2 {
width: 100%;
display: flex;
@@ -536,7 +967,7 @@
flex-wrap: wrap;
background-color: #f2f2f2;
}
-
+
.shop_body_t_item {
width: 345rpx;
// margin: 0 2.5%;
@@ -546,17 +977,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;
@@ -565,7 +996,7 @@
padding: 20rpx;
box-sizing: border-box;
}
-
+
.shop_body_t_item_info_title {
display: -webkit-box;
-webkit-box-orient: vertical;
@@ -577,44 +1008,303 @@
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 {
+ width: 48rpx;
+ height: 48rpx;
+ border-radius: 50%;
+ background: #ff6b6b;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: white;
+ font-size: 24rpx;
+ }
+
+ .spec-select-btn {
+ padding: 2rpx 4rpx;
+ background: #ff6b6b;
+ color: white;
+ border-radius: 24rpx;
+ font-size: 24rpx;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 120rpx;
+ 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;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ z-index: 1000;
+ visibility: hidden;
+ opacity: 0;
+ transition: all 0.3s ease;
+ }
+
+ .spec-popup.visible {
+ visibility: visible;
+ opacity: 1;
+ }
+
+ .popup-mask {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: rgba(0, 0, 0, 0.6);
+ }
+
+ .popup-content {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ background: white;
+ border-top-left-radius: 20rpx;
+ border-top-right-radius: 20rpx;
+ padding: 30rpx;
+ transform: translateY(100%);
+ transition: transform 0.3s ease;
+ 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;
+ top: 0;
+ display: flex;
+ align-items: center;
+ gap: 20rpx;
+ }
+
+ .cart-badge {
+ position: absolute;
+ top: -12rpx;
+ right: -12rpx;
+ background: #ff4757;
+ color: white;
+ border-radius: 50%;
+ min-width: 32rpx;
+ height: 32rpx;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 20rpx;
+ line-height: 1;
+ padding: 0 6rpx;
+ z-index: 10;
+ }
+
+ .cart-count {
+ color: white;
+ font-size: 20rpx;
+ line-height: 1;
+ }
+
+ .close-btn {
+ width: 50rpx;
+ height: 50rpx;
+ display: flex;
+ align-items: center;
+ 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;
+ border-radius: 10rpx;
+ margin-right: 20rpx;
+ 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;
+ border: 1rpx solid #ddd;
+ border-radius: 10rpx;
+ display: flex;
+ align-items: center;
+ 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;
+ background: linear-gradient(90deg, #ff6b6b, #ff8e8e);
+ border-radius: 40rpx;
+ color: white;
+ font-size: 32rpx;
+ border: none;
+ }
</style>
+</file>
\ No newline at end of file
--
Gitblit v1.9.2