505 lines
16 KiB
Vue
505 lines
16 KiB
Vue
<template>
|
||
<page-meta :page-style="'overflow:'+(show?'hidden':'visible')"></page-meta>
|
||
<view class="main">
|
||
<!-- 头部区域 -->
|
||
<view class="head" :style="{'padding-top':headerHeight+'px'}" >
|
||
<view class="head_location" :class="storeName?'head_location_active':''" @click="location()"><text class="location_title">{{storeName||'正在获取定位'}}</text></view>
|
||
<view class="head_ul">
|
||
<view class="head_l">
|
||
<view class="head_q">购物车</view>
|
||
<view class="head_w">我常买</view>
|
||
</view>
|
||
<view class="head_r">
|
||
<view class="head_li" @click.stop="OpenCoupon()">优惠券(3)</view>
|
||
<view class="head_li" :class="showEdit?'head_edit':''" @click.stop="edit">{{showEdit?'退出管理':'管理'}}</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="cont">
|
||
<view class="head_fixed" :style="{'height':75+headerHeight+'px'}">下拉刷新...</view>
|
||
<view class="cart">
|
||
<view style="height: 10rpx;"></view>
|
||
<template v-if="cartList.length">
|
||
<uni-swipe-action>
|
||
<uni-swipe-action-item v-for="(item,index) in cartList" :key="index" :right-options="options" @click="removeCart(1,item)">
|
||
<view class="cart_item">
|
||
<view class="cart_selected" @click="checkedShop(item)">
|
||
<view :class="item.isSelect === 1?'cart_selected_true':'cart_selected_false'">
|
||
<image v-if="item.isSelect" src="../../static/selected.png"></image>
|
||
</view>
|
||
</view>
|
||
<view class="cart_shop">
|
||
<image class="cart_shop_img" :src="item.image" mode="widthFix"></image>
|
||
</view>
|
||
<view class="cart_shop_cont">
|
||
<view class="cart_title"><text class="cart_text">{{item.storeName}}</text></view>
|
||
<view class="cart_desc">{{item.desc}}</view>
|
||
<view class="cart_bottom">
|
||
<view class="cart_price price">{{item.price}}<!--<text class="market_name prices">59.9</text>--></view>
|
||
<view class="cart_counter" v-if="showEdit" @click="removeCart(1,item)">
|
||
<view class="cart_remove">删除</view>
|
||
</view>
|
||
<view class="cart_counter" v-else>
|
||
<view class="cart_counter_btn border_l" @click="editAmount(1,item)">
|
||
<image class="cart_counter_btn_img" src="https://zhkj1.oss-cn-shanghai.aliyuncs.com/zhscMerchant/minus.png" mode="widthFix"></image>
|
||
</view>
|
||
<view class="cart_counter_center">{{item.cartNum}}</view>
|
||
<view class="cart_counter_btn border_r" @click="editAmount(2,item)">
|
||
<image class="cart_counter_btn_img" src="https://zhkj1.oss-cn-shanghai.aliyuncs.com/zhscMerchant/add.png" mode="widthFix"></image>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- <view class="cart_items" v-if="item.type == 2">
|
||
<view class="cart_t">
|
||
<view class="cart_selected">
|
||
<view :class="item.isSelect?'cart_selected_true':'cart_selected_false'">
|
||
<image v-if="item.isSelect" src="../../static/selected.png"></image>
|
||
</view>
|
||
</view>
|
||
<view class="cart_view_scroll">
|
||
<view class="cart_scroll">
|
||
<scroll-view class="cart_scroll_ul" :scroll-with-animation="true" :enhanced="true" :show-scrollbar="false" scroll-x="true">
|
||
<view class="cart_scroll_li" v-for="(i,index) in item.list">
|
||
<view class="cart_scroll_img">
|
||
<image class="cart_scroll_img_url" :src="i.imgUrl" mode="widthFix"></image>
|
||
</view>
|
||
<view class="cart_scroll_title">{{i.title}}</view>
|
||
<view class="cart_scroll_price price">{{i.price}}<text class="market_name prices">59.9</text></view>
|
||
</view>
|
||
|
||
</scroll-view>
|
||
</view>
|
||
<view class="cart_bottom">
|
||
<view class=""></view>
|
||
<view class="cart_counter" v-if="showEdit" @click="removeCart(1,item)">
|
||
<view class="cart_remove">删除</view>
|
||
</view>
|
||
<view class="cart_counter" v-else>
|
||
<view class="cart_counter_btn border_l">
|
||
<image class="cart_counter_btn_img" src="https://zhkj1.oss-cn-shanghai.aliyuncs.com/zhscMerchant/minus.png" mode="widthFix"></image>
|
||
</view>
|
||
<view class="cart_counter_center">1</view>
|
||
<view class="cart_counter_btn border_r">
|
||
<image class="cart_counter_btn_img" src="https://zhkj1.oss-cn-shanghai.aliyuncs.com/zhscMerchant/add.png" mode="widthFix"></image>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view> -->
|
||
</uni-swipe-action-item>
|
||
</uni-swipe-action>
|
||
</template>
|
||
<!-- 失效商品 -->
|
||
<view class="cart_lose" v-if="cartList_invalid.length">
|
||
<view class="cart_lose_top">
|
||
<view class="cart_lose_top_l">共{{cartList_invalid.length}}款失效商品</view>
|
||
<view class="cart_lose_top_r">一键清空</view>
|
||
</view>
|
||
<view class="cart_lose_bottom" v-for="(item,index) in cartList_invalid" :key="index">
|
||
<view class="cart_lose_img">
|
||
<view class="cart_lose_bcg">
|
||
<view class="cart_lose_text">商品已下架</view>
|
||
</view>
|
||
<image class="cart_lose_img_url" :src="item.image" mode="widthFix"></image>
|
||
</view>
|
||
<view class="cart_lose_ly">
|
||
<view class="cart_lose_title">{{item.storeName}}</view>
|
||
<view class="cart_lose_desc">商品下架了</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="empty" v-if="iscartShow && !cartList.length && !cartList_invalid.length">
|
||
<view class="empty_cont">
|
||
<image class="empty_cont_img" src="../../static/Empty/cart.png" mode="widthFix"></image>
|
||
<view class="empty_cont_title">购物车还是空的,快去加购吧</view>
|
||
<view class="empty_cont_btn">去逛逛</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<template>
|
||
<recomGoods v-if="iscartListLoaded" :apiType="5" @updatecart="cartType"></recomGoods>
|
||
</template>
|
||
<view style="height: 200rpx;"></view>
|
||
<view class="footer" v-if="cartList.length">
|
||
<view class="footer_l">
|
||
<view class="footer_selected" @click="allChecked">
|
||
<view :class="allCheckedShow?'footer_selected_true':'footer_selected_false'">
|
||
<image v-if="allCheckedShow" src="../../static/selected.png"></image>
|
||
</view>
|
||
<view class="footer_text">全选</view>
|
||
</view>
|
||
</view>
|
||
<view class="footer_r">
|
||
<view class="footer_edit" v-if="showEdit">
|
||
<view class="footer_edit_li footer_edit_li_border" @click="removeCart(2)">一键清空</view>
|
||
<view class="footer_edit_li" @click="removeCart(3)">删除</view>
|
||
</view>
|
||
<block v-else>
|
||
<view class="footer_v">
|
||
<view class="footer_text">合计:</view>
|
||
<view class="footer_price">{{totalPrice}}</view>
|
||
</view>
|
||
<view class="footer_btn" :class="!totalPrice?'opy':''" @click="orderConfirm">去结算</view>
|
||
</block>
|
||
</view>
|
||
</view>
|
||
|
||
<uni-popup ref="couponPopup" type="bottom" @change="changeCoupon">
|
||
<view class="shop_open shop_open_bcg">
|
||
<view class="shop_open_title">优惠券<view class="shop_open_close" @click="OpenCoupon()"><image src="../../static/order/close.png" mode="widthFix"></image></view></view>
|
||
<view class="shop_open_desc">可使用券(2)</view>
|
||
<view class="coupon_cont">
|
||
<view class="coupon_item">
|
||
<view class="coupon_item_l">
|
||
<view class="coupon_item_absolute"></view>
|
||
<view class="coupon_item_v">
|
||
<view class="coupon_item_price">5</view>
|
||
<view class="coupon_item_desc">满39可用</view>
|
||
</view>
|
||
</view>
|
||
<view class="coupon_item_border"></view>
|
||
<view class="coupon_item_r">
|
||
<view class="coupon_item_r_l">
|
||
<view class="coupon_item_name">新人限时券</view>
|
||
<view class="coupon_item_time">今日23:59到期</view>
|
||
</view>
|
||
<view class="coupon_item_r_r">领取</view>
|
||
</view>
|
||
</view>
|
||
<view class="coupon_item">
|
||
<view class="coupon_item_l">
|
||
<view class="coupon_item_absolute"></view>
|
||
<view class="coupon_item_v">
|
||
<view class="coupon_item_price">10</view>
|
||
<view class="coupon_item_desc">满59可用</view>
|
||
</view>
|
||
</view>
|
||
<view class="coupon_item_border"></view>
|
||
<view class="coupon_item_r">
|
||
<view class="coupon_item_r_l">
|
||
<view class="coupon_item_name">新人限时券</view>
|
||
<view class="coupon_item_time">今日23:59到期</view>
|
||
</view>
|
||
<view class="coupon_item_r_r">领取</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</uni-popup>
|
||
<!-- 获取定位失败小组件提示 -->
|
||
<locationOpen></locationOpen>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import NP from 'number-precision';
|
||
import { loads } from '@/utils/index.js'
|
||
import recomGoods from '@/components/recomGoods/recomGoods.vue';
|
||
import { ref,computed } from 'vue';
|
||
import { useCounterStore } from '@/store/counter'; // 引入Pinia Store
|
||
import { storeToRefs } from 'pinia';//实现解构付值
|
||
import { onLoad,onShow,onPullDownRefresh,onReachBottom } from "@dcloudio/uni-app"
|
||
import { cartlist,cartnum,cartdelete,preorder,optForCart } from "@/server/api.js"
|
||
const counterStore = useCounterStore(); // 使用 Store
|
||
//使用pinia:storeToRefs方法包裹(保持响应式更新,不使用视图无法更新)
|
||
const {statusHeight,headerHeight,token,storeName,storeId,latitude,longitude,locationShow } = storeToRefs(counterStore);
|
||
const couponPopup = ref(null);
|
||
const couponShow = ref(false);
|
||
const show = ref(false);
|
||
const showEdit = ref(false);
|
||
const cartList = ref([]);
|
||
const cartList_invalid = ref([]);
|
||
const allCheckedShow = ref(false)
|
||
const cartpages = ref(0);
|
||
const cartdecs = ref("");
|
||
const iscartListLoaded = ref(false)
|
||
const iscartShow = ref(false);
|
||
const carttotal = ref(0)
|
||
const options = ref([
|
||
{
|
||
text: '删除',
|
||
style: {
|
||
backgroundColor: '#FD4955'
|
||
}
|
||
}
|
||
]);
|
||
const OpenCoupon =() =>{
|
||
couponShow.value ? couponPopup.value.close():couponPopup.value.open()
|
||
};
|
||
const changeCoupon = (e)=>{
|
||
couponShow.value = e.show;
|
||
show.value = e.show;
|
||
};
|
||
const edit = (e)=>{
|
||
showEdit.value ? showEdit.value = false:showEdit.value = true;
|
||
};
|
||
const cartType = (type)=>{
|
||
api_cartlist(true);
|
||
}
|
||
const goDetail= ()=>{
|
||
uni.navigateTo({
|
||
url:`/shopProDetail/detail/detail`
|
||
})
|
||
}
|
||
|
||
//购物车有效商品
|
||
const api_cartlist = (e) =>{
|
||
if(e){
|
||
// cartList.value = [];
|
||
// cartdecs.value = '';
|
||
// cartpages.value = 0;
|
||
iscartShow.value = false;
|
||
}
|
||
cartdecs.value = "—— 加载中... ——";
|
||
// cartpages.value = cartpages.value + 1;
|
||
loads('', true)
|
||
const params = {isValid:"1",page:'1',limit:'100'}
|
||
return cartlist(params).then(({data})=>{
|
||
uni.hideLoading()
|
||
cartdecs.value = '—— 上拉加载更多 ——'
|
||
if(data.list.length < 10){
|
||
cartdecs.value = '—— 嗷呜,已经到底啦 ——';
|
||
}
|
||
//更改全选状态
|
||
const allSelected = data.list.every(item => item.isSelect === 1);
|
||
if(allSelected){
|
||
allCheckedShow.value = true;
|
||
}else{
|
||
allCheckedShow.value = false;
|
||
}
|
||
cartList.value = data.list;
|
||
carttotal.value = data.total;
|
||
})
|
||
.then(()=>{
|
||
if(e){api_cartlist_invalid(true)}
|
||
})
|
||
.catch(({message}) => {
|
||
uni.hideLoading()
|
||
uni.showModal({
|
||
content:message,
|
||
showCancel: false
|
||
})
|
||
})
|
||
}
|
||
//购物车无效商品
|
||
const api_cartlist_invalid = (empty) =>{
|
||
// if(empty){
|
||
// cartList_invalid.value = [];
|
||
// }
|
||
const params = {isValid:"0",page:'1',limit:'50'}
|
||
return cartlist(params).then(({data})=>{
|
||
uni.hideLoading()
|
||
cartList_invalid.value = data.list;
|
||
iscartListLoaded.value = true
|
||
iscartShow.value = true
|
||
})
|
||
.catch(({message}) => {
|
||
uni.hideLoading()
|
||
uni.showModal({
|
||
content:message,
|
||
showCancel: false
|
||
})
|
||
})
|
||
}
|
||
//编辑购物车商品数量
|
||
const editAmount=(type,data)=>{
|
||
console.log('data',data);
|
||
let { id,cartNum } = data;
|
||
//加/减数量
|
||
if(cartNum == 1 && type == 1) return false;
|
||
let number = type == 1 ? cartNum - 1 : cartNum + 1;
|
||
loads('', true)
|
||
return cartnum(id,number).then(({message})=>{
|
||
uni.hideLoading()
|
||
cartList.value.forEach(item=>{
|
||
if(id == item.id){
|
||
item.cartNum = type == 1 ? item.cartNum - 1 : item.cartNum + 1;
|
||
}
|
||
})
|
||
}).catch(({message}) => {
|
||
uni.hideLoading()
|
||
uni.showModal({
|
||
content:message,
|
||
showCancel: false
|
||
})
|
||
})
|
||
};
|
||
//全选
|
||
const allChecked=()=>{
|
||
let cartType = "";
|
||
if(allCheckedShow.value){
|
||
cartType = "no"
|
||
}else{
|
||
cartType = "yes"
|
||
}
|
||
api_optForCart(2,0,cartType);
|
||
};
|
||
//商品选中未选中
|
||
const checkedShop=(e)=>{
|
||
let cartType = ""
|
||
if(e.isSelect){
|
||
cartType = "no"
|
||
}else{
|
||
cartType = "yes"
|
||
}
|
||
api_optForCart(1,e.id,cartType);
|
||
};
|
||
const api_optForCart=(type,cartIds,cartType)=>{
|
||
const params = {cartType}
|
||
if(type == 1){
|
||
params.cartIds = cartIds
|
||
}
|
||
loads('', true)
|
||
return optForCart(params).then(({data})=>{
|
||
uni.hideLoading()
|
||
if(type == 1){
|
||
//更改单商品选中状态
|
||
cartList.value.forEach((item,index)=>{
|
||
if(cartIds == item.id){
|
||
item.isSelect = item.isSelect === 1 ? 0 : 1
|
||
}
|
||
})
|
||
//更改全选状态
|
||
const allSelected = cartList.value.every(item => item.isSelect === 1);
|
||
allCheckedShow.value =allSelected ? true : false;
|
||
}else{
|
||
allCheckedShow.value = cartType == "yes" ? true : false;
|
||
cartList.value.forEach((item,index)=>{
|
||
item.isSelect = cartType == "yes" ? 1 : 0;
|
||
})
|
||
}
|
||
})
|
||
.catch(({message}) => {
|
||
uni.hideLoading()
|
||
uni.showModal({
|
||
content:message,
|
||
showCancel: false
|
||
})
|
||
})
|
||
}
|
||
//计算总价
|
||
const totalPrice = computed(() => {
|
||
//过滤出选中的对象
|
||
const selectedItems = cartList.value.filter(item => item.isSelect === 1);
|
||
//计算总价(考虑数量)
|
||
return selectedItems.reduce((sum, item) => NP.round(NP.plus(sum,NP.times(item.price,item.cartNum)),2), 0);
|
||
});
|
||
//选中多少数件
|
||
const selectedAmount = computed(() => {
|
||
//过滤出选中的对象
|
||
const selectedItems = cartList.value.filter(item => item.isSelect === 1);
|
||
return selectedItems.length
|
||
});
|
||
const removeCart=(type,item)=>{
|
||
let content = '';
|
||
if(type == 1){
|
||
content = "确定要删除此商品吗?"
|
||
}else if(type == 2){
|
||
content = "确定要清空购物车所有商品吗?"
|
||
}else{
|
||
content = `确定要删除购物车选中的${selectedAmount.value}种商品吗?`
|
||
}
|
||
uni.showModal({
|
||
content:content,
|
||
confirmText:type == 2?'清空':'删除',
|
||
confirmColor:'#F14D48',
|
||
success: ({confirm}) => {
|
||
if (confirm) {
|
||
if(type == 1){
|
||
api_cartdelete(type,item.id);
|
||
}else if(type == 2){
|
||
const ids = cartList.value.map(item => item.id);
|
||
api_cartdelete(type,ids)
|
||
}else{
|
||
//过滤出选中的对象
|
||
const ids = cartList.value.filter(item => item.isSelect === 1).map(item => item.id);
|
||
api_cartdelete(type,ids)
|
||
}
|
||
}
|
||
}
|
||
})
|
||
};
|
||
const api_cartdelete = (type,ids) => {
|
||
loads('', true)
|
||
return cartdelete(ids).then(({message})=>{
|
||
uni.hideLoading()
|
||
if(type == 1){
|
||
cartList.value = cartList.value.filter(item => item.id !== ids);
|
||
}else{
|
||
cartList.value = cartList.value.filter(item => !ids.includes(item.id));
|
||
}
|
||
if(showEdit.value){ showEdit.value = false }
|
||
})
|
||
.catch(({message}) => {
|
||
uni.hideLoading()
|
||
uni.showModal({
|
||
content:message,
|
||
showCancel: false
|
||
})
|
||
})
|
||
}
|
||
//预下单
|
||
const orderConfirm = () => {
|
||
const orderDetails = cartList.value.filter(item => item.isSelect === 1).map(item => ({shoppingCartId:item.id}));
|
||
if(!orderDetails.length){
|
||
uni.showToast({
|
||
title:'请选中商品后,在结算',
|
||
icon:'none'
|
||
})
|
||
return false
|
||
}
|
||
loads('', true)
|
||
let params = {
|
||
merId:storeId.value,
|
||
orderDetails,
|
||
preOrderType:'shoppingCart'
|
||
};
|
||
return preorder(params).then(({data})=>{
|
||
uni.hideLoading();
|
||
uni.navigateTo({
|
||
url:`/order/orderConfirm/orderConfirm?preOrderNo=${data.preOrderNo}`
|
||
})
|
||
})
|
||
.catch(({message}) => {
|
||
uni.hideLoading()
|
||
uni.showModal({
|
||
content:message,
|
||
showCancel: false
|
||
})
|
||
})
|
||
}
|
||
|
||
const location=()=>{
|
||
if(locationShow.value) return false;
|
||
uni.navigateTo({
|
||
url:`/userserve/location/location`
|
||
})
|
||
}
|
||
//使用 uni.onLoad 监听页面加载
|
||
onLoad((options) => {});
|
||
onShow(() => {
|
||
api_cartlist(true);
|
||
});
|
||
onPullDownRefresh(()=>{
|
||
api_cartlist(true);
|
||
uni.stopPullDownRefresh();
|
||
})
|
||
onReachBottom(()=>{
|
||
// api_cartlist(false);
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
@import './style.scss';
|
||
.uni-swipe{
|
||
margin: 0rpx 20rpx 0rpx 20rpx !important;
|
||
margin-bottom: 20rpx !important;
|
||
border-radius: 25rpx !important;
|
||
background-color: #fff !important;
|
||
}
|
||
</style> |