2023-10-11 11:27:47 +08:00
|
|
|
|
<template>
|
2023-11-14 17:21:03 +08:00
|
|
|
|
<Popup
|
|
|
|
|
ref="popupRef"
|
|
|
|
|
:showCloseable="false"
|
|
|
|
|
@close="emit('close')"
|
2023-10-11 11:27:47 +08:00
|
|
|
|
>
|
|
|
|
|
<view
|
2023-11-14 17:21:03 +08:00
|
|
|
|
class="goodAttrSelect"
|
2023-10-11 11:27:47 +08:00
|
|
|
|
>
|
2023-11-14 17:21:03 +08:00
|
|
|
|
<view
|
|
|
|
|
class="goodAttrSelect-goods"
|
|
|
|
|
v-if="curAttr"
|
|
|
|
|
>
|
|
|
|
|
<uv-image
|
|
|
|
|
class="attr-image"
|
2024-02-08 21:01:37 +08:00
|
|
|
|
:src="curAttr.image || storeInfo.image"
|
2023-11-14 17:21:03 +08:00
|
|
|
|
width="150rpx"
|
|
|
|
|
height="150rpx"
|
|
|
|
|
></uv-image>
|
|
|
|
|
<view class="attr-info">
|
|
|
|
|
<view class="name">
|
|
|
|
|
{{ storeInfo.storeName }}
|
|
|
|
|
</view>
|
|
|
|
|
<view class="attr-info-bottom">
|
2024-02-08 21:01:37 +08:00
|
|
|
|
<!-- 普通SKU -->
|
|
|
|
|
<template v-if="actionType==='singleBuy' || !curAttr.campaignType">
|
|
|
|
|
<view class="price">¥{{ curAttr.price }}</view>
|
|
|
|
|
<view class="stock">库存:{{ curAttr.stock }}</view>
|
|
|
|
|
</template>
|
|
|
|
|
<!-- 活动SKU -->
|
|
|
|
|
<template v-else>
|
|
|
|
|
<view class="flex flex-ai__end">
|
|
|
|
|
<view
|
|
|
|
|
class="price-name"
|
|
|
|
|
v-if="curAttr.campaignState===1">{{ activityName }}
|
|
|
|
|
</view>
|
|
|
|
|
<view class="price primary-color">¥{{ curAttr.campaignPrice }}</view>
|
|
|
|
|
<view class="old-price">¥{{ curAttr.price }}</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="stock">库存:{{ curAttr.campaignStock }}</view>
|
|
|
|
|
</template>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<!-- 没有选中sku -->
|
|
|
|
|
<view
|
|
|
|
|
class="goodAttrSelect-goods"
|
|
|
|
|
v-else
|
|
|
|
|
>
|
|
|
|
|
<uv-image
|
|
|
|
|
class="attr-image"
|
|
|
|
|
:src="storeInfo.image"
|
|
|
|
|
width="150rpx"
|
|
|
|
|
height="150rpx"
|
|
|
|
|
></uv-image>
|
|
|
|
|
<view class="attr-info">
|
|
|
|
|
<view class="name">
|
|
|
|
|
{{ storeInfo.storeName }}
|
|
|
|
|
</view>
|
|
|
|
|
<view class="attr-info-bottom">
|
|
|
|
|
<view class="price">¥{{ storeInfo.price }}</view>
|
|
|
|
|
<view class="stock">库存:{{ storeInfo.stock }}</view>
|
2023-11-14 17:21:03 +08:00
|
|
|
|
</view>
|
|
|
|
|
</view>
|
2023-10-11 11:27:47 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<div class="line"></div>
|
2023-11-14 17:21:03 +08:00
|
|
|
|
<view
|
|
|
|
|
class="goodAttrSelect-attr row"
|
|
|
|
|
v-if="curAttr"
|
|
|
|
|
>
|
2023-10-11 11:27:47 +08:00
|
|
|
|
<view class="goodAttrSelect-attr-title">
|
|
|
|
|
数量
|
|
|
|
|
</view>
|
|
|
|
|
<view class="goodAttrSelect-attr-content">
|
2023-11-14 17:21:03 +08:00
|
|
|
|
<!-- cart number -->
|
|
|
|
|
<view
|
|
|
|
|
class="cart-num flex flex-ai__center flex-jc__sb"
|
|
|
|
|
@click.stop=""
|
|
|
|
|
>
|
|
|
|
|
<view
|
|
|
|
|
class="button"
|
2023-11-17 20:55:32 +08:00
|
|
|
|
:class="storeNum <= 1 && 'disabled'"
|
2023-11-14 17:21:03 +08:00
|
|
|
|
@click="handleCartNumberChange(curAttr,'minus')"
|
|
|
|
|
>
|
|
|
|
|
<uv-icon
|
|
|
|
|
name="minus"
|
|
|
|
|
color="#333"
|
2023-11-17 20:55:32 +08:00
|
|
|
|
size="24rpx"
|
2023-11-14 17:21:03 +08:00
|
|
|
|
></uv-icon>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="input">
|
|
|
|
|
<input
|
|
|
|
|
type="number"
|
|
|
|
|
inputmode="numeric"
|
|
|
|
|
v-model="storeNum"
|
|
|
|
|
@blur="(e)=>handleCartNumberInputChange(e,curAttr)"
|
2024-02-08 21:01:37 +08:00
|
|
|
|
@input="(e)=>cartNumberInput(e,curAttr)"
|
2023-11-14 17:21:03 +08:00
|
|
|
|
>
|
|
|
|
|
</view>
|
|
|
|
|
<view
|
|
|
|
|
class="button"
|
2023-11-17 20:55:32 +08:00
|
|
|
|
:class="storeNum >= curAttr.stock && 'disabled'"
|
2023-11-14 17:21:03 +08:00
|
|
|
|
@click="handleCartNumberChange(curAttr,'plus')"
|
|
|
|
|
>
|
|
|
|
|
<uv-icon
|
|
|
|
|
name="plus"
|
|
|
|
|
color="#333"
|
2023-11-17 20:55:32 +08:00
|
|
|
|
size="24rpx"
|
2023-11-14 17:21:03 +08:00
|
|
|
|
></uv-icon>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
2023-10-11 11:27:47 +08:00
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<div class="line"></div>
|
|
|
|
|
|
|
|
|
|
<view
|
2023-11-14 17:21:03 +08:00
|
|
|
|
class="goodAttrSelect-attr"
|
|
|
|
|
v-for="(item, index) in productAttr"
|
|
|
|
|
:key="index"
|
2023-10-11 11:27:47 +08:00
|
|
|
|
>
|
|
|
|
|
<view class="goodAttrSelect-attr-title">
|
|
|
|
|
{{ item.attrName }}
|
|
|
|
|
</view>
|
|
|
|
|
<view class="goodAttrSelect-attr-content">
|
2024-02-08 21:01:37 +08:00
|
|
|
|
<space
|
|
|
|
|
wrap="warp"
|
|
|
|
|
gap>
|
2023-10-11 11:27:47 +08:00
|
|
|
|
<view
|
2024-02-08 21:01:37 +08:00
|
|
|
|
:class="{ attr: true, check: selectedAttr[index] === attr,disabled:checkAttrDisable(index,attr)}"
|
2023-11-14 17:21:03 +08:00
|
|
|
|
v-for="(attr, attrIndex) in item.attrValueArr"
|
|
|
|
|
:key="attrIndex"
|
|
|
|
|
@tap="handleSelectAttr(index, attr)"
|
|
|
|
|
>{{ attr }}
|
|
|
|
|
</view>
|
2023-10-11 11:27:47 +08:00
|
|
|
|
</space>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="goodAttrSelect-action">
|
|
|
|
|
<uv-button
|
2024-02-08 21:01:37 +08:00
|
|
|
|
:disabled="!curAttr || curAttr&&curAttr.stock===0 || storeNum===0"
|
2023-11-14 17:21:03 +08:00
|
|
|
|
round
|
|
|
|
|
block
|
|
|
|
|
type="primary"
|
|
|
|
|
@tap="handleSubmit"
|
2023-10-11 11:27:47 +08:00
|
|
|
|
>
|
|
|
|
|
确定
|
|
|
|
|
</uv-button>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
2023-11-14 17:21:03 +08:00
|
|
|
|
</Popup>
|
2023-10-11 11:27:47 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup>
|
2024-02-08 21:01:37 +08:00
|
|
|
|
import {computed, nextTick, ref, toRefs} from 'vue';
|
2023-11-14 17:21:03 +08:00
|
|
|
|
import { useInterface } from "@/hooks/useInterface";
|
|
|
|
|
import Popup from '@/components/Popup/index.vue';
|
2024-02-08 21:01:37 +08:00
|
|
|
|
// ====================== hooks ============================
|
|
|
|
|
const {toast} = useInterface()
|
2023-10-11 11:27:47 +08:00
|
|
|
|
|
2024-02-08 21:01:37 +08:00
|
|
|
|
// ====================== 组件相关 ============================
|
|
|
|
|
const emit = defineEmits(['select', 'close'])
|
|
|
|
|
/**
|
|
|
|
|
* @property goodsDetail 商品详情
|
|
|
|
|
* @property skuId sku打开时默认sku
|
|
|
|
|
*/
|
|
|
|
|
const props = defineProps({
|
|
|
|
|
goodsDetail: {
|
|
|
|
|
type: Object,
|
|
|
|
|
},
|
|
|
|
|
skuId: {
|
|
|
|
|
type: [String, Number],
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
const {goodsDetail, skuId} = toRefs(props)
|
|
|
|
|
|
|
|
|
|
// ======================= 数据相关 ==============================
|
|
|
|
|
const storeInfo = computed(() => goodsDetail.value.storeInfo) // 商品信息
|
|
|
|
|
const productAttr = computed(() => goodsDetail.value.productAttr) // 商品sku attr细腻些
|
|
|
|
|
const productValue = computed(() => goodsDetail.value.productValue) // 商品sku value信息
|
|
|
|
|
const activityName = computed(() => {
|
|
|
|
|
if (!curAttr.value) return ''
|
|
|
|
|
return ['拼团价', '秒杀价', '折扣价'][curAttr.value.campaignType - 1]
|
|
|
|
|
})
|
2023-10-11 11:27:47 +08:00
|
|
|
|
|
2024-02-08 21:01:37 +08:00
|
|
|
|
// ======================= sku 操作相关 ==========================
|
|
|
|
|
const selectedAttr = ref([]) // 当前选中sku的attr key信息
|
|
|
|
|
const curAttr = ref(null) // 当前选中的sku
|
2023-10-11 11:27:47 +08:00
|
|
|
|
|
2024-02-08 21:01:37 +08:00
|
|
|
|
/**
|
|
|
|
|
* 检查是否为disable
|
|
|
|
|
* @param attrRowIndex
|
|
|
|
|
* @param attr
|
|
|
|
|
* @return {boolean}
|
|
|
|
|
*/
|
|
|
|
|
function checkAttrDisable(attrRowIndex, attr) {
|
|
|
|
|
// 模拟当前值选中
|
|
|
|
|
const selectedAttrMock = JSON.parse(JSON.stringify(selectedAttr.value))
|
|
|
|
|
selectedAttrMock[attrRowIndex] = attr
|
|
|
|
|
const filterAttrMock = selectedAttrMock.filter(i => i);
|
|
|
|
|
// 如果不是最后一次选择属性,构不成sku比较,直接return false
|
|
|
|
|
if (filterAttrMock.length < productAttr.value.length) return false
|
|
|
|
|
const mockNameStr = filterAttrMock.filter(i => i)
|
|
|
|
|
for (const skuName in productValue.value) {
|
|
|
|
|
if (skuName.includes(mockNameStr)) {
|
|
|
|
|
const sku = productValue.value[skuName]
|
|
|
|
|
const trueStock = sku.campaignState === 1 ? sku.campaignStock : sku.stock // 真实库存 (区分活动和普通)
|
|
|
|
|
// !!!从有库存的开始查,不要从没库存的直接break
|
|
|
|
|
// 只要有一条includes且库存大于0就直接break
|
|
|
|
|
if (trueStock > 0) return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true
|
2023-11-17 20:55:32 +08:00
|
|
|
|
}
|
2023-10-11 11:27:47 +08:00
|
|
|
|
|
2024-02-08 21:01:37 +08:00
|
|
|
|
/**
|
|
|
|
|
* 设置默认sku选中
|
|
|
|
|
*/
|
|
|
|
|
function handleSetDefaultSkuSelect() {
|
|
|
|
|
const skuList = productValue.value
|
|
|
|
|
// 遍历sku的对象数组,匹配到id相同的项
|
|
|
|
|
if (skuId.value) {
|
|
|
|
|
for (const skuName in skuList) {
|
|
|
|
|
const sku = skuList[skuName]
|
|
|
|
|
const trueStock = sku.campaignState === 1 ? sku.campaignStock : sku.stock // 真实库存 (区分活动和普通)
|
|
|
|
|
if (sku.id === skuId.value && trueStock > 0) {
|
|
|
|
|
// 设置默认选中
|
|
|
|
|
selectedAttr.value = skuName.split(',')
|
|
|
|
|
curAttr.value = sku
|
|
|
|
|
break;
|
|
|
|
|
}
|
2023-11-14 17:21:03 +08:00
|
|
|
|
}
|
2024-02-08 21:01:37 +08:00
|
|
|
|
}
|
|
|
|
|
// 如果没有找到,那就默认选中sku的第一个、
|
|
|
|
|
if (selectedAttr.value.filter(i => i).length <= 0) {
|
|
|
|
|
const skuNameList = Reflect.ownKeys(skuList)
|
|
|
|
|
if (skuNameList.length > 0) {
|
|
|
|
|
let defaultSku, defaultSkuName
|
|
|
|
|
for (const skuName of skuNameList) {
|
|
|
|
|
const sku = skuList[skuName];
|
|
|
|
|
const trueStock = sku.campaignState === 1 ? sku.campaignStock : sku.stock // 真实库存 (区分活动和普通)
|
|
|
|
|
if (trueStock > 0) {
|
|
|
|
|
defaultSku = sku
|
|
|
|
|
defaultSkuName = skuName
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (defaultSku) {
|
|
|
|
|
selectedAttr.value = defaultSkuName.split(',')
|
|
|
|
|
curAttr.value = defaultSku
|
|
|
|
|
}
|
2023-11-17 20:55:32 +08:00
|
|
|
|
}
|
2023-10-11 11:27:47 +08:00
|
|
|
|
}
|
2024-02-08 21:01:37 +08:00
|
|
|
|
handleSetStoreNum()
|
2023-10-11 11:27:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-08 21:01:37 +08:00
|
|
|
|
/**
|
|
|
|
|
* sku选中
|
|
|
|
|
* @param attrRowIndex sku属性row索引
|
|
|
|
|
* @param attrItemName sku选中的item的名称(object的key)
|
|
|
|
|
*/
|
|
|
|
|
const handleSelectAttr = (attrRowIndex, attrItemName) => {
|
|
|
|
|
if (checkAttrDisable(attrRowIndex, attrItemName)) return toast({title: "商品抢完啦~看看其他的吧"})
|
|
|
|
|
curAttr.value = undefined
|
|
|
|
|
if (selectedAttr.value[attrRowIndex] && selectedAttr.value[attrRowIndex] === attrItemName) {
|
|
|
|
|
selectedAttr.value[attrRowIndex] = ''
|
|
|
|
|
return;
|
2023-11-17 20:55:32 +08:00
|
|
|
|
}
|
2024-02-08 21:01:37 +08:00
|
|
|
|
selectedAttr.value[attrRowIndex] = attrItemName
|
|
|
|
|
if (selectedAttr.value.filter(i => i).length === productAttr.value.length) {
|
|
|
|
|
curAttr.value = productValue.value[selectedAttr.value.join(',')]
|
|
|
|
|
// 设置库存
|
|
|
|
|
handleSetStoreNum()
|
2023-11-17 20:55:32 +08:00
|
|
|
|
}
|
2023-10-11 11:27:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-08 21:01:37 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 提交
|
|
|
|
|
*/
|
2023-10-11 11:27:47 +08:00
|
|
|
|
const handleSubmit = () => {
|
2024-02-08 21:01:37 +08:00
|
|
|
|
if (!curAttr.value) return;
|
|
|
|
|
if (curAttr.value.stock === 0 && storeNum.value === 0) return
|
|
|
|
|
emit('select', {
|
|
|
|
|
store: curAttr.value,
|
|
|
|
|
num: storeNum.value
|
|
|
|
|
})
|
|
|
|
|
close()
|
2023-10-11 11:27:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-08 21:01:37 +08:00
|
|
|
|
// ========================== 数量相关 ===========================
|
|
|
|
|
|
|
|
|
|
const storeNum = ref(1) // 数量
|
2023-11-14 17:21:03 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 用户手动输入改变数量
|
|
|
|
|
* @param e
|
|
|
|
|
* @param item
|
|
|
|
|
* @returns {*}
|
|
|
|
|
*/
|
|
|
|
|
function handleCartNumberInputChange(e, item) {
|
|
|
|
|
const value = Number(e.detail.value)
|
2024-02-08 21:01:37 +08:00
|
|
|
|
const trueStock = item.campaignState === 1 ? item.campaignStock : item.stock // 真实库存 (区分活动和普通)
|
2023-11-14 17:21:03 +08:00
|
|
|
|
if (value <= 0) {
|
|
|
|
|
storeNum.value = 1
|
2024-02-08 21:01:37 +08:00
|
|
|
|
} else if (value > trueStock) {
|
|
|
|
|
storeNum.value = trueStock
|
2023-11-17 20:55:32 +08:00
|
|
|
|
} else {
|
2024-02-08 21:01:37 +08:00
|
|
|
|
storeNum.value = value.toString().replace(/^0+/, '')
|
2023-11-14 17:21:03 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-08 21:01:37 +08:00
|
|
|
|
/**
|
|
|
|
|
* 购买数量验证
|
|
|
|
|
*/
|
|
|
|
|
function cartNumberInput(e, item){
|
|
|
|
|
const pattern = /^0+|[.]*/g;
|
|
|
|
|
nextTick(() => {
|
|
|
|
|
storeNum.value = e.detail.value.replace(pattern,'');
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-14 17:21:03 +08:00
|
|
|
|
/**
|
|
|
|
|
* 用户点击购物车+-改变数量
|
|
|
|
|
* @param item
|
|
|
|
|
* @param type
|
|
|
|
|
* @returns {*}
|
|
|
|
|
*/
|
|
|
|
|
function handleCartNumberChange(item, type = 'plus') {
|
2024-02-08 21:01:37 +08:00
|
|
|
|
const trueStock = item.campaignState === 1 ? item.campaignStock : item.stock // 真实库存 (区分活动和普通)
|
2023-11-14 17:21:03 +08:00
|
|
|
|
if (type === 'plus') {
|
2024-02-08 21:01:37 +08:00
|
|
|
|
if (storeNum.value + 1 > trueStock) {
|
|
|
|
|
storeNum.value = trueStock
|
|
|
|
|
} else {
|
2023-11-17 20:55:32 +08:00
|
|
|
|
storeNum.value += 1
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-14 17:21:03 +08:00
|
|
|
|
} else {
|
2024-02-08 21:01:37 +08:00
|
|
|
|
if (storeNum.value - 1 <= 0) {
|
2023-11-17 20:55:32 +08:00
|
|
|
|
storeNum.value = 1
|
|
|
|
|
} else {
|
|
|
|
|
storeNum.value -= 1
|
|
|
|
|
}
|
2023-11-14 17:21:03 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-08 21:01:37 +08:00
|
|
|
|
/**
|
|
|
|
|
* 设置选中数量
|
|
|
|
|
* 当sku发生改变的时候需要调用
|
|
|
|
|
*/
|
|
|
|
|
const handleSetStoreNum = () => {
|
|
|
|
|
if (!curAttr.value) return storeNum.value = 0
|
|
|
|
|
if (storeNum.value === 0 && curAttr.value.stock > 0) {
|
|
|
|
|
storeNum.value = 1
|
|
|
|
|
}
|
|
|
|
|
if (storeNum.value > curAttr.value.stock) {
|
|
|
|
|
storeNum.value = curAttr.value.stock
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-11-14 17:21:03 +08:00
|
|
|
|
|
2024-02-08 21:01:37 +08:00
|
|
|
|
// ========================= 弹窗相关 ============================
|
|
|
|
|
const popupRef = ref()
|
|
|
|
|
const actionType = ref('select') // select:普通选择 cart:购物车选择 buy:普通下单 activeBuy:活动下单 singleBuy:单独购买
|
|
|
|
|
/**
|
|
|
|
|
* 打开弹窗
|
|
|
|
|
* @param cartNum
|
|
|
|
|
* @param action 打开弹窗类型
|
|
|
|
|
*/
|
|
|
|
|
const open = (cartNum = 1, action = 'select') => {
|
|
|
|
|
actionType.value = action
|
|
|
|
|
storeNum.value = cartNum || 1
|
|
|
|
|
const attrLength = productAttr.value.length
|
|
|
|
|
selectedAttr.value = new Array(attrLength).fill('')
|
|
|
|
|
handleSetDefaultSkuSelect()
|
2023-11-14 17:21:03 +08:00
|
|
|
|
popupRef.value.show()
|
2023-10-11 11:27:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const close = () => {
|
2024-02-08 21:01:37 +08:00
|
|
|
|
curAttr.value = null
|
2023-11-14 17:21:03 +08:00
|
|
|
|
emit('close')
|
2024-02-08 21:01:37 +08:00
|
|
|
|
popupRef.value.close()
|
2023-10-11 11:27:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
defineExpose({
|
|
|
|
|
open,
|
|
|
|
|
close
|
|
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
|
2023-11-14 17:21:03 +08:00
|
|
|
|
<style lang="scss">
|
2023-10-11 11:27:47 +08:00
|
|
|
|
.goodAttrSelect {
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
|
|
|
|
&-goods {
|
2023-11-14 17:21:03 +08:00
|
|
|
|
padding: 40rpx 30rpx;
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
|
|
.attr-image {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.attr-info {
|
2023-11-17 20:55:32 +08:00
|
|
|
|
max-width: calc(100% - 150rpx - 30rpx);
|
2023-11-14 17:21:03 +08:00
|
|
|
|
display: flex;
|
2023-11-17 20:55:32 +08:00
|
|
|
|
flex: 1;
|
2023-11-14 17:21:03 +08:00
|
|
|
|
flex-direction: column;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
margin-left: 30rpx;
|
2024-02-08 21:01:37 +08:00
|
|
|
|
|
2023-11-14 17:21:03 +08:00
|
|
|
|
.name {
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
line-height: 40rpx;
|
|
|
|
|
color: #333333;
|
2023-11-17 20:55:32 +08:00
|
|
|
|
display: -webkit-box;
|
|
|
|
|
-webkit-box-orient: vertical;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
-webkit-line-clamp: 2;
|
2023-11-14 17:21:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&-bottom {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
|
|
|
|
.price {
|
|
|
|
|
font-size: 30rpx;
|
|
|
|
|
line-height: 42rpx;
|
2024-02-08 21:01:37 +08:00
|
|
|
|
color: #ee6d46;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.price-name {
|
|
|
|
|
background: #ee6d46;
|
|
|
|
|
color: #fff;
|
|
|
|
|
border-radius: 10rpx;
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
font-style: italic;
|
|
|
|
|
padding: 3rpx 10rpx;
|
|
|
|
|
margin-right: 5rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.old-price {
|
|
|
|
|
font-size: 22rpx;
|
|
|
|
|
color: grey;
|
|
|
|
|
text-decoration: line-through;
|
2023-11-14 17:21:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.stock {
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
line-height: 42rpx;
|
|
|
|
|
color: #666666;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-10-11 11:27:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&-action {
|
|
|
|
|
padding: 20rpx 20rpx;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&-attr {
|
2023-11-17 20:55:32 +08:00
|
|
|
|
padding: 40rpx 30rpx 10rpx 0;
|
2023-10-11 11:27:47 +08:00
|
|
|
|
|
|
|
|
|
&.row {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: space-between;
|
2023-11-17 20:55:32 +08:00
|
|
|
|
padding-bottom: 40rpx;
|
2023-10-11 11:27:47 +08:00
|
|
|
|
|
|
|
|
|
.goodAttrSelect-attr-title {
|
|
|
|
|
margin-bottom: 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&-title {
|
2024-02-08 21:01:37 +08:00
|
|
|
|
margin: 0 0 30rpx 30rpx;
|
2023-10-11 11:27:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-14 17:21:03 +08:00
|
|
|
|
&-content {
|
|
|
|
|
}
|
2023-10-11 11:27:47 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.line {
|
|
|
|
|
height: 1rpx;
|
|
|
|
|
background: #E6E6E6;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.attr {
|
|
|
|
|
height: 68rpx;
|
|
|
|
|
border: 1rpx solid #333333;
|
|
|
|
|
padding: 0 20rpx;
|
|
|
|
|
font-size: 28rpx;
|
2023-11-14 17:21:03 +08:00
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
align-items: center;
|
2023-11-17 20:55:32 +08:00
|
|
|
|
margin: 0 0 30rpx 30rpx;
|
2024-02-08 21:01:37 +08:00
|
|
|
|
|
2023-10-11 11:27:47 +08:00
|
|
|
|
&.check {
|
|
|
|
|
background: #333333;
|
|
|
|
|
color: #fff;
|
|
|
|
|
}
|
2024-02-08 21:01:37 +08:00
|
|
|
|
|
|
|
|
|
&.disabled {
|
|
|
|
|
border: none;
|
|
|
|
|
background: #f5f7fa;
|
|
|
|
|
color: #ccced3;
|
|
|
|
|
}
|
2023-10-11 11:27:47 +08:00
|
|
|
|
}
|
2023-11-14 17:21:03 +08:00
|
|
|
|
|
|
|
|
|
.cart-num {
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
|
|
|
|
.input {
|
|
|
|
|
width: 120rpx;
|
|
|
|
|
|
|
|
|
|
input {
|
|
|
|
|
width: 100%;
|
|
|
|
|
text-align: center;
|
|
|
|
|
color: #333;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.button {
|
|
|
|
|
font-size: 32rpx;
|
2023-11-17 20:55:32 +08:00
|
|
|
|
width: 40rpx;
|
2024-02-08 21:01:37 +08:00
|
|
|
|
height: 40rpx;
|
2023-11-14 17:21:03 +08:00
|
|
|
|
aspect-ratio: 1/1;
|
|
|
|
|
border-radius: 5rpx;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
transition: all .3s;
|
2023-11-17 20:55:32 +08:00
|
|
|
|
border: 1px solid #999999;
|
2023-11-14 17:21:03 +08:00
|
|
|
|
|
|
|
|
|
&:active {
|
|
|
|
|
scale: 1.2;
|
|
|
|
|
}
|
2024-02-08 21:01:37 +08:00
|
|
|
|
|
|
|
|
|
&.disabled {
|
2023-11-17 20:55:32 +08:00
|
|
|
|
border-color: #dddddd;
|
2024-02-08 21:01:37 +08:00
|
|
|
|
|
|
|
|
|
:deep(.uv-icon__icon) {
|
2023-11-17 20:55:32 +08:00
|
|
|
|
color: #dddddd !important;
|
|
|
|
|
}
|
2024-02-08 21:01:37 +08:00
|
|
|
|
|
2023-11-17 20:55:32 +08:00
|
|
|
|
&:active {
|
|
|
|
|
scale: 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-11-14 17:21:03 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-08 21:01:37 +08:00
|
|
|
|
.gap {
|
2023-11-17 20:55:32 +08:00
|
|
|
|
gap: 20rpx;
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-11 11:27:47 +08:00
|
|
|
|
</style>
|