Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)二十一(购物车

读者福利

秋招我借这份PDF的复习思路,收获美团,小米,京东等Java岗offer

更多笔记分享

秋招我借这份PDF的复习思路,收获美团,小米,京东等Java岗offer

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

methods: {

loadCarts() {

// 先判断登录状态

ly.verifyUser()

.then(() => {

// 已登录

})

.catch(() => {

// 未登录

this.carts = ly.store.get(“carts”) || [];

this.selected = this.carts;

})

}

}

components: {

shortcut: () => import(“/js/pages/shortcut.js”)

}

})

刷新页面,查看控制台Vue实例:

在这里插入图片描述

3.5.2.渲染到页面

接下来,我们在页面中展示carts的数据:

页面位置:

在这里插入图片描述

修改后:

在这里插入图片描述

要注意,价格的展示需要进行格式化,这里使用的是我们在common.js中定义的formatPrice方法:

在这里插入图片描述

效果:

在这里插入图片描述

3.6.修改数量


我们给页面的 +-绑定点击事件,修改num 的值:

在这里插入图片描述

两个事件:

increment© {

c.num++;

ly.verifyUser()

.then(() => {

// TODO 已登录,向后台发起请求

})

.catch(() => {

// 未登录,直接操作本地数据

ly.store.set(“carts”, this.carts);

})

},

decrement© {

if (c.num <= 1) {

return;

}

c.num–;

this.verifyUser()

.then(() => {

// TODO 已登录,向后台发起请求

})

.catch(() => {

// 未登录,直接操作本地数据

ly.store.set(“carts”, this.carts);

})

},

3.7.删除商品


给删除按钮绑定事件:

在这里插入图片描述

点击事件中删除商品:

deleteCart(i) {

ly.verifyUser()

.then(() => {

// 已登录

})

.catch(() => {

// 未登录

this.carts.splice(i, 1);

ly.store.set(“carts”, this.carts);

})

}

3.8.选中商品


在页面中,每个购物车商品左侧,都有一个复选框,用户可以选择部分商品进行下单,而不一定是全部:

在这里插入图片描述

我们定义一个变量,记录所有被选中的商品:

在这里插入图片描述

3.8.1.选中一个

我们给商品前面的复选框与selected绑定,并且指定其值为当前购物车商品:

在这里插入图片描述

3.8.2.初始化全选

我们在加载完成购物车查询后,初始化全选:

在这里插入图片描述

3.8.4.总价格

然后编写一个计算属性,计算出选中商品总价格:

computed: {

totalPrice() {

return this.selected.map(c => c.num * c.price).reduce((p1, p2) => p1 + p2, 0);

}

}

在页面中展示总价格:

在这里插入图片描述

效果:

在这里插入图片描述

4.已登录购物车

===================================================================

4.1.购物车的微服务


4.1.1.创建购物车的微服务

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4.1.2.pom依赖

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns=“http://maven.apache.org/POM/4.0.0”

xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”>

leyou

com.leyou.parent

1.0.0-SNAPSHOT

4.0.0

com.leyou.service

ly-cart

org.springframework.boot

spring-boot-starter-web

org.springframework.cloud

spring-cloud-starter-netflix-eureka-client

org.springframework.cloud

spring-cloud-starter-openfeign

org.springframework.boot

spring-boot-starter-data-redis

4.1.3.配置文件

在这里插入图片描述

在这里插入图片描述

server:

port: 8088

spring:

application:

name: cart-service

redis:

host: 192.168.206.66

eureka:

client:

service-url:

defaultZone: http://127.0.0.1:10086/eureka

registry-fetch-interval-seconds: 5

instance:

prefer-ip-address: true

ip-address: 127.0.0.1

instance-id: e u r e k a . i n s t a n c e . i p − a d d r e s s . {eureka.instance.ip-address}. eureka.instance.ipaddress.{server.port}

lease-renewal-interval-in-seconds: 3

lease-expiration-duration-in-seconds: 10

4.1.4.启动类

在这里插入图片描述

在这里插入图片描述

@SpringBootApplication

@EnableDiscoveryClient

@EnableFeignClients

public class LyCartApplication {

public static void main(String[] args) {

SpringApplication.run(LyCartApplication.class, args);

}

}

4.1.5.添加到网关的路由当中

在这里插入图片描述

5.已登录购物车

===================================================================

接下来,我们完成已登录购物车。

在刚才的未登录购物车编写时,我们已经预留好了编写代码的位置,逻辑也基本一致。

5.1.添加登录校验


购物车系统只负责登录状态的购物车处理,因此需要添加登录校验,我们通过JWT鉴权即可实现。

5.1.1.引入JWT相关依赖

我们引入之前写的鉴权工具:ly-auth-common

在这里插入图片描述

com.leyou.auth

ly-auth-common

1.0.0-SNAPSHOT

5.1.2.配置公钥

在这里插入图片描述

ly:

jwt:

pubKeyPath: C:\Users\ZHENG\Desktop\leyou_msgrs\rsa\rsa.pub # 公钥地址

cookieName: LY_TOKEN # cookie的名称

5.1.3.加载公钥

在这里插入图片描述

在这里插入图片描述

package com.leyou.cart.config;

import com.leyou.auth.utils.RsaUtils;

import lombok.Data;

import lombok.extern.slf4j.Slf4j;

import org.springframework.boot.context.properties.ConfigurationProperties;

import javax.annotation.PostConstruct;

import java.security.PublicKey;

@Data

@ConfigurationProperties(prefix = “ly.jwt”)

@Slf4j

public class JwtProperties {

private String pubKeyPath;// 公钥

private PublicKey publicKey; // 公钥

private String cookieName;

@PostConstruct

public void init(){

try {

// 获取公钥和私钥

this.publicKey = RsaUtils.getPublicKey(pubKeyPath);

} catch (Exception e) {

log.error(“初始化公钥失败!”, e);

throw new RuntimeException();

}

}

}

5.1.4.编写过滤器

引入依赖:

在这里插入图片描述

com.leyou.common

ly-common

1.0.0-SNAPSHOT

代码:

因为很多接口都需要进行登录,我们直接编写SpringMVC拦截器,进行统一登录校验。同时,我们还要把解析得到的用户信息保存起来,以便后续的接口可以使用。

在这里插入图片描述

在这里插入图片描述

package com.leyou.interceptor;

import com.leyou.auth.entity.UserInfo;

import com.leyou.auth.utils.JwtUtils;

import com.leyou.cart.config.JwtProperties;

import com.leyou.common.utils.CookieUtils;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.context.properties.EnableConfigurationProperties;

import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

@Slf4j

public class UserInterceptor implements HandlerInterceptor {

private JwtProperties prop;

private static final ThreadLocal tl = new ThreadLocal<>();

public UserInterceptor(JwtProperties prop) {

this.prop = prop;

}

@Override

public boolean preHandle(HttpServletRequest request,

HttpServletResponse response,

Object handler) throws Exception {

//获取Cookie

String token = CookieUtils.getCookieValue(request, prop.getCookieName());

try {

//解析token

UserInfo user = JwtUtils.getUserInfo(prop.getPublicKey(), token);

//传递User

tl.set(user);

//放行

return true;

} catch (Exception e) {

log.error(“[购物车服务]解析用户身份失败”, e);

return false;

}

}

@Override

public void afterCompletion(HttpServletRequest request,

HttpServletResponse response,

Object handler, Exception ex)

throws Exception {

tl.remove();

}

public static UserInfo getLoginUser() {

return tl.get();

}

}

注意:

  • 这里我们使用了ThreadLocal来存储查询到的用户信息,线程内共享,因此请求到达Controller后可以共享User

  • 并且对外提供了静态的方法:getLoginUser()来获取User信息

5.1.5.配置过滤器

配置SpringMVC,使过滤器生效:

在这里插入图片描述

在这里插入图片描述

package com.leyou.cart.config;

import com.leyou.interceptor.UserInterceptor;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.context.properties.EnableConfigurationProperties;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration

@EnableConfigurationProperties(JwtProperties.class)

public class MvcConfig implements WebMvcConfigurer {

@Autowired

private JwtProperties prop;

@Override

public void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(new UserInterceptor(prop)).addPathPatterns(“/**”);

}

}

5.2.后台购物车设计


数据结构设计

当用户登录时,我们需要把购物车数据保存到后台,可以选择保存在数据库。但是购物车是一个读写频率很高的数据。因此我们这里选择读写效率比较高的Redis作为购物车存储。

Redis有5种不同数据结构,这里选择哪一种比较合适呢?

  • 首先不同用户应该有独立的购物车,因此购物车应该以用户的作为key来存储,Value是用户的所有购物车信息。这样看来基本的k-v结构就可以了。

  • 但是,我们对购物车中的商品进行增、删、改操作,基本都需要根据商品id进行判断,为了方便后期处理,我们的购物车也应该是k-v结构,key是商品id,value才是这个商品的购物车信息。

综上所述,我们的购物车结构是一个双层Map:Map<String,Map<String,String>>

  • 第一层Map,Key是用户id

  • 第二层Map,Key是购物车中商品id,值是购物车数据

  • Map<string,Map<String,String>>

实体类

在这里插入图片描述

@Data

public class Cart {

private Long userId;// 用户id

private Long skuId;// 商品id

private String title;// 标题

private String image;// 图片

private Long price;// 加入购物车时的价格

private Integer num;// 购买数量

private String ownSpec;// 商品规格参数

}

4.3.添加商品到购物车


4.3.1.页面发起请求:

已登录情况下,向后台添加购物车:

在这里插入图片描述

这里发起的是Json请求。那么我们后台也要以json接收。

4.3.2.后台添加购物车

Service

这里我们不访问数据库,而是直接操作Redis。基本思路:

  • 先查询之前的购物车数据

  • 判断要添加的商品是否存在

  • 存在:则直接修改数量后写回Redis

  • 不存在:新建一条数据,然后写入Redis

代码:

在这里插入图片描述

在这里插入图片描述

controller

先分析一下:

  • 请求方式:新增,肯定是Post

  • 请求路径:/cart ,这个其实是Zuul路由的路径,我们可以不管

  • 请求参数:Json对象,包含skuId和num属性

  • 返回结果:无

在这里插入图片描述

在这里插入图片描述

package com.leyou.cart.web;

import com.leyou.cart.pojo.Cart;

import com.leyou.cart.service.CartService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.http.HttpStatus;

import org.springframework.http.ResponseEntity;

import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RestController;

@RestController

public class CartController {

@Autowired

private CartService cartService;

/*

新增购物车

*/

@PostMapping(“cart”)

public ResponseEntity addCart(@RequestBody Cart cart){

cartService.addCart(cart);

return ResponseEntity.status(HttpStatus.CREATED).build();

}

}

完善CartService

在这里插入图片描述

在这里插入图片描述

package com.leyou.cart.service;

import com.leyou.auth.entity.UserInfo;

import com.leyou.cart.pojo.Cart;

import com.leyou.common.utils.JsonUtils;

import com.leyou.interceptor.UserInterceptor;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.BoundHashOperations;

import org.springframework.data.redis.core.StringRedisTemplate;

import org.springframework.stereotype.Service;

@Service

public class CartService {

@Autowired

private StringRedisTemplate redisTemplate;

private static final String KEY_PREFIX = “cart:uid:”;

public void addCart(Cart cart) {

//获取登录的用户

UserInfo user = UserInterceptor.getLoginUser();

//key

String key = KEY_PREFIX + user.getId();

//hashKey

String hashKey = cart.getSkuId().toString();

//记录num

Integer num = cart.getNum();

BoundHashOperations<String, Object, Object> operation = redisTemplate.boundHashOps(key);

//判断当前购物车商品是否存在

if(operation.hasKey(hashKey)){

//存在,修改数量

String json = operation.get(hashKey).toString();

cart = JsonUtils.toBean(json, Cart.class);

cart.setNum(cart.getNum() + num);

}

//写回redis

operation.put(hashKey,JsonUtils.toString(cart));

}

}

4.3.3.运行测试

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在虚拟机的redis当中查看

在这里插入图片描述

5.4.查询购物车


5.4.1.页面发起请求

在这里插入图片描述

5.4.2.后台实现

Controller

在这里插入图片描述

/**

最后

对于很多Java工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。

整理的这些资料希望对Java开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

再分享一波我的Java面试真题+视频学习详解+技能进阶书籍

美团二面惜败,我的凉经复盘(附学习笔记+面试整理+进阶书籍)

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

mg.cn/4ff782ab4ccd4bafb7ca56dd151657d7.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6JOd55uS5a2QaXRibHVlYm94,size_18,color_FFFFFF,t_70,g_se,x_16)

5.4.查询购物车


5.4.1.页面发起请求

在这里插入图片描述

5.4.2.后台实现

Controller

在这里插入图片描述

/**

最后

对于很多Java工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。

整理的这些资料希望对Java开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

再分享一波我的Java面试真题+视频学习详解+技能进阶书籍

[外链图片转存中…(img-BsBWob6F-1715451691847)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 22
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值