Springboot3 + MyBatis-Plus + MySql + Uniapp 商品加入购物车功能实现(针对上一篇sku)
- 1、效果展示
- 2、后端代码
-
- [2.1 model](#2.1 model)
- [2.2 mapper server serverImpl 参照上一篇自动生成](#2.2 mapper server serverImpl 参照上一篇自动生成)
- [2.3 controller](#2.3 controller)
- 3、前端代码
-
- [3.1 index.js](#3.1 index.js)
- [3.2 shop-info.vue](#3.2 shop-info.vue)
- [3.3 ShopBottomButton.vue](#3.3 ShopBottomButton.vue)
- [3.4 shop-cart.vue](#3.4 shop-cart.vue)
本文章基于上一篇文章 Springboot3 + MyBatis-Plus + MySql + Uniapp 实现商品规格选择sku(附带自设计数据库,最新保姆级教程)
1、效果展示
2、后端代码
2.1 model
java
package com.zhong.model.entity.shop;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.math.BigDecimal;
import java.util.Date;
import com.zhong.model.entity.BaseEntity;
import lombok.Data;
/**
*
* @TableName shop_cart
*/
@TableName(value ="shop_cart")
@Data
public class ShopCart extends BaseEntity {
/**
* 商品ID
*/
private Integer goodsId;
/**
* 附加信息 "自营"
*/
private String businessName;
/**
* 商品店铺
*/
private String shopName;
/**
* 商品主图
*/
private String mainImage;
/**
* 商品标题
*/
private String title;
/**
* 商品价格
*/
private BigDecimal price;
/**
* 商品数量
*/
private Integer goodsNum;
/**
* 购物车所属用户id
*/
private Integer userId;
/**
* 所选商品规格id
*/
private Integer goodsSpecsId;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}
2.2 mapper server serverImpl 参照上一篇自动生成
ShopCartService
java
package com.zhong.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zhong.model.entity.shop.ShopCart;
import com.zhong.vo.shop.ShopCartVo;
import com.zhong.vo.shop.ShopSkuVo;
/**
* @author zhong
* @description 针对表【shop_cart】的数据库操作Service
* @createDate 2024-09-19 10:53:15
*/
public interface ShopCartService extends IService<ShopCart> {
Page<ShopCartVo> pageItem(Page<ShopCart> page);
ShopSkuVo getSpecsById(Long id);
}
ShopCartServiceImpl
java
package com.zhong.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhong.login.LoginUserHolder;
import com.zhong.mapper.shop.ShopCartMapper;
import com.zhong.mapper.shop.ShopSpecsMapper;
import com.zhong.model.entity.shop.ShopCart;
import com.zhong.model.entity.shop.ShopSku;
import com.zhong.model.entity.shop.ShopSpecs;
import com.zhong.service.ShopCartService;
import com.zhong.service.ShopSkuService;
import com.zhong.vo.shop.ShopCartVo;
import com.zhong.vo.shop.ShopSkuVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* @author zhong
* @description 针对表【shop_cart】的数据库操作Service实现
* @createDate 2024-09-19 10:53:15
*/
@Service
public class ShopCartServiceImpl extends ServiceImpl<ShopCartMapper, ShopCart>
implements ShopCartService {
@Autowired
private ShopCartMapper shopCartMapper;
@Autowired
private ShopSpecsMapper shopSpecsMapper;
@Autowired
private ShopSkuService shopSkuService;
@Override
public Page<ShopCartVo> pageItem(Page<ShopCart> page) {
Long userId = LoginUserHolder.getLoginUser().getUserId();
LambdaQueryWrapper<ShopCart> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ShopCart::getIsDeleted, 0)
.eq(ShopCart::getUserId, userId);
// 获取所有购物车列表
Page<ShopCart> shopCartPage = shopCartMapper.selectPage(page, queryWrapper);
// 初始化返回的 ShopCartVo 分页对象
Page<ShopCartVo> shopCartVoPage = new Page<>(shopCartPage.getCurrent(), shopCartPage.getSize(), shopCartPage.getTotal());
// 获取 ShopCart 列表
List<ShopCart> shopCartList = shopCartPage.getRecords();
List<ShopCartVo> shopCartListVo = new ArrayList<>();
// 遍历 ShopCart 列表并转换为 ShopCartVo 列表
for (ShopCart shopCart : shopCartList) {
ShopCartVo shopCartVo = new ShopCartVo();
// 使用 BeanUtils 复制属性
BeanUtils.copyProperties(shopCart, shopCartVo);
// 获取商品规格信息并设置到 ShopCartVo 中
Integer specsId = shopCart.getGoodsSpecsId();
if (specsId != null) {
ShopSkuVo shopSkuVo = getSpecsById(Long.valueOf(specsId));
shopCartVo.setSpecs(shopSkuVo);
}
// 添加到 ShopCartVo 列表
shopCartListVo.add(shopCartVo);
}
// 将转换后的 ShopCartVo 列表设置到分页对象中
shopCartVoPage.setRecords(shopCartListVo);
return shopCartVoPage;
}
@Override
public ShopSkuVo getSpecsById(Long id) {
ShopSkuVo shopSkuVo = new ShopSkuVo();
ShopSpecs shopSpecs = shopSpecsMapper.selectById(id);
// 新建一个规格详情信息 Vo 方便后续添加到 shopSkuVo
List<ShopSku> skuArrayList = new ArrayList<>();
if (shopSpecs.getSku1() != null) {
// 新建一个 shopSku 方便添加到 List<ShopSku>
ShopSku shopSku = new ShopSku();
// 根据规格ID获取规格详情
ShopSku sku = shopSkuService.getById(shopSpecs.getSku1());
shopSkuVo.setId(shopSpecs.getId());
shopSku.setAttr(sku.getAttr());
// 将规格值添加到 shopSku
shopSku.setAttrValue(sku.getAttrValue());
skuArrayList.add(shopSku);
}
if (shopSpecs.getSku2() != null) {
// 新建一个 shopSku 方便添加到 List<ShopSku>
ShopSku shopSku = new ShopSku();
// 根据规格ID获取规格详情
ShopSku sku = shopSkuService.getById(shopSpecs.getSku2());
shopSkuVo.setId(shopSpecs.getId());
shopSku.setAttr(sku.getAttr());
// 将规格值添加到 shopSku
shopSku.setAttrValue(sku.getAttrValue());
skuArrayList.add(shopSku);
}
if (shopSpecs.getSku3() != null) {
// 新建一个 shopSku 方便添加到 List<ShopSku>
ShopSku shopSku = new ShopSku();
// 根据规格ID获取规格详情
ShopSku sku = shopSkuService.getById(shopSpecs.getSku3());
shopSkuVo.setId(shopSpecs.getId());
shopSku.setAttr(sku.getAttr());
// 将规格值添加到 shopSku
shopSku.setAttrValue(sku.getAttrValue());
skuArrayList.add(shopSku);
}
if (shopSpecs.getSku4() != null) {
// 新建一个 shopSku 方便添加到 List<ShopSku>
ShopSku shopSku = new ShopSku();
// 根据规格ID获取规格详情
ShopSku sku = shopSkuService.getById(shopSpecs.getSku4());
shopSkuVo.setId(shopSpecs.getId());
shopSku.setAttr(sku.getAttr());
// 将规格值添加到 shopSku
shopSku.setAttrValue(sku.getAttrValue());
skuArrayList.add(shopSku);
}
shopSkuVo.setSkus(skuArrayList);
shopSkuVo.setPrice(shopSpecs.getPrice());
return shopSkuVo;
}
}
2.3 controller
java
package com.zhong.controller.shop;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhong.login.LoginUserHolder;
import com.zhong.model.entity.shop.ShopCart;
import com.zhong.result.Result;
import com.zhong.service.ShopCartService;
import com.zhong.vo.shop.ShopCartVo;
import com.zhong.vo.shop.ShopInfoVo;
import com.zhong.vo.shop.ShopSkuVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @ClassName : ShopCartController
* @Description :
* @Author : zhx
* @Date: 2024-09-19 10:55
*/
@RestController
@RequestMapping("/app/shop/cart")
@Tag(name = "购物车信息")
public class ShopCartController {
@Autowired
private ShopCartService service;
@Operation(summary = "添加到购物车")
@PostMapping("add")
public Result getDetailById(@RequestBody ShopCart shopCart) {
// 判断是否存在
LambdaQueryWrapper<ShopCart> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ShopCart::getIsDeleted, 0)
.eq(ShopCart::getGoodsSpecsId, shopCart.getGoodsSpecsId());
ShopCart dbShopCart = service.getOne(queryWrapper);
if(dbShopCart != null) {
dbShopCart.setPrice(dbShopCart.getPrice().add(shopCart.getPrice()));
dbShopCart.setGoodsNum(dbShopCart.getGoodsNum() + shopCart.getGoodsNum());
service.saveOrUpdate(dbShopCart);
}else {
Long userId = LoginUserHolder.getLoginUser().getUserId();
shopCart.setUserId(Math.toIntExact(userId));
shopCart.setIsDeleted((byte) 0);
service.saveOrUpdate(shopCart);
}
return Result.ok();
}
@Operation(summary = "分页获取购物车商品信息")
@GetMapping("listItem")
public Result<Page<ShopCartVo>> listItem(@RequestParam long current, @RequestParam long size) {
Page<ShopCart> shopCartPage = new Page<>(current, size);
Page<ShopCartVo> page = service.pageItem(shopCartPage);
return Result.ok(page);
}
@Operation(summary = "根据id获取商品规格")
@GetMapping("getSpecsById")
public Result<ShopSkuVo> getSpecsById(@RequestParam Long id) {
ShopSkuVo shopSkuVo = service.getSpecsById(id);
return Result.ok(shopSkuVo);
}
}
3、前端代码
3.1 index.js
js
import http from '@/utils/request.js';
export const getAllShopApi = (params) => {
return http.get(`/app/shop/listItem?current=${params.current}&size=${params.size}`)
}
export const getShopByIdApi = (id) => {
return http.get(`/app/shop/getDetailById?id=${id}`)
}
// 添加到购物车
export const addShopToCartApi = (params) => {
return http.post(`/app/shop/cart/add`, params)
}
// 分页获取购物车
export const getAllShopCartApi = (params) => {
return http.get(`/app/shop/cart/listItem?current=${params.current}&size=${params.size}`)
}
3.2 shop-info.vue
js
<template>
<view>
<template v-for="(item, index) in [data]" :key="index">
<view class="">
<up-swiper :list="item.shopImgSwiper" circular :autoplay="true" bgColor="#ffffff" height="360rpx"
imgMode="auto"></up-swiper>
</view>
<view class="connect card card-shadow">
<view class="price">
<view class="">
<up-text mode="price" :text="item.newPrice" color="red" size="24"></up-text>
</view>
<view class="">
<text>已售{{item.saleNumber}}</text>
</view>
</view>
<!-- 标题 -->
<view class="title">
<up-row customStyle="margin-bottom: 10px">
<up-col span="2" v-if="item.businessName">
<view class="" style="display: flex;">
<up-tag :text="item.businessName" size="mini" type="error"></up-tag>
</view>
</up-col>
<up-col :span="item.businessName?10 :12">
<text>{{item.title}}</text>
</up-col>
</up-row>
</view>
<!-- 发货 -->
<view class="logistics flex" style=" position: relative;">
<up-icon name="car"></up-icon>
<view class="" style="width: 20rpx;"></view>
<view class="font-lite-size">
<text>承诺24小时内发货,晚发必赔</text>
</view>
<view class="" style="position: absolute;right: 10rpx;">
<up-icon name="arrow-right"></up-icon>
</view>
</view>
<!-- 破损 -->
<view class="pock flex" style=" position: relative;">
<up-icon name="car"></up-icon>
<view class="" style="width: 20rpx;"></view>
<view class="font-lite-size">
<text>破损包退 | 退货运费险 | 极速退款 | 7天无理由退换</text>
</view>
<view class="" style="position: absolute;right: 10rpx;">
<up-icon name="arrow-right" size="16"></up-icon>
</view>
</view>
</view>
<!-- 评价 -->
<view class="card card-shadow">
<ShopCommentVue></ShopCommentVue>
</view>
<!-- 店铺信息 -->
<view class="card card-shadow">
<StoreInformationVue></StoreInformationVue>
</view>
<!-- 商品详情图片 -->
<view class="bb-info card card-shadow" v-if="data.shopImgInfo.length> 0">
<ShopInfoImageListVue :imgList="data.shopImgInfo"></ShopInfoImageListVue>
</view>
<!-- 提示 -->
<view class="tips card card-shadow">
<ShopTipsVue></ShopTipsVue>
</view>
<!-- 底部tabbar安全距离 -->
<view class="" style="height: 140rpx;">
</view>
</template>
<!-- 加入购物车等操作 -->
<view class="bottom">
<ShopBottomButtonVue :data="data"></ShopBottomButtonVue>
</view>
</view>
</template>
<script setup>
import {
reactive,
ref,
onMounted
} from 'vue';
import ShopCommentVue from '@/pages/components/Home/ShopComment.vue';
import StoreInformationVue from '@/pages/components/Home/StoreInformation.vue';
import ShopInfoImageListVue from '@/pages/components/Home/ShopInfoImageList.vue';
import ShopTipsVue from '@/pages/components/Home/ShopTips.vue';
import ShopBottomButtonVue from '@/pages/components/Home/ShopBottomButton.vue';
import {
onLoad
} from "@dcloudio/uni-app"
import {
getShopByIdApi
} from "@/pages/api/shop/index.js"
const shopId = ref();
const data = ref();
onLoad((options) => {
shopId.value = options.id;
})
onMounted(async () => {
console.log(shopId.value);
let res = await getShopByIdApi(shopId.value);
data.value = res;
console.log(res);
})
// 父组件中的价格数据
const price = ref(null);
// 处理子组件传来的价格更新
const handlePriceUpdate = (newPrice) => {
price.value = newPrice;
};
</script>
<style lang="less" scoped>
.card-shadow {
border-radius: 20rpx;
box-shadow: 10rpx 10rpx 10rpx 10rpx rgba(0.2, 0.1, 0.2, 0.2);
}
.card {
margin: 20rpx;
padding: 20rpx;
background-color: #FFF;
border-radius: 20rpx;
}
.font-lite-size {
font-size: 26rpx;
}
.flex {
display: flex;
align-items: center;
}
.title {
margin-top: 20rpx;
}
.pock {
margin: 20rpx 0;
}
.price {
padding-right: 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
}
</style>
3.3 ShopBottomButton.vue
js
<template>
<view class="mains">
<view class="connect">
<view class="letf-connect">
<up-icon name="gift" size="40rpx"></up-icon>
<text style="font-size: 26rpx;">店铺</text>
</view>
<view class="letf-connect">
<up-icon name="kefu-ermai" size="40rpx"></up-icon>
<text style="font-size: 26rpx;">客服</text>
</view>
<view class="letf-connect" @click="toShopCart">
<up-icon name="shopping-cart" size="40rpx"></up-icon>
<text style="font-size: 26rpx;">购物车</text>
</view>
<view class="" style="display: flex;flex: 1;padding-left: 20rpx;">
<up-button text="加入购物车" type="warning" @click="addCartButtonFun"></up-button>
<up-button text="立即购买" type="success" @click="nowBuyFun"></up-button>
</view>
</view>
<!-- 弹出层选择商品规格 -->
<up-popup :show="show" mode="bottom" :round="10" @close="close" @open="open">
<view>
<view class="top">
<up-image :src="props.data.mainImage" width="200rpx" height="300rpx" radius="10"></up-image>
<view style="padding-left: 40rpx;">
<text style="flex: 1;overflow: hidden;">{{props.data.title}}</text>
<view style="padding: 20rpx 0;" v-if="calculatedPrice">
<up-text mode="price" :text="calculatedPrice" color="red" size="20"></up-text>
</view>
<view style="padding: 20rpx 0;" v-else>
<up-text mode="price" :text="props.data.newPrice * shopNum" color="red" size="20"></up-text>
</view>
<view style="display: flex;padding-top: 20rpx;">
<up-number-box v-model="shopNum" min="1"></up-number-box>
</view>
</view>
</view>
<!-- 渲染规格 -->
<view class="">
<template v-for="(item,index) in resSkuGroup">
<view style="padding-left: 20rpx;">{{item.key}}</view>
<view style="display: flex;">
<template v-for="(tag,i) in item.value" :key="i">
<view class="" style="display: flex;padding:20rpx;">
<up-tag :text="tag.info" :plain="!tag.isCheck" :color="tag.isCheck?'#FFF':'#000'"
:borderColor="tag.isCheck?'#FFF':'#000'" type="error"
@click="changeTagIsCheckFun(tag,index)"></up-tag>
</view>
</template>
</view>
</template>
</view>
<view class="" style="padding: 20rpx;" v-if="isBuy">
<up-button text="立即购买" shape="circle" type="error" @click="BuyShopFun"></up-button>
</view>
<view class="" style="padding: 20rpx;" v-else>
<up-button text="加入购物车" shape="circle" type="error" @click="addCartFun"></up-button>
</view>
</view>
</up-popup>
</view>
</template>
<script setup>
import {
computed,
onMounted,
reactive,
defineEmits,
watch,
ref
} from 'vue';
import {
addShopToCartApi
} from "@/pages/api/shop/index.js";
// 创建响应式数据
const props = defineProps({
data: Object
});
const show = ref(false);
const resData = ref();
const resSkuData = ref();
const resSkuGroup = ref();
const resDataFun = async () => {
resSkuGroup.value = await props.data.skuGroup;
resSkuData.value = await props.data.shopSpecs;
console.log(props.data.shopSpecs);
console.log(resSkuData.value);
}
const changeTagIsCheckFun = (item, index) => {
resSkuGroup.value[index].value.map(x => {
if (x.info == item.info) {
x.isCheck = true;
} else {
x.isCheck = false;
}
})
console.log(resSkuGroup.value);
}
// 通过 computed 计算选中的属性值
const checkedAttributes = computed(() => {
return resSkuGroup.value.map(option => ({
attr: option.key,
attrValue: option.value.find(item => item.isCheck)?.info || null
}));
});
// 商品数量
const shopNum = ref(1);
// 根据选中的属性值匹配 SKU,返回匹配的 SKU 对象
const matchingSku = computed(() => {
return resSkuData.value.find(sku => {
return sku.skus.every(skuAttr => {
return checkedAttributes.value.some(attr =>
attr.attr === skuAttr.attr && attr.attrValue === skuAttr.attrValue
);
});
});
});
// 计算匹配 SKU 的价格和 ID
const calculatedPrice = computed(() => {
return matchingSku.value ? matchingSku.value.price * shopNum.value : null;
});
const matchingSkuId = computed(() => {
return matchingSku.value ? matchingSku.value.id : null;
});
// 区分是加入购物车还是立即购买
const isBuy = ref(false);
// 加入购物车
const addCartButtonFun = () => {
show.value = true;
isBuy.value = false;
}
// 立即购买
const nowBuyFun = () => {
show.value = true;
isBuy.value = true;
}
// 立即购买操作
const BuyShopFun = () => {
}
onMounted(() => {
console.log(props.data);
resDataFun();
})
// 定义方法
const open = () => {
// 打开逻辑,比如设置 show 为 true
show.value = true;
// console.log('open');
}
const close = () => {
// 关闭逻辑,设置 show 为 false
show.value = false;
// console.log('close');
}
const toShopCart = () => {
uni.navigateTo({
url: "/pages/src/home/shop-cart/shop-cart"
})
}
// 添加到购物车
const addCartFun = async () => {
let res = {
businessName: props.data.businessName,
shopName: props.data.shopName,
mainImage: props.data.mainImage,
title: props.data.title,
price: calculatedPrice.value,
goodsId: props.data.id,
goodsNum: shopNum.value,
goodsSpecsId: matchingSkuId.value
}
console.log(res);
await addShopToCartApi(res);
close();
uni.showToast({
title: "添加成功",
icon: 'success'
})
}
</script>
<style lang="scss" scoped>
.top {
display: flex;
padding: 40rpx;
}
.mains {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
/* 占据全宽 */
height: 120rpx;
/* Tabbar 高度 */
background-color: #FFF;
border-top: 2rpx solid #7d7e80;
}
.connect {
display: flex;
justify-content: space-around;
padding: 20rpx;
align-items: center;
}
.letf-connect {
padding: 0 10rpx;
display: flex;
flex-direction: column;
align-items: center;
}
</style>
3.4 shop-cart.vue
js
<template>
<view class="">
<view class="" v-if="state.cartItems.length == 0">
<up-empty mode="car" icon="http://cdn.uviewui.com/uview/empty/car.png">
</up-empty>
</view>
<view class="card" v-else>
<template v-for="(info, j) in state.cartItems" :key="j">
<view class="cart-data card-shadow">
<view class="" style="display: flex;">
{{info.shopName}}<up-icon name="arrow-right"></up-icon>
</view>
<template v-for="(item, index) in info.items" :key="index">
<view class="" style="display: flex;padding: 20rpx 0;align-items: center;">
<view>
<up-checkbox :customStyle="{marginBottom: '8px'}" usedAlone
v-model:checked="item.isChoose" @change="toggleItemChoose(item.shopName, item.id)">
</up-checkbox>
</view>
<view class="cart-image">
<up-image :src="item.mainImage" mode="widthFix" height="200rpx" width="220rpx"
radius="10"></up-image>
</view>
<view>
<view class="cart-right">
<view style="margin-bottom: 10rpx;font-size: 30rpx;">{{item.title}}</view>
<view class="" v-if="item.specs" style="display: flex;">
<template v-for="(sku, i) in item.specs.skus">
<view
style="margin-bottom: 20rpx;font-size: 26rpx;color: #7d7e80;margin-right: 10rpx;">
{{sku.attr}}/{{sku.attrValue}}
</view>
</template>
</view>
<view class="" style="display: flex;align-items: center;">
<up-text mode="price" :text="item.price"></up-text>
<view class="" style="width: 10rpx;"></view>
<up-number-box v-model="item.goodsNum"
@change="val => changeItemQuantity(item,item.id, val.value)"
min="1"></up-number-box>
</view>
</view>
</view>
</view>
</template>
</view>
</template>
</view>
<view class="" style="height: 160rpx;">
</view>
<view class="foot card">
<view class="card-connect">
<up-checkbox :customStyle="{marginBottom: '8px'}" usedAlone v-model:checked="state.allChose"
@change="toggleAllChose">
</up-checkbox>
<view class="" style="display: flex; align-items: center;">
<view style="font-size: 28rpx;">全选</view>
<view style="padding-left: 20rpx;font-size: 24rpx;">已选{{selectedItemsCount}}件,合计</view>
<view class="" style="display: flex;flex: 1;">
<up-text mode="price" :text="totalSelectedPrice" color="red" size="18"></up-text>
</view>
</view>
<view class="" style="width: 20rpx;position: relative;">
</view>
<view class="" style="position: absolute;right: 40rpx;">
<view class="" style="display: flex;">
<up-button type="error" text="去结算" shape="circle" style="width: 150rpx;"
@click="toSubmitOrder"></up-button>
</view>
</view>
<up-toast ref="uToastRef"></up-toast>
</view>
</view>
</view>
</template>
<script setup>
import {
ref,
computed,
onMounted,
watch
} from 'vue';
import {
useCartStore
} from '@/pages/store/cart/cart.js'
import {
getAllShopCartApi
} from "@/pages/api/shop/index.js"
import {
storeToRefs
} from "pinia";
// 使用 Pinia store
const cartStore = useCartStore();
// 获取状态和操作
const {
state,
selectedItemsCount,
totalSelectedPrice,
selectedItems
} = storeToRefs(cartStore);
const {
toggleItemChoose,
changeItemQuantity,
toggleAllChose
} = cartStore;
const current = ref(1);
const size = ref(10);
onMounted(async () => {
let res = {
current: current.value,
size: size.value
}
// 恢复购物车数据
const response = await getAllShopCartApi(res)
console.log(response);
const groupedItems = [];
response.records.forEach(item => {
// 查找是否已经存在相同店铺名的对象
const shop = groupedItems.find(shop => shop.shopName === item.shopName);
if (shop) {
// 如果存在,直接将商品添加到该店铺的商品列表中
shop.items.push(item);
} else {
// 如果不存在,创建一个新的店铺对象,并将商品添加进去
groupedItems.push({
shopName: item.shopName,
items: [item]
});
}
});
console.log(groupedItems);
cartStore.setCartItems(groupedItems);
});
// 创建响应式数据
const show = ref(false);
// 方法
const uToastRef = ref(null)
const showToast = (params) => {
uToastRef.value.show(params);
}
const toSubmitOrder = () => {
if (selectedItems.value.length > 0) {
uni.navigateTo({
url: "/pages/src/home/submit-order/submit-order"
})
} else {
showToast({
type: 'default',
title: '默认主题',
message: "您还没有选择商品哦",
});
}
}
</script>
<style lang="scss" scoped>
.foot {
position: fixed;
bottom: 0;
left: 0;
width: 90%;
/* 占据全宽 */
height: 100rpx;
/* Tabbar 高度 */
background-color: #FFF;
display: flex;
align-items: center;
.card-connect {
display: flex;
align-items: center;
justify-content: space-between;
}
}
.card {
margin: 20rpx;
padding: 20rpx;
background-color: #FFF;
border-radius: 20rpx;
}
.card-shadow {
border-radius: 20rpx;
box-shadow: 10rpx 10rpx 10rpx 10rpx rgba(0.2, 0.1, 0.2, 0.2);
}
.cart-data {
margin-bottom: 40rpx;
padding: 20rpx;
display: flex;
flex-wrap: wrap;
align-items: center;
.cart-image {
flex: 1;
}
.cart-right {
display: flex;
flex-direction: column;
padding-left: 20rpx;
}
}
</style>