930 lines
25 KiB
Vue
930 lines
25 KiB
Vue
<template>
|
||
<up-popup :show="visible" :round="20" mode="bottom" @close="close" :close-on-click-overlay="true">
|
||
<view class="" style="height: calc(100vh - 70px);">
|
||
<view class="shop_sku" >
|
||
|
||
<scroll-view scroll-y style="height: calc(100vh - 240px); width: 100%">
|
||
<!-- <view class="positionabsolute">
|
||
<up-icon name="arrow-down" @click="close" color="#333" size="22"></up-icon>
|
||
</view> -->
|
||
<view class="positionabsolute">
|
||
<up-icon name="close-circle" @click="close" color="#000" size="25"></up-icon>
|
||
</view>
|
||
<up-swiper :list="goods.images" @change="swiperChange" :current="swiperCurrent" radius="6px"
|
||
height="250" @click="prveImgs(goods.images, goods.images[swiperCurrent])">
|
||
</up-swiper>
|
||
|
||
<view class="shop_sku_name">{{ goods.name }}</view>
|
||
<view class="shop_sku_description" v-if="isSkuGoods">
|
||
{{ goods.shortTitle ? goods.shortTitle : '' }}
|
||
</view>
|
||
<view v-if="goods.type != 'package'">
|
||
<view class="shop_sku_box" v-for="(specOptions, specType) in goods.selectSpecInfo" :key="specType">
|
||
<view class="shop_sku_box_name">
|
||
{{ specType }}
|
||
</view>
|
||
<view class="flex-start">
|
||
<view class="shop_sku_box_item" v-for="option in specOptions" :key="option"
|
||
@click="selectSpec(specType, option)" :class="{
|
||
shop_sku_box_item_selected: isSkuSelected(specType, option)
|
||
}">
|
||
{{ option }}
|
||
<view class="shop_sku_box_item_tip"
|
||
v-if="goods.result && goods.result.isSoldStock == 1 && selectedSpecs[specType] === option">
|
||
<view>售罄</view>
|
||
</view>
|
||
<view class="shop_sku_box_item_tip"
|
||
v-if="goods.result == 'kong' && canSubmit == false && selectedSpecs[specType] === option">
|
||
<view>已下架</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- 套餐 -->
|
||
<view v-else>
|
||
<view class="shop_sku_box">
|
||
<view v-for="(setmenu, setmenuindex) in goods.groupSnap" :key="setmenuindex">
|
||
<view class="shop_sku_box_name">{{ setmenu.title }} {{ setmenu.count }}
|
||
选{{ setmenu.number }}</view>
|
||
<view class="flex-start">
|
||
<view class="shop_sku_box_item" v-for="(option, goodsid) in setmenu.goods"
|
||
:key="goodsid" @click="goodsidClick(setmenuindex, option, goodsid)" :class="{
|
||
shop_sku_box_item_selected: isOptionSelected(setmenuindex, option)
|
||
}" :disabled="isMaxSelected(setmenuindex) && !isOptionSelected(setmenuindex, option)">
|
||
{{ option.proName }}
|
||
<text v-if="option.unitName">/{{ option.unitName }}</text>
|
||
<view class="shop_sku_box_item_tip" v-if="goods.isSoldStock == 1">
|
||
<view>售罄</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 推荐搭配 -->
|
||
<view class="u-m-t-48 u-p-30" v-if="goods.relatedRecommendJson.length">
|
||
<view class="font-bold u-font-32 ">推荐搭配</view>
|
||
<view class="u-flex recommand-goods">
|
||
<view class=" item" v-for="(product,index) in goods.relatedRecommendJson" :key="index"
|
||
@click="modalAdd(product)">
|
||
<view class="relative">
|
||
<up-image width="210rpx" height="210rpx" radius="12rpx"
|
||
:src="product.coverImg"></up-image>
|
||
<view class="vifgoodsImg flex-center"
|
||
v-if="product.isSale == 0 || (product.isSaleTime == 0 && !product.isSaleTimeshow) || product.isSoldStock == 1 || (product.isStock == 1 && product.stockNumber <= 0)">
|
||
<image v-if="product.isSale == 0" src="@/static/ztt/icon_goods_yxj.svg"
|
||
style="width: 200rpx; height: 100%" mode=""></image>
|
||
<image v-else-if="product.isSaleTime == 0 && !product.isSaleTimeshow"
|
||
src="@/static/ztt/icon_goods_wks.svg" style="width: 200rpx; height: 100%"
|
||
mode="">
|
||
</image>
|
||
<image v-else-if="product.isSoldStock == 1" src="@/static/ztt/icon_goods_sq.svg"
|
||
style="width: 200rpx; height: 100%" mode=""></image>
|
||
<image v-else-if="product.isStock == 1 && product.stockNumber <= 0"
|
||
src="@/static/ztt/icon_goods_kcbz.svg" style="width: 200rpx; height: 100%"
|
||
mode="">
|
||
</image>
|
||
</view>
|
||
</view>
|
||
<view class="info">
|
||
<view class="u-line-2 name u-m-t-10 u-font-32 font-500">
|
||
{{product.name}}
|
||
</view>
|
||
|
||
<view class="u-flex u-row-between">
|
||
<view class="font-bold u-flex u-col-baseline">
|
||
<text class="u-font-24">¥</text>
|
||
|
||
<view class="u-font-32">
|
||
|
||
<GoodsPrice :limitDiscount="cartStore.limitTimeDiscount"
|
||
:cart="returnFirstSku(product)" :shopUserInfo="shopUserInfo"
|
||
:shopInfo="shopInfo"></GoodsPrice>
|
||
</view>
|
||
</view>
|
||
<view class="btn relative" @click.stop="addGoods(product)">
|
||
<up-icon name="plus-circle-fill" color="#E9AB7A" size="25"></up-icon>
|
||
<view class="dot" v-if="returnGoodsImCartNum(product)>0">
|
||
{{returnGoodsImCartNum(product)}}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
</view>
|
||
|
||
|
||
</view>
|
||
</view>
|
||
|
||
|
||
</view>
|
||
</scroll-view>
|
||
<view class="shop_bottom">
|
||
<view class="flex-between">
|
||
<view class="price price-sku" v-if="goods.type != 'package' && goods.result">
|
||
<text class="i">¥</text>
|
||
<view class="num">
|
||
<GoodsPrice :limitDiscount="cartStore.limitTimeDiscount" :cart="selSku"
|
||
:shopUserInfo="shopUserInfo" :shopInfo="shopInfo"></GoodsPrice>
|
||
</view>
|
||
|
||
<text class="num" v-if="false">
|
||
{{
|
||
shopInfo.isVip == 1 && shopInfo.isMemberPrice == 1
|
||
? goods.result.memberPrice || goods.result.salePrice
|
||
: goods.result.salePrice
|
||
}}
|
||
</text>
|
||
<text class="i" v-if="goods.unitName">/{{ goods.unitName }}</text>
|
||
<text
|
||
v-if="goods.result.suitNum > 1">「{{ goods.result.suitNum }}{{ goods.result.unitName }}起点」</text>
|
||
</view>
|
||
<view class="price price-package" v-else>
|
||
<text class="i">¥</text>
|
||
<view class="num">
|
||
<GoodsPrice :limitDiscount="cartStore.limitTimeDiscount" :cart="goods"
|
||
:shopUserInfo="shopUserInfo" :shopInfo="shopInfo"></GoodsPrice>
|
||
</view>
|
||
<text class="num" v-if="false">
|
||
{{
|
||
shopInfo.isVip == 1 && shopInfo.isMemberPrice == 1
|
||
? goods.memberPrice || goods.salePrice
|
||
: goods.salePrice
|
||
}}
|
||
</text>
|
||
<text class="i" v-if="goods.unitName">/{{ goods.unitName }}</text>
|
||
<text v-if="goods.suitNum > 1">「{{ goods.suitNum }}{{ goods.unitName }}起点」</text>
|
||
</view>
|
||
|
||
<view class="operation-wrap" v-if="goods.type != 'package'&&stockNumberIsFull(goods)">
|
||
<view class="btn">
|
||
<up-icon name="minus-circle-fill" color="#E9AB7A" size="25"
|
||
v-if="shopCartNumber > 0"></up-icon>
|
||
<view class="btnClick" @click="shopCart('-')"></view>
|
||
</view>
|
||
<text class="num">{{ shopCartNumber }}</text>
|
||
<view class="btn">
|
||
<up-icon name="plus-circle-fill" color="#E9AB7A" size="25"></up-icon>
|
||
<view class="btnClick" @click="shopCart('+')"></view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="shop_skuselect flex-start" v-if="selectedSpecsStr">
|
||
<view class="shop_skuselectname">{{ selectedSpecsStr }}</view>
|
||
</view>
|
||
<template v-if="!stockNumberIsFull(goods)">
|
||
<view class="addShopping">
|
||
库存不足
|
||
</view>
|
||
</template>
|
||
<template v-else>
|
||
<template v-if="isSkuGoods">
|
||
<view v-if="goods.type == 'package'" class="addShopping package"
|
||
:class=" allConditionsSatisfied ? 'active' : ''" @click="submitSelection(goods)">
|
||
添加到购物车
|
||
</view>
|
||
<view v-else class="sku addShopping" :class="shopCartNumber > 0 && canSubmit ? 'active' : ''"
|
||
@click="submitSelection(goods)">
|
||
添加到购物车
|
||
</view>
|
||
</template>
|
||
<template v-else>
|
||
<view class="addShopping single" :class="shopCartNumber > 0 ? 'active' : ''"
|
||
@click="submitSelection(goods)">
|
||
添加到购物车
|
||
</view>
|
||
</template>
|
||
</template>
|
||
|
||
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
|
||
</up-popup>
|
||
</template>
|
||
|
||
<script setup>
|
||
import {
|
||
useNavbarStore
|
||
} from '@/stores/navbarStore';
|
||
const store = useNavbarStore();
|
||
const {
|
||
showBack,
|
||
rightText,
|
||
showSearch,
|
||
title,
|
||
isTransparent,
|
||
height,
|
||
hasPlaceholder,
|
||
scrollTop
|
||
} = toRefs(store);
|
||
import {
|
||
APIminiAppinfo,
|
||
APIminiAppskuinfo,
|
||
productRelated
|
||
} from '@/common/api/product/product.js';
|
||
import dayjs from 'dayjs';
|
||
//价格计算辅助函数
|
||
import {
|
||
limitUtils
|
||
} from 'ysk-utils';
|
||
import GoodsPrice from '@/components/goods-price.vue';
|
||
import {
|
||
computed,
|
||
inject,
|
||
ref,
|
||
watch
|
||
} from "vue";
|
||
const cartStore = inject('cartStore')
|
||
const shopUserInfo = inject('shopUserInfo')
|
||
const shopInfo = inject('shopInfo')
|
||
const props = defineProps({
|
||
data: {
|
||
type: Object,
|
||
default: () => {},
|
||
},
|
||
goods: {
|
||
type: Object,
|
||
default: () => {
|
||
return {
|
||
relatedRecommendJson: []
|
||
}
|
||
},
|
||
},
|
||
GoodsIDInCartNumMap: {
|
||
type: Object,
|
||
default: () => {
|
||
return {
|
||
|
||
}
|
||
},
|
||
}
|
||
});
|
||
|
||
// / 选择规格的方法
|
||
const goodsidClick = (setmenuindex, option, goodsid) => {
|
||
if (!selectedOptions.value[setmenuindex]) {
|
||
// 如果 selectedOptions.value[setmenuindex] 不存在,初始化一个空数组
|
||
selectedOptions.value[setmenuindex] = [];
|
||
}
|
||
if (isOptionSelected(setmenuindex, option)) {
|
||
// 如果已经选中,取消选中
|
||
selectedOptions.value[setmenuindex] = selectedOptions.value[setmenuindex].filter((item) => item.proId !==
|
||
option.proId);
|
||
} else if (!isMaxSelected(setmenuindex)) {
|
||
// 如果未达到最大选择数量,添加到选中列表
|
||
selectedOptions.value[setmenuindex].push(option);
|
||
}
|
||
};
|
||
|
||
// 计算所有选中条件是否都符合
|
||
const allConditionsSatisfied = computed(() => {
|
||
// 检查 specifications.item.groupSnap 是否存在
|
||
if (!props.goods?.groupSnap) {
|
||
return false;
|
||
}
|
||
return props.goods.groupSnap.every((optionGroup, index) => {
|
||
// 获取当前索引对应的已选选项,如果不存在则默认为空数组
|
||
const selected = selectedOptions.value[index] || [];
|
||
// 检查是否达到最大选择数量
|
||
const hasEnoughSelection = selected.length === optionGroup.number;
|
||
return hasEnoughSelection;
|
||
});
|
||
});
|
||
// 存储用户当前选择的规格,初始为空对象
|
||
const selectedSpecs = ref({});
|
||
|
||
const shopCartNumber = ref(0)
|
||
|
||
function isSkuSelected(specType, option) {
|
||
return selectedSpecs.value[specType] === option;
|
||
}
|
||
const selSku = ref(null)
|
||
// 处理规格选择的方法
|
||
const selectSpec = async (specType, option) => {
|
||
// 规格清零
|
||
shopCartNumber.value = 0;
|
||
|
||
// 更新 selectedSpecs 对象,将当前规格类型的选中值设置为用户点击的选项
|
||
const newSelectedSpecs = {};
|
||
const specKeys = Object.keys(props.goods.selectSpecInfo);
|
||
for (const key of specKeys) {
|
||
if (key === specType) {
|
||
newSelectedSpecs[key] = option;
|
||
} else {
|
||
newSelectedSpecs[key] = selectedSpecs.value[key];
|
||
}
|
||
}
|
||
selectedSpecs.value = newSelectedSpecs;
|
||
if (allSpecsSelected.value) {
|
||
// try {
|
||
let result = await APIminiAppskuinfo({
|
||
specInfo: selectedSpecsStr.value,
|
||
id: props.goods.id
|
||
});
|
||
// skuList
|
||
if (result != true) {
|
||
selSku.value = result
|
||
} else {}
|
||
} else {}
|
||
};
|
||
// 判断是否达到最大选择数量
|
||
const isMaxSelected = (setmenuindex) => {
|
||
// 确保 selectedOptions.value[setmenuindex] 存在
|
||
if (selectedOptions.value[setmenuindex]) {
|
||
return selectedOptions.value[setmenuindex].length >= props.goods.groupSnap[setmenuindex].number;
|
||
}
|
||
return false;
|
||
};
|
||
// 存储选中的选项,二维数组
|
||
const selectedOptions = ref(props.goods.groupSnap.map(() => []));
|
||
// 判断选项是否已选中
|
||
const isOptionSelected = (setmenuindex, option) => {
|
||
// 确保 selectedOptions.value[setmenuindex] 存在
|
||
if (selectedOptions.value[setmenuindex]) {
|
||
return selectedOptions.value[setmenuindex].some((item) => item.proId === option.proId);
|
||
}
|
||
return false;
|
||
};
|
||
const canSubmit = computed(() => {
|
||
if (shopCartNumber.value <= 0) {
|
||
return false
|
||
}
|
||
return true
|
||
})
|
||
// 计算属性,将 selectedSpecs 转换为字符串形式
|
||
const selectedSpecsStr = computed(() => {
|
||
const values = Object.values(selectedSpecs.value);
|
||
return values.join(',');
|
||
});
|
||
// 计算属性,判断是否所有规格类型都有选中项
|
||
const allSpecsSelected = computed(() => {
|
||
// 获取所有规格类型的键
|
||
const specKeys = Object.keys(props.goods.selectSpecInfo);
|
||
// skuBtnText.value = selectedSpecsStr.value ? `您还没选择${specKeys[1]}哦` : ``
|
||
// 检查每个规格类型是否都在 selectedSpecs 中有对应的选中值
|
||
return specKeys.every((key) => selectedSpecs.value[key]);
|
||
});
|
||
|
||
const swiperCurrent = ref(0);
|
||
|
||
function returnFirstSku(product) {
|
||
return product.skuList[0]
|
||
}
|
||
//返回是否是多规格商品
|
||
function returnIsSkuGoods(item) {
|
||
if (item.type == 'single' || item.type == 'weight' || (item.type == 'package' && item.groupType == '0')) {
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
const isSkuGoods = computed(() => {
|
||
return returnIsSkuGoods(props.goods);
|
||
});
|
||
|
||
|
||
function swiperChange(e) {
|
||
swiperCurrent.value = e.current;
|
||
}
|
||
|
||
const emits = defineEmits(['prveImgs', 'websocketsendMessage', 'close', 'modalAdd'])
|
||
|
||
function prveImgs(images, currentUrl) {
|
||
emits('prveImgs', images, currentUrl)
|
||
}
|
||
|
||
function modalAdd(item) {
|
||
emits('modalAdd', item)
|
||
}
|
||
|
||
const visible = defineModel({
|
||
default: false,
|
||
});
|
||
|
||
|
||
function stockNumberIsFull(item) {
|
||
if (item.isStock && item.stockNumber < item.suitNum) {
|
||
return false
|
||
}
|
||
return true
|
||
}
|
||
|
||
function close() {
|
||
visible.value = false;
|
||
shopCartNumber.value = 0;
|
||
selectedOptions.value = props.goods.groupSnap.map(() => [])
|
||
emits('close')
|
||
}
|
||
|
||
function isSelected(option) {
|
||
return selectedSpecs.value[specType] === option;
|
||
}
|
||
const calculateValue = (cartNumber, i, step = 1) => {
|
||
if (i == '+') {
|
||
const result = parseFloat(cartNumber) + parseFloat(step);
|
||
return result.toFixed(2);
|
||
} else {
|
||
// 当减到0返回del
|
||
const result = parseFloat(cartNumber) - parseFloat(step);
|
||
return result == 0 ? 'del' : result.toFixed(2);
|
||
}
|
||
};
|
||
// 判断商品是否在可售时间内
|
||
const isProductAvailable = async (sellDaysStr, startTimeStr, endTimeStr) => {
|
||
// 将后端返回的字符串转换为数组
|
||
const sellDays = sellDaysStr.split(',');
|
||
const now = dayjs();
|
||
const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
||
const currentDay = days[now.day()];
|
||
|
||
// console.log('当前日期:', currentDay);
|
||
// console.log('可售日期列表:', sellDays);
|
||
|
||
// 检查当前周几是否在可售周几列表中
|
||
if (!sellDays.includes(currentDay)) {
|
||
// console.log('当前日期不在可售日期列表中');
|
||
return false;
|
||
}
|
||
|
||
const startTime = dayjs(`${now.format('YYYY-MM-DD')} ${startTimeStr}`);
|
||
let endTime = dayjs(`${now.format('YYYY-MM-DD')} ${endTimeStr}`);
|
||
|
||
// 处理跨天情况
|
||
if (endTime.isBefore(startTime)) {
|
||
endTime = endTime.add(1, 'day');
|
||
}
|
||
|
||
// console.log('当前时间:', now.format('YYYY-MM-DD HH:mm:ss'));
|
||
// console.log('开始时间:', startTime.format('YYYY-MM-DD HH:mm:ss'));
|
||
// console.log('结束时间:', endTime.format('YYYY-MM-DD HH:mm:ss'));
|
||
|
||
const isInRange = now.isBetween(startTime, endTime, null, '[)');
|
||
// console.log('当前时间是否在可售时间范围内:', isInRange);
|
||
|
||
return isInRange;
|
||
};
|
||
|
||
async function addGoods(goods) {
|
||
if (!isProductAvailable(goods.days, goods.startTime,
|
||
goods.endTime)) {
|
||
uni.showToast({
|
||
title: '不在可售时间内'
|
||
});
|
||
return false;
|
||
}
|
||
if (goods.isSoldStock == 1 || (goods.isSaleTime == 0 && !goods.isSaleTimeshow)) {
|
||
return uni.showToast({
|
||
title: '商品已下架或不在可售时间内',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
const sku = goods.skuList[0]
|
||
const findCart = cartStore.carts.find(cart => cart.product_id == goods.id && sku.id)
|
||
emits('websocketsendMessage', {
|
||
id: findCart ? findCart.id : '',
|
||
type: 'shopping',
|
||
suitNum: sku.suitNum,
|
||
table_code: uni.cache.get('tableCode'),
|
||
shop_id: uni.cache.get('shopId'),
|
||
operate_type: findCart ? 'edit' : 'add',
|
||
product_id: goods.id,
|
||
sku_id: sku.id,
|
||
number: findCart ? await calculateValue(findCart.number * 1, '+', 1) : 1,
|
||
pro_group_info: '',
|
||
goods_type: goods.type == 'package' ? 'package' : '',
|
||
memberPrice: goods.memberPrice,
|
||
is_print: 1,
|
||
product_type: goods.type,
|
||
is_time_discount: showLimitDiscount(goods)
|
||
})
|
||
|
||
}
|
||
|
||
|
||
/**
|
||
* 返回购物车对应的商品数量
|
||
*/
|
||
function returnGoodsImCartNum(goods) {
|
||
console.log('props.GoodsIDInCartNumMap', props.GoodsIDInCartNumMap)
|
||
if (props.GoodsIDInCartNumMap.hasOwnProperty(goods.id)) {
|
||
return props.GoodsIDInCartNumMap[goods.id]
|
||
}
|
||
return 0
|
||
}
|
||
|
||
function returnSelectedGroupSnap() {
|
||
if (!props.goods?.groupSnap) {
|
||
return '';
|
||
}
|
||
return props.goods.groupSnap.map((v, index) => {
|
||
return {
|
||
...v,
|
||
goods: selectedOptions.value[index]
|
||
}
|
||
});
|
||
}
|
||
|
||
// 提交选择并执行下一步操作的方法
|
||
const submitSelection = async (goods) => {
|
||
if (!isProductAvailable(goods.days, goods.startTime,
|
||
goods.endTime)) {
|
||
uni.showToast({
|
||
title: '不在可售时间内'
|
||
});
|
||
return false;
|
||
}
|
||
// 判断购物车是否有该选中商品
|
||
if (goods.type != 'package' && shopCartNumber.value <= 0) {
|
||
return;
|
||
}
|
||
if (goods.type == 'package' && !allConditionsSatisfied.value) {
|
||
return
|
||
}
|
||
|
||
if ((goods.type == 'package' && allConditionsSatisfied.value) || (goods.type ==
|
||
'sku' && canSubmit.value)) {
|
||
let res = cartStore.carts.find(cart => cart.product_id == goods.id && cart.sku_id == selSku.value.id)
|
||
let suitNum = 1;
|
||
let sku_id = ''
|
||
// 是否是套餐 有就传
|
||
if (goods.type == 'package') {
|
||
// 需求更改:所所有商品套餐都是add,没有修改
|
||
shopCartNumber.value = props.goods.suitNum;
|
||
suitNum = props.goods.suitNum;
|
||
sku_id = props.goods.sku_id;
|
||
res = null;
|
||
} else {
|
||
|
||
suitNum = selSku.value.suitNum
|
||
sku_id = selSku.value.id
|
||
}
|
||
console.log('goods', goods);
|
||
emits('websocketsendMessage', {
|
||
id: res ? res.id : '',
|
||
type: 'shopping',
|
||
suitNum,
|
||
table_code: uni.cache.get('tableCode'),
|
||
shop_id: uni.cache.get('shopId'),
|
||
operate_type: res ? 'edit' : 'add',
|
||
product_id: goods.id,
|
||
sku_id,
|
||
number: res ? await calculateValue(res.cartNumber, '+', shopCartNumber.value) :
|
||
shopCartNumber.value,
|
||
pro_group_info: returnSelectedGroupSnap(),
|
||
goods_type: goods.type == 'package' ? 'package' : '',
|
||
memberPrice: goods.memberPrice,
|
||
is_print: 1,
|
||
product_type: goods.type,
|
||
is_time_discount: showLimitDiscount(goods)
|
||
})
|
||
} else {
|
||
let res = cartStore.carts.find(cart => cart.product_id == goods.id && goods.skuList[0].id)
|
||
emits('websocketsendMessage', {
|
||
id: res ? res.id : '',
|
||
type: 'shopping',
|
||
suitNum: goods.suitNum,
|
||
table_code: uni.cache.get('tableCode'),
|
||
shop_id: uni.cache.get('shopId'),
|
||
operate_type: res ? 'edit' : 'add',
|
||
product_id: goods.id,
|
||
sku_id: goods.skuList[0].id,
|
||
number: res ? await calculateValue(res.cartNumber, '+', shopCartNumber.value) :
|
||
shopCartNumber.value,
|
||
memberPrice: goods.memberPrice,
|
||
is_print: 1,
|
||
product_type: goods.type,
|
||
is_time_discount: showLimitDiscount(goods)
|
||
})
|
||
|
||
}
|
||
|
||
close()
|
||
|
||
};
|
||
|
||
function showLimitDiscount(item) {
|
||
if (!cartStore.limitTimeDiscount || !cartStore.limitTimeDiscount.id) {
|
||
return 0;
|
||
}
|
||
return limitUtils.canUseLimitTimeDiscount(item, cartStore.limitTimeDiscount, shopInfo, shopUserInfo.value, 'id') ?
|
||
1 : 0;
|
||
}
|
||
|
||
// 多规格 套餐 单规格添加数量
|
||
const shopCart = async (i) => {
|
||
if (i == '-' && shopCartNumber.value <= (props.goods.suitNum || 1)) {
|
||
shopCartNumber.value = 0;
|
||
return false;
|
||
}
|
||
let res = null
|
||
|
||
if (i == '-') {
|
||
if (!res && shopCartNumber.value == props.goods.suitNum) {
|
||
uni.showToast({
|
||
title: `起点${props.goods.suitNum}个`,
|
||
icon: 'none'
|
||
});
|
||
return false;
|
||
} else {
|
||
shopCartNumber.value--;
|
||
}
|
||
} else {
|
||
|
||
if (!res && shopCartNumber.value < 1) {
|
||
if (props.goods.type == 'sku') {
|
||
if (!selSku.value) {
|
||
return
|
||
}
|
||
shopCartNumber.value = parseFloat(selSku.value.suitNum);
|
||
} else {
|
||
shopCartNumber.value = parseFloat(props.goods.suitNum);
|
||
}
|
||
} else {
|
||
shopCartNumber.value++;
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
<style lang="scss" scoped>
|
||
.box {
|
||
height: 100vh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
|
||
.top {
|
||
width: 750rpx;
|
||
}
|
||
}
|
||
|
||
.shop_sku {
|
||
width: 100%;
|
||
flex: 1;
|
||
position: relative;
|
||
border-radius: 20rpx;
|
||
background: #fff;
|
||
box-sizing: border-box;
|
||
overflow: hidden;
|
||
.positionabsolute {
|
||
position: absolute;
|
||
top: 30rpx;
|
||
z-index: 999;
|
||
right: 30rpx;
|
||
}
|
||
|
||
// .positionabsolute {
|
||
// position: absolute;
|
||
// top: 30rpx;
|
||
// z-index: 999;
|
||
// left: 30rpx;
|
||
// width: 60rpx;
|
||
// height: 60rpx;
|
||
// display: flex;
|
||
// align-items: center;
|
||
// justify-content: center;
|
||
// background-color: #eee;
|
||
// border-radius: 50%;
|
||
// }
|
||
|
||
.shop_sku_name {
|
||
padding: 0 28rpx;
|
||
margin-top: 20rpx;
|
||
font-weight: bold;
|
||
font-size: 32upx;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.shop_sku_returned {
|
||
padding: 0 28rpx;
|
||
font-weight: 400;
|
||
font-size: 24rpx;
|
||
color: #ff534b;
|
||
}
|
||
|
||
.shop_sku_description {
|
||
padding: 0 28rpx;
|
||
font-weight: 400;
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
margin-top: 16rpx;
|
||
padding-bottom: 32rpx;
|
||
box-sizing: border-box;
|
||
border-bottom: 2rpx solid #f0f0f0;
|
||
}
|
||
|
||
|
||
|
||
.shop_sku_box {
|
||
padding: 20rpx;
|
||
|
||
.shop_sku_box_name {
|
||
margin-top: 20rpx;
|
||
font-weight: 500;
|
||
font-size: 28upx;
|
||
color: #333;
|
||
}
|
||
|
||
.flex-start {
|
||
.shop_sku_box_item {
|
||
margin-top: 16rpx;
|
||
padding: 12rpx 28rpx;
|
||
border-radius: 8rpx;
|
||
font-size: 24upx;
|
||
margin-right: 56rpx;
|
||
background: #efefef;
|
||
border: 2rpx solid #efefef;
|
||
position: relative;
|
||
color: #666666;
|
||
|
||
.shop_sku_box_item_tip {
|
||
width: 62rpx;
|
||
height: 47rpx;
|
||
text-align: right;
|
||
position: absolute;
|
||
top: 0;
|
||
right: 0;
|
||
background: linear-gradient(45deg, transparent, transparent 50%, #cecece 50%, #cecece 100%);
|
||
|
||
view {
|
||
font-size: 18rpx;
|
||
color: #666666;
|
||
transform: rotate(45deg);
|
||
position: absolute;
|
||
top: 5rpx;
|
||
right: 3rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.shop_sku_box_item:nth-child(1) {
|
||
margin-left: 0;
|
||
}
|
||
|
||
.disabled {
|
||
color: #999;
|
||
background-color: #f5f5f5;
|
||
border: 2rpx solid #f5f5f5;
|
||
}
|
||
|
||
.shop_sku_box_item_noselected {
|
||
color: #666;
|
||
}
|
||
|
||
.shop_sku_box_item_selected {
|
||
background: #fefaf7;
|
||
border-radius: 8rpx;
|
||
border: 2rpx solid #e8ad7b;
|
||
color: #e8ad7b;
|
||
}
|
||
}
|
||
}
|
||
|
||
.shop_skuselect {
|
||
margin-top: 16rpx;
|
||
width: 100%;
|
||
// background: #f7f7f7;
|
||
color: #999;
|
||
font-size: 24upx;
|
||
|
||
.shop_skuselectname {
|
||
color: #000;
|
||
font-size: 26upx;
|
||
}
|
||
}
|
||
|
||
.shop_bottom {
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
padding: 30rpx 28rpx;
|
||
background-color: #fff;
|
||
box-shadow: 0rpx -6rpx 14rpx 2rpx rgba(0, 0, 0, 0.1);
|
||
|
||
.price {
|
||
display: flex;
|
||
align-items: flex-end;
|
||
|
||
.i {
|
||
font-size: 28rpx;
|
||
color: #e8ad7b;
|
||
position: relative;
|
||
bottom: 4upx;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.num {
|
||
font-size: 42rpx;
|
||
color: #e8ad7b;
|
||
position: relative;
|
||
top: 6upx;
|
||
padding: 0 4upx;
|
||
}
|
||
}
|
||
|
||
.operation-wrap {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.num {
|
||
font-size: 32upx;
|
||
padding: 0 16upx;
|
||
}
|
||
|
||
.btn {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
position: relative;
|
||
|
||
.btnClick {
|
||
width: 100rpx;
|
||
height: 100rpx;
|
||
position: absolute;
|
||
// bottom: 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
.addShopping {
|
||
width: 100%;
|
||
height: 96rpx;
|
||
line-height: 96rpx;
|
||
text-align: center;
|
||
background: #ccc;
|
||
border-radius: 48rpx;
|
||
font-weight: 400;
|
||
font-size: 32rpx;
|
||
color: #ffffff;
|
||
margin-top: 36rpx;
|
||
}
|
||
|
||
.addShopping.active {
|
||
background: #e8ad7b;
|
||
}
|
||
}
|
||
}
|
||
|
||
.recommand-goods {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
margin-top: 24rpx;
|
||
|
||
.item {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
margin-right: 30rpx;
|
||
margin-bottom: 30rpx;
|
||
width: 210rpx;
|
||
|
||
&:nth-child(3n) {
|
||
margin-right: 0;
|
||
}
|
||
|
||
.name {
|
||
height: 84rpx;
|
||
}
|
||
|
||
.info {
|
||
width: 100%;
|
||
}
|
||
}
|
||
}
|
||
|
||
.relative {
|
||
position: relative;
|
||
}
|
||
|
||
.dot {
|
||
position: absolute;
|
||
right: -10rpx;
|
||
top: -10rpx;
|
||
background-color: #FF534B;
|
||
border-radius: 32rpx;
|
||
width: 30rpx;
|
||
font-size: 20rpx;
|
||
color: #fff;
|
||
height: 30rpx;
|
||
text-align: center;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.vifgoodsImg {
|
||
width: 100%;
|
||
height: 204rpx;
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
z-index: 20;
|
||
background-color: rgb(0, 0, 0, 0.5);
|
||
|
||
image {
|
||
padding: 30rpx;
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
}
|
||
</style> |