Springboot3 + MyBatis-Plus + MySql + Uniapp 商品加入购物车功能实现(最新教程附源码)

Springboot3 + MyBatis-Plus + MySql + Uniapp 商品加入购物车功能实现(针对上一篇sku)

  • 1、效果展示
  • 2、后端代码
    • 2.1 model
    • 2.2 mapper server serverImpl 参照上一篇自动生成
    • 2.3 controller
  • 3、前端代码
    • 3.1 index.js
    • 3.2 shop-info.vue
    • 3.3 ShopBottomButton.vue
    • 3.4 shop-cart.vue

本文章基于上一篇文章 Springboot3 + MyBatis-Plus + MySql + Uniapp 实现商品规格选择sku(附带自设计数据库,最新保姆级教程)

1、效果展示


在这里插入图片描述

2、后端代码

2.1 model

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

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

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 {@Autowiredprivate ShopCartMapper shopCartMapper;@Autowiredprivate ShopSpecsMapper shopSpecsMapper;@Autowiredprivate ShopSkuService shopSkuService;@Overridepublic 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;}@Overridepublic ShopSkuVo getSpecsById(Long id) {ShopSkuVo shopSkuVo = new ShopSkuVo();ShopSpecs shopSpecs = shopSpecsMapper.selectById(id);// 新建一个规格详情信息 Vo 方便后续添加到 shopSkuVoList<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());// 将规格值添加到 shopSkushopSku.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());// 将规格值添加到 shopSkushopSku.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());// 将规格值添加到 shopSkushopSku.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());// 将规格值添加到 shopSkushopSku.setAttrValue(sku.getAttrValue());skuArrayList.add(shopSku);}shopSkuVo.setSkus(skuArrayList);shopSkuVo.setPrice(shopSpecs.getPrice());return shopSkuVo;}
}

2.3 controller


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 {@Autowiredprivate 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

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

<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

<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 的价格和 IDconst 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

<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'}" usedAlonev-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"><viewstyle="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 storeconst 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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/429118.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机毕业设计hadoop+spark+hive新能源汽车销售数据分析系统 二手车销量分析 新能源汽车推荐系统 可视化大屏 汽车爬虫 机器学习

《HadoopSparkHive新能源汽车销售数据分析系统》开题报告 一、选题背景与意义 1.1 选题背景 随着全球对环境保护意识的增强和能源结构的转型&#xff0c;新能源汽车市场迅速崛起。新能源汽车的销售数据不仅反映了市场趋势和消费者偏好&#xff0c;还为企业决策、政府监管和政…

【玉米田】

题目 代码 #include <bits/stdc.h> using namespace std; typedef long long LL;const int mod 1e8; const int M 1 << 12; LL f[13][M]; int g[13]; vector<int> state; vector<int> p[M]; int n, m; bool check(int x) {return !(x & x <&…

“一屏显江山”,激光显示重构「屏中世界」

【潮汐商业评论/原创】 2024年国庆期间&#xff0c;曾感动过无数国人的舞蹈诗剧《只此青绿》改编的同名电影即将上映&#xff0c;而这一次观众们不必走进电影院&#xff0c;在家里打开官方合作的海信激光电视也能享受到同等的视听效果&#xff0c;这是激光电视在观影场景领域的…

java 获取集合a比集合b多出来的对象元素

public class OrderListEntity {/*** deprecated 对象集合的处理* param aData 集合a* param bData 集合b* return 返回集合a比集合b多出来的部分, 通过id判断*/public static List<OrderListEntity> AHasMoreThanBData(List<OrderListEntity> aData, List<Ord…

Stable Diffusion 使用详解(11)--- 场景ICON制作

目录 背景 controlNet 整体描述 Canny Lineart Depth 实际使用 AI绘制需求 绘制过程 PS打底 场景模型选择 设置提示词及绘制参数 controlnet 设置 canny 边缘 depth 深度 lineart 线稿 效果 背景 这段时间不知道为啥小伙伴似乎喜欢制作很符合自己场景的ICON。…

鸿蒙开发(HarmonyOS)组件化浅谈

众所周知&#xff0c;现在组件化在移动开发中是很常见的&#xff0c;那么组件化有哪些好处&#xff1a; 1. 提高代码复用性&#xff1a;组件化允许将应用程序的不同功能模块化&#xff0c;使得这些模块可以在不同的项目中重复使用&#xff0c;从而提高开发效率并减少重复工作。…

LabVIEW编程能力如何能突飞猛进

要想让LabVIEW编程能力实现突飞猛进&#xff0c;需要采取系统化的学习方法&#xff0c;并结合实际项目进行不断的实践。以下是一些提高LabVIEW编程能力的关键策略&#xff1a; 1. 扎实掌握基础 LabVIEW的编程本质与其他编程语言不同&#xff0c;它是基于图形化的编程方式&…

行业人工智能研究-Python自监督方式学习图像表示算法

学术界人工智能研究落后于工业界 摘要 行业或工业界在人工智能研究上超出学术界&#xff0c;并占据着大量的计算力&#xff0c;数据集和人才诱人的薪水和明朗的预期吸引大量人才离开学术界&#xff0c;涌入行业或工业界即使&#xff0c;比如Meta开源其人工智能模型&#xff0…

小程序地图展示poi帖子点击可跳转

小程序地图展示poi帖子点击可跳转 是类似于小红书地图功能的需求 缺点 一个帖子只能有一个点击事件&#xff0c;不适合太复杂的功能&#xff0c;因为一个markers只有一个回调回调中只有markerId可以使用。 需求介绍 页面有地图入口&#xff0c;点开可打开地图界面地图上展…

python:编写一个函数查找字符串中的最长公共前缀

最近在csdn网站上刷到一个题目&#xff0c;题目要求编写一个函数查找字符串中的最长公共前缀&#xff0c;题目如下&#xff1a; 给出的答案如下&#xff1a; from typing import List def longestCommonPrefix(strs:List[str]) -> str:if len(strs) 0:return i 0 #代…

2024/9/21 数学20题

常见概率可加性&#xff1a;

网络安全详解

目录 引言 一、网络安全概述 1.1 什么是网络安全 1.2 网络安全的重要性 二、网络安全面临的威胁 2.1 恶意软件&#xff08;Malware&#xff09; 2.2 网络钓鱼&#xff08;Phishing&#xff09; 2.3 中间人攻击&#xff08;Man-in-the-Middle Attack&#xff09; 2.4 拒…

Mac 搭建仓颉语言开发环境(Cangjie SDK)

文章目录 仓颉编程语言通用版本SDK Beta试用报名仓颉语言文档注册 GitCode登录 GitCode 下载 Cangjie SDK配置环境变量VSCode 插件VSCode 创建项目 仓颉编程语言通用版本SDK Beta试用报名 https://wj.qq.com/s2/14870499/c76f/ 仓颉语言文档 https://developer.huawei.com/c…

Redis——持久化策略

Redis持久化 Redis的读写操作都是在内存上&#xff0c;所以Redis性能高。 但是当重启的时候&#xff0c;或者因为特殊情况导致Redis崩了&#xff0c;就可能导致数据的丢失。 所以Redis采取了持久化的机制&#xff0c;重启的时候利用之间持久化的文件实现数据的恢复。 Redis提…

Golang | Leetcode Golang题解之第424题替换后的最长重复字符

题目&#xff1a; 题解&#xff1a; func characterReplacement(s string, k int) int {cnt : [26]int{}maxCnt, left : 0, 0for right, ch : range s {cnt[ch-A]maxCnt max(maxCnt, cnt[ch-A])if right-left1-maxCnt > k {cnt[s[left]-A]--left}}return len(s) - left }f…

PyCharm与Anaconda超详细安装配置教程

1、安装Anaconda&#xff08;过程&#xff09;-CSDN博客 2.创建虚拟环境conda create -n pytorch20 python3.9并输入conda activate pytorch20进入 3.更改镜像源conda/pip(只添加三个pip源和conda源即可) 4.安装PyTorch&#xff08;CPU版&#xff09; 5.安装Pycharm并破解&…

猫咪检测系统源码分享

猫咪检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …

USDT自动化交易【Pinoex】【自动化分析】【ChatGPT量化脚本】

Pinoex 是一个相对较新的加密货币交易平台&#xff0c;虽然具体的自动交易算法细节对外部用户可能并不公开&#xff0c;但我们可以讨论一般情况下加密货币自动交易算法的常见策略和方法。以下是一些可能会被类似平台或个人交易者使用的自动交易算法和策略。 1. 市场制造商&…

Google 扩展 Chrome 安全和隐私功能

过去一周&#xff0c;谷歌一直在推出新特性和功能&#xff0c;旨在让用户在 Chrome 上的桌面体验更加安全&#xff0c;最新的举措是扩展在多个设备上保存密钥的功能。 到目前为止&#xff0c;Chrome 网络用户只能将密钥保存到 Android 上的 Google 密码管理器&#xff0c;然后…

计算机网络17——IM聊天系统——客户端核心处理类框架搭建

目的 拆开客户端和服务端&#xff0c;使用Qt实现客户端&#xff0c;VS实现服务端 Qt创建项目 Qt文件类型 .pro文件&#xff1a;配置文件&#xff0c;决定了哪些文件参与编译&#xff0c;怎样参与编译 .h .cpp .ui&#xff1a;画图文件 Qt编码方式 Qt使用utf-8作为编码方…