TakeOutShop/components/multi/multi.vue
2025-04-13 20:39:43 +08:00

398 lines
10 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<!-- 多规格组件弹框 -->
<uni-popup ref="multiPopup" type="bottom" @change="changeMulti">
<view class="multiPopup">
<view class="shop_open_close" @click="OpenMulti()">
<image src="../../static/order/close.png" mode="widthFix"></image>
</view>
<view class="multishop">
<image class="multishop_img" :src="imageUrls" mode="widthFix"></image>
<view class="multishop_text">
<view class="multishop_title"><text>{{titles}}</text></view>
<view class="multishop_price">{{prices}}<text class="multishop_name">{{otPrices}}</text></view>
<view class="multishop_spec">已选:<text :class="!specValue?'specValue':''">{{specValue||'请选择规格'}}</text></view>
</view>
</view>
<view class="multishop_list" v-for="(item,index) in productAttr" :key="index">
<view class="multishop_list_title">{{item.attrName}}</view>
<view class="multishop_list_item">
<view v-for="(v,i) in item.attrValueList" :key="i" class="multishop_list_name" :class="selectedSpecs[item.attrName] === v?'multishop_list_arver':''" @click="choose(item.attrName,v)">{{v}}</view>
</view>
</view>
<view style="height: 200rpx;"></view>
<view class="footer_multi">
<view class="multishop_amount">
<view class="multishop_name_amount">选数量</view>
<view class="multishop_data_edit">
<view class="multishop_data_edit_img border_l" @click="editAmount(1)">
<image class="multishop_data_edit_imgurl" :class="amount == 1 ?'opy':''" src="https://zhkj1.oss-cn-shanghai.aliyuncs.com/zhscMerchant/minus.png" mode="widthFix"></image>
</view>
<view class="multishop_data_number">{{amount}}</view>
<view class="multishop_data_edit_img border_r" @click="editAmount(2)">
<image class="multishop_data_edit_imgurl" src="https://zhkj1.oss-cn-shanghai.aliyuncs.com/zhscMerchant/add.png" mode="widthFix"></image>
</view>
</view>
</view>
<view class="footer_multi_btn" @click="specConfirm">确定</view>
</view>
</view>
</uni-popup>
</template>
<script setup>
import { loads } from '@/utils/index.js'
import { frontproduct,skudetail,cartsave,frontcartcount } from '@/server/api';
import { computed,ref,onMounted,defineEmits,watch } from 'vue';
import { useCounterStore } from '@/store/counter'; // 引入 Pinia Store
import { storeToRefs } from 'pinia';//实现解构付值
import { onLoad,onShow,onPullDownRefresh,onPageScroll,onReachBottom,onReady } from "@dcloudio/uni-app"
const counterStore = useCounterStore(); // 使用 Store
//使用piniastoreToRefs方法包裹(保持响应式更新,不使用视图无法更新)
const { token,cartcount } = storeToRefs(counterStore);
const multiPopup = ref(null);
const multiShow = ref(false);
const show = ref(false);
const emit = defineEmits(['add-success', 'add-error']);
const productAttr = ref([]);
const productValue = ref([]);
const titles = ref("");
const prices = ref("");
const otPrices = ref("");
const imageUrls = ref("");
const amount = ref(1);
// 当前选中的规格
const selectedSpecs = ref("")
const specValue = ref("");
// 当前匹配的SKU
const currentSku = ref({})
const changeMulti = (e)=>{
multiShow.value = e.show;
show.value = e.show;
}
const OpenMulti =() =>{
multiShow.value ? multiPopup.value.close():multiPopup.value.open()
}
const props = defineProps({
shopitem:{
type:Object,
default:{}
}
})
//加购物车
const addCart=(i,type)=>{
const { jumpIds,productInfo,specType,id,image,storeName,price,otPrice } = i;
let specTypes = false;
let ids = ""
if(type){
imageUrls.value = image;
titles.value = storeName;
prices.value = price;
otPrices.value = otPrice;
specTypes = specType;
}else{
specTypes = productInfo.specType;
}
if(jumpIds){
ids = jumpIds;
}else{
ids = id;
}
api_skudetail(specTypes,ids);
}
// 暴露方法给父组件
defineExpose({
addCart
})
//购物车数量
const api_frontcartcount=()=>{
frontcartcount().then(({data}) => {cartcount.value = data.count;})
}
//购物车规格详情接口 specTypes 多规格true、单规格false
const api_skudetail=(specTypes,ids)=>{
loads('', true)
return skudetail(ids).then(({data}) => {
if(specTypes){
uni.hideLoading()
amount.value = 1;
productAttr.value = data.productAttr;
productValue.value = Object.values(data.productValue);
multiPopup.value.open();
}else{
const { productId,id } = data.productValue.默认;
api_cartsave(productId,id);
}
})
.catch(({message}) => {
uni.hideLoading()
uni.showModal({
content:message,
showCancel: false
})
})
}
//选择多规格
const choose = (name,value)=>{
selectedSpecs.value = {
...selectedSpecs.value,
[name]: value
}
const valuesArray = Object.values(selectedSpecs.value).toString();
specValue.value = valuesArray;
productValue.value.forEach(item=>{
if(valuesArray == item.suk){
if(item.image){
imageUrls.value = item.image
}
if(item.price){
prices.value = item.price
}
currentSku.value = item
}
})
}
const specConfirm = ()=>{
if(productAttr.value.length !== Object.values(selectedSpecs.value).length){
uni.showToast({
title:'请选择规格',
icon:'none'
})
return false
}
api_cartsave(currentSku.value.productId,currentSku.value.id);
}
const api_cartsave = (productId,productAttrUnique) =>{
const params = {
cartNum:amount.value,
productId,
productAttrUnique
}
return cartsave(params).then(({message})=>{
uni.hideLoading()
uni.showToast({
title:'添加购物车成功',
icon:'none',
success: () => {
emit('add-success', message)
api_frontcartcount();
if(multiShow.value){
multiPopup.value.close()
}
}
})
})
.catch(({message}) => {
emit('add-error', message)
uni.hideLoading()
uni.showModal({
content:message,
showCancel: false
})
})
}
const editAmount = (type) =>{
if(type == 1){
if(amount.value == 1) return false;
amount.value = amount.value - 1;
}else{
amount.value = amount.value + 1;
}
}
//生命周期钩子
onMounted(() => {});
</script>
<style lang="scss">
//多规格
.multiPopup{
background-color: #FFFFFF;
border-top-left-radius: 25rpx;
border-top-right-radius: 25rpx;
max-height: 800rpx;
overflow-y: auto;
position: relative;
.shop_open_close{
width: 80rpx;
height: 80rpx;
position: absolute;
top: 0;
right: 0;
display: flex;
align-items: center;
justify-content: center;
}
.shop_open_close image{
width: 45rpx;
height: 45rpx;
}
.multishop{
display: flex;
padding: 25rpx 25rpx 0rpx 25rpx;
.multishop_img{
width: 180rpx;
height: 180rpx;
border-radius: 10rpx;
}
.multishop_text{
width: 460rpx;
margin-left: 20rpx;
.multishop_title{
font-size: 28rpx;
color: #333;
font-weight: 500;
margin-top: 5rpx;
min-height: 75rpx;
}
.multishop_title text{
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.multishop_price{
font-size: 32rpx;
color: #FD3F3F;
font-weight: 500;
.multishop_name{
color: #999;
font-size: 23rpx;
text-decoration: line-through;
margin-left: 5rpx;
font-weight: 400;
}
.multishop_name::before{
content: "¥";
font-size: 20rpx;
margin-right: 5rpx;
}
}
.multishop_spec{
color: #333333;
font-size: 26rpx;
margin-top: 15rpx;
}
.multishop_spec text{
margin-left: 10rpx;
}
.specValue{
color: #999;
}
.multishop_price::before{
content: "¥";
font-size: 24rpx;
margin-right: 5rpx;
}
}
}
.multishop_list{
padding: 25rpx 25rpx 0rpx 25rpx;
.multishop_list_title{
font-size: 28rpx;
color: #333;
font-weight: 500;
margin-bottom: 25rpx;
}
.multishop_list_item{
display: flex;
flex-wrap: wrap;
.multishop_list_name{
padding: 12rpx 35rpx 12rpx 35rpx;
border-radius: 10rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 24rpx;
color: #333333;
background-color: #f6f6f6;
margin-right: 25rpx;
margin-bottom: 25rpx;
border:1px solid #f6f6f6;
}
.multishop_list_arver{
background-color: #FFD7D7;
border:1px solid #fd3f3f;
color: #fd3f3f;
}
}
}
.footer_multi{
position: fixed;
bottom: 0rpx;
width: 100%;
background-color: #FFFFFF;
border-top-left-radius: 20rpx;
border-top-right-radius: 20rpx;
padding-bottom: 20rpx;
.multishop_amount{
display: flex;
align-items: center;
justify-content: space-between;
padding-left: 25rpx;
padding-right: 25rpx;
margin-top: 15rpx;
margin-bottom: 40rpx;
.multishop_name_amount{
font-size: 28rpx;
color: #333;
font-weight: 500;
}
.multishop_data_edit{
display: flex;
align-items: center;
justify-content: center;
.multishop_data_edit_img{
width: 55rpx;
height: 50rpx;
display: flex;
align-items: center;
justify-content: center;
border-top: 1px solid #E9E9E9;
border-bottom: 1px solid #E9E9E9;
.multishop_data_edit_imgurl{
width: 25rpx;
height: 25rpx;
display: block;
}
}
.border_l{
border-left: 1px solid #E9E9E9;
border-top-left-radius: 50rpx;
border-bottom-left-radius: 50rpx;
}
.border_r{
border-right: 1px solid #E9E9E9;
border-top-right-radius: 50rpx;
border-bottom-right-radius: 50rpx;
}
}
.multishop_data_number{
width: 60rpx;
height: 50rpx;
font-size: 28rpx;
color: #333;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid #E9E9E9;
}
}
.footer_multi_btn{
margin: 0 28rpx 0 28rpx;
height:84rpx;
background-color: #FD3F3F;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
color: #FFFFFF;
border-radius: 50rpx;
}
}
}
.opy{
opacity: 0.3;
}
</style>