当前位置: 首页> 房产> 家装 > 上海官网建设费用_网站架构图怎么画_网络销售的工作内容_无线网络优化工程师

上海官网建设费用_网站架构图怎么画_网络销售的工作内容_无线网络优化工程师

时间:2025/7/10 13:29:48来源:https://blog.csdn.net/m0_46695127/article/details/143948457 浏览次数:0次
上海官网建设费用_网站架构图怎么画_网络销售的工作内容_无线网络优化工程师

文章目录

  • cubemall-product
    • SkuSaleAttrValueController.java
    • SkuSaleAttrValueDao.java
    • SkuSaleAttrValueService.java
    • SkuSaleAttrValueServiceImpl.java
    • SkuSaleAttrValueDao.xml
    • SkuInfoController.java
    • SkuInfoDao.java
    • SkuInfoService.java
    • application.yml
    • pom.xml
  • cubemall-auth
    • LoginController.java
    • UserService.java
    • UserServiceImpl.java
    • application.yml
    • CubemallAuthApplication.java
    • pom.xml
  • cubemall-cart
    • config
      • SpringBeansUtils.java
      • ThreadPoolConfig.java
      • ThreadPoolProperties.java
    • dto
      • UserInfoDTO.java
    • entity
      • UserEntity.java
    • interceptor
      • CartInterceptor.java
      • InterceptorConfig.java
    • rpc
      • AuthRemoteClient.java
      • ProductRemoteClient.java
    • service
      • CartService.java
      • CartServiceImpl.java
    • utils
      • Constants.java
      • CookieUtils.java
    • vo
      • CartItemVo.java
      • CartVo.java
      • SkuInfoVo.java
    • web
      • CartController.java
    • application.yml
    • CubemallCartApplication.java
    • pom.xml

购物车添加的时候用户未登录,用户已经登录,如何添加购物车?
用户是否登录,都可以添加购物车,用户未登录,添加到cookie,Redis都可以,前提是在cookie中都需要存储一个信息(直接把购物车数据存储在cookie,在cookie存储一个用户身份信息,然后把购物车数据还是存储在服务端)

购物车对象设计
CartVo
totalAccount 商品总价
countNum 商品数量
List<CartItemVo> 商品详细

CartItemVo
skuId
title
price
image
List<String> skuAttr
count
check=false
totalPrice

购物车

SELECT CONCAT(attr_name, ": ", attr_value) FROM tb_sku_sale_attr_value WHERE sku_id = 15

sql
sql2
getter方法的优先级:当Thymeleaf解析 ${item.totalPrice} 时,它实际上是在调用 item 对象的 getTotalPrice() 方法(如果这个方法存在的话)。这是因为在Java Bean规范中,属性的访问通常是通过getter方法进行的。因此,即使 CartItemVo 类中有一个名为 totalPrice 的字段,Thymeleaf也会优先尝试调用 getTotalPrice() 方法来获取值

cubemall-product

SkuSaleAttrValueController.java

package com.xd.cubemall.product.controller;import java.util.Arrays;
import java.util.List;
import java.util.Map;import com.xd.cubemall.common.utils.PageUtils;
import com.xd.cubemall.common.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import com.xd.cubemall.product.entity.SkuSaleAttrValueEntity;
import com.xd.cubemall.product.service.SkuSaleAttrValueService;/*** sku销售属性值** @author xuedong* @email email@gmail.com* @date 2024-08-13 07:57:20*/
@RestController
@RequestMapping("product/skusaleattrvalue")
public class SkuSaleAttrValueController {@RequestMapping("/sale/{skuId}")public List<String> getSaleAttrsString(@PathVariable("skuId") Long skuId){List<String> saleAttrsString = skuSaleAttrValueService.getSaleAttrsString(skuId);return saleAttrsString;}
}

SkuSaleAttrValueDao.java

package com.xd.cubemall.product.dao;import com.xd.cubemall.product.entity.SkuSaleAttrValueEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xd.cubemall.product.vo.SkuItemSaleAttrVo;
import org.apache.ibatis.annotations.Mapper;import java.util.List;/*** sku销售属性值* * @author xuedong* @email email@gmail.com* @date 2024-08-13 01:36:04*/
@Mapper
public interface SkuSaleAttrValueDao extends BaseMapper<SkuSaleAttrValueEntity> {public List<String> getSaleAttrsString(Long skuId);	
}

SkuSaleAttrValueService.java

package com.xd.cubemall.product.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.xd.cubemall.common.utils.PageUtils;
import com.xd.cubemall.product.entity.SkuSaleAttrValueEntity;
import com.xd.cubemall.product.vo.SkuItemSaleAttrVo;import java.util.List;
import java.util.Map;/*** sku销售属性值** @author xuedong* @email email@gmail.com* @date 2024-08-13 01:36:04*/
public interface SkuSaleAttrValueService extends IService<SkuSaleAttrValueEntity> {/*** 根据skuID查询销售属性* @param skuId* @return*/public List<String> getSaleAttrsString(Long skuId);
}

SkuSaleAttrValueServiceImpl.java

package com.xd.cubemall.product.service.impl;import com.xd.cubemall.common.utils.PageUtils;
import com.xd.cubemall.common.utils.Query;
import com.xd.cubemall.product.vo.SkuItemSaleAttrVo;
import org.springframework.stereotype.Service;import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;import com.xd.cubemall.product.dao.SkuSaleAttrValueDao;
import com.xd.cubemall.product.entity.SkuSaleAttrValueEntity;
import com.xd.cubemall.product.service.SkuSaleAttrValueService;@Service("skuSaleAttrValueService")
public class SkuSaleAttrValueServiceImpl extends ServiceImpl<SkuSaleAttrValueDao, SkuSaleAttrValueEntity> implements SkuSaleAttrValueService {/*** 根据skuID查询销售属性* @param skuId* @return*/@Overridepublic List<String> getSaleAttrsString(Long skuId) {List<String> saleAttrsString = this.baseMapper.getSaleAttrsString(skuId);return saleAttrsString;}
}

SkuSaleAttrValueDao.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.xd.cubemall.product.dao.SkuSaleAttrValueDao"><select id="getSaleAttrsString" resultType="java.lang.String">SELECTCONCAT( attr_name, ": ", attr_value )FROMtb_sku_sale_attr_valueWHEREsku_id = #{skuId}</select></mapper>

SkuInfoController.java

package com.xd.cubemall.product.controller;import java.util.Arrays;
import java.util.Map;import com.xd.cubemall.common.utils.PageUtils;
import com.xd.cubemall.common.utils.R;
import com.xd.cubemall.product.vo.SpuSaveVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import com.xd.cubemall.product.entity.SkuInfoEntity;
import com.xd.cubemall.product.service.SkuInfoService;/*** sku** @author xuedong* @email email@gmail.com* @date 2024-08-13 07:57:20*/
@RestController
@RequestMapping("product/skuinfo")
public class SkuInfoController {@Autowiredprivate SkuInfoService skuInfoService;/*** 信息*/@RequestMapping("/info/{id}")//@RequiresPermissions("product:skuinfo:info")public R info(@PathVariable("id") Long id){SkuInfoEntity skuInfo = skuInfoService.getById(id);return R.ok().put("skuInfo", skuInfo);}}

SkuInfoDao.java

package com.xd.cubemall.product.dao;import com.xd.cubemall.product.entity.SkuInfoEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;/*** sku??Ϣ* * @author xuedong* @email email@gmail.com* @date 2024-08-13 01:36:04*/
@Mapper
public interface SkuInfoDao extends BaseMapper<SkuInfoEntity> {}

SkuInfoService.java

package com.xd.cubemall.product.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.xd.cubemall.common.utils.PageUtils;
import com.xd.cubemall.product.entity.SkuInfoEntity;
import com.xd.cubemall.product.entity.SpuInfoEntity;
import com.xd.cubemall.product.vo.SkuItemVo;
import com.xd.cubemall.product.vo.SpuSaveVo;import java.util.Map;/*** sku??Ϣ** @author xuedong* @email email@gmail.com* @date 2024-08-13 01:36:04*/
public interface SkuInfoService extends IService<SkuInfoEntity> {}

application.yml

spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/cube_goods?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghaiusername: rootpassword: rootcloud:nacos:discovery:server-addr: 127.0.0.1:8848ip: 127.0.0.1application:name: cubemall-product
server:port: 8081
mybatis-plus:mapper-locations: classpath:/mapper/**/*.xmlglobal-config:db-config:id-type: autologic-delete-value: 1 #逻辑删除值(默认为1)logic-not-delete-value: 0 #逻辑未删除值(默认为0)logging:level:com.xd.cubemall: debug# 线程池相关的配置
cubemall:thread:core-pool-size: 20max-pool-size: 200keep-alive-time: 10

pom.xml

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.18.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.xd.cubemall</groupId><artifactId>cubemall-product</artifactId><version>0.0.1-SNAPSHOT</version><name>cubemall-product</name><description>cubemall-product</description><url/><licenses><license/></licenses><developers><developer/></developers><scm><connection/><developerConnection/><tag/><url/></scm><properties><java.version>1.8</java.version><spring-cloud.version>Greenwich.SR3</spring-cloud.version></properties><dependencies><!--引入common公共模块--><dependency><groupId>com.xd.cubemall</groupId><artifactId>cubemall-common</artifactId><version>0.0.1-SNAPSHOT</version></dependency><!--添加模板技术渲染页面--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!--阿里云OSS-->
<!--        <dependency>-->
<!--            <groupId>com.aliyun.oss</groupId>-->
<!--            <artifactId>aliyun-sdk-oss</artifactId>-->
<!--            <version>3.17.4</version>-->
<!--        </dependency>--></dependencies><dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.1.0.RELEASE</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

cubemall-auth

LoginController.java

package com.xd.cubemall.user.web;import com.alibaba.fastjson.JSON;
import com.xd.cubemall.common.utils.R;
import com.xd.cubemall.user.pojo.UserDTO;
import com.xd.cubemall.user.service.UserService;
import com.xd.cubemall.user.utils.Constants;
import com.xd.cubemall.user.utils.CookieUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@Controller
public class LoginController {// 注入service服务对象@Autowiredprivate UserService userService;/*** 根据token查询用户身份信息* "http://localhost:8082/user/info/"+token*/@ResponseBody@RequestMapping("/user/info/{token}")public String userInfo(@PathVariable String token,String callback){// 调用服务方法,查询用户身份信息R r = userService.userInfo(token);// 判断是否是跨域if(StringUtils.isBlank(callback)){return JSON.toJSONString(r);}// 是跨域return callback + "("+JSON.toJSONString(r)+")";}}

UserService.java

package com.xd.cubemall.user.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.xd.cubemall.common.utils.PageUtils;
import com.xd.cubemall.common.utils.R;
import com.xd.cubemall.user.entity.UserEntity;
import com.xd.cubemall.user.pojo.UserDTO;import java.util.Map;/*** 会员** @author xuedong* @email email@gmail.com* @date 2024-11-20 14:45:16*/
public interface UserService extends IService<UserEntity> {/*** 根据token查询用户身份信息* "http://localhost:8082/user/info/"+token*/R userInfo(String token);}

UserServiceImpl.java

package com.xd.cubemall.user.service.impl;import com.alibaba.fastjson.JSON;
import com.xd.cubemall.common.utils.R;
import com.xd.cubemall.user.pojo.UserDTO;
import com.xd.cubemall.user.utils.Constants;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.concurrent.TimeUnit;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xd.cubemall.common.utils.PageUtils;
import com.xd.cubemall.common.utils.Query;import com.xd.cubemall.user.dao.UserDao;
import com.xd.cubemall.user.entity.UserEntity;
import com.xd.cubemall.user.service.UserService;@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {// 注入redis服务@Autowiredprivate RedisTemplate<String,String> redisTemplate;/*** 根据token查询用户身份信息* "http://localhost:8082/user/info/"+token*/@Overridepublic R userInfo(String token) {// 根据token从redis服务中查询用户身份信息String userJson = redisTemplate.opsForValue().get(Constants.REDIS_LOGIN_KEY + token);// 把json字符串转换对象if(StringUtils.isBlank(userJson)){return R.error("用户身份已失效");}// 用户身份存在UserEntity userEntity = JSON.parseObject(userJson,UserEntity.class);// 返回结果return R.ok(userEntity);}}

application.yml

spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/cube_user?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghaiusername: rootpassword: rootcloud:nacos:discovery:server-addr: 127.0.0.1:8848ip: 127.0.0.1redis:port: 6379host: 127.0.0.1application:name: cubemall-auth
server:port: 8082
mybatis-plus:mapper-locations: classpath:/mapper/**/*.xmlglobal-config:db-config:id-type: autologic-delete-value: 1 #逻辑删除值(默认为1)logic-not-delete-value: 0 #逻辑未删除值(默认为0)logging:level:com.xd.cubemall: debuggithub:# 客户端IDclientId: # 客户端秘钥clientSecret: # 用户授权地址(返回授权码)authorizationUrl: https://github.com/login/oauth/authorize# 回调地址,获取access_tokenredirectUrl: http://localhost:8082/auth2/success# 认证服务器生成access_tokenaccessTokenUrl: https://github.com/login/oauth/access_token# 获取用户身份信息userInfoUrl: https://api.github.com/user

CubemallAuthApplication.java

package com.xd.cubemall.user;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class CubemallAuthApplication {public static void main(String[] args) {SpringApplication.run(CubemallAuthApplication.class, args);}}

pom.xml

<?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/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.18.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.xd.cubemall</groupId><artifactId>cubemall-auth</artifactId><version>0.0.1-SNAPSHOT</version><name>cubemall-auth</name><description>cubemall-auth</description><properties><java.version>1.8</java.version><spring-cloud.version>Greenwich.SR3</spring-cloud.version></properties><dependencies><!--引入common公共模块--><dependency><groupId>com.xd.cubemall</groupId><artifactId>cubemall-common</artifactId><version>0.0.1-SNAPSHOT</version></dependency><!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.16</version><scope>provided</scope></dependency><!--添加模板技术渲染页面--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!--阿里云OSS--><!--        <dependency>--><!--            <groupId>com.aliyun.oss</groupId>--><!--            <artifactId>aliyun-sdk-oss</artifactId>--><!--            <version>3.17.4</version>--><!--        </dependency>--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.1.0.RELEASE</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

cubemall-cart

config

SpringBeansUtils.java

package com.xd.cubemall.cart.config;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;@Component
public class SpringBeansUtils implements ApplicationContextAware {//定一个spring上下文的变量private static ApplicationContext applicationContext;@Override@Autowiredpublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {SpringBeansUtils.applicationContext = applicationContext;}//获取上下文对象public static ApplicationContext getApplicationContext() {return applicationContext;}//根据名称获取spring对象public static Object getBean(String name){return getApplicationContext().getBean(name);}//根据class类获取对象public static Object getBeanClass(Class clazz){return getApplicationContext().getBean(clazz);}}

ThreadPoolConfig.java

package com.xd.cubemall.cart.config;import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;@EnableConfigurationProperties(ThreadPoolProperties.class)
@Configuration
public class ThreadPoolConfig {@Beanpublic ThreadPoolExecutor executor(ThreadPoolProperties poolProperties){return new ThreadPoolExecutor(poolProperties.getCoreSize(),poolProperties.getMaxSize(),poolProperties.getKeepAliveTime(),TimeUnit.SECONDS,new LinkedBlockingDeque<>(),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());}}

ThreadPoolProperties.java

package com.xd.cubemall.cart.config;import lombok.Data;
import lombok.ToString;import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@ConfigurationProperties(prefix = "cubemall.thread")
@Data
@ToString
public class ThreadPoolProperties {private Integer coreSize;private Integer maxSize;private Integer keepAliveTime;}

dto

UserInfoDTO.java

package com.xd.cubemall.cart.dto;import lombok.Data;
import lombok.ToString;@ToString
@Data
public class UserInfoDTO {private Long userId; //用户登录使用的private String userKey; //标识临时用户的key,未登录使用这个值private Boolean tempUser = false;}

entity

UserEntity.java

package com.xd.cubemall.cart.entity;import lombok.Data;import java.io.Serializable;
import java.util.Date;/*** 会员* * @author xuedong* @email email@gmail.com* @date 2024-11-20 14:45:16*/
@Data
public class UserEntity implements Serializable {private static final long serialVersionUID = 1L;/*** id*/private Long id;/*** 会员等级id*/private Long levelId;/*** 用户名*/private String username;/*** 密码*/private String password;/*** 昵称*/private String nickname;/*** 手机号码*/private String mobile;/*** 邮箱*/private String email;/*** 头像*/private String header;/*** 性别*/private Integer gender;/*** 生日*/private Date birth;/*** 所在城市*/private String city;/*** 职业*/private String job;/*** 个性签名*/private String sign;/*** 用户来源*/private Integer sourceType;/*** 积分*/private Integer integration;/*** 启用状态*/private Integer status;/*** 注册时间*/private Date createTime;}

interceptor

CartInterceptor.java

package com.xd.cubemall.cart.interceptor;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.xd.cubemall.cart.config.SpringBeansUtils;
import com.xd.cubemall.cart.dto.UserInfoDTO;
import com.xd.cubemall.cart.entity.UserEntity;
import com.xd.cubemall.cart.rpc.AuthRemoteClient;
import com.xd.cubemall.cart.utils.Constants;
import com.xd.cubemall.cart.utils.CookieUtils;
import com.xd.cubemall.common.utils.R;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;public class CartInterceptor implements HandlerInterceptor {//创建一个ThreadLocal对象,用来存储用户身份信息//主要用来实现数据隔离,填充的数据只属于当前线程,高并发用户情况下,每一个用户只维护自己的用户信息即可public static ThreadLocal<UserInfoDTO> dtoThreadLocal = new ThreadLocal<>();// 注入远程调用rpc接口AuthRemoteClient remoteClient = (AuthRemoteClient) SpringBeansUtils.getBeanClass(AuthRemoteClient.class);/*** 业务方法执行之前执行的方法* @param request* @param response* @param handler* @return* @throws Exception*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//创建对象,判断用户处于状态UserInfoDTO userInfoDTO = new UserInfoDTO();//获取cookie中token,判断token是否存在,如果token不存在,表示用户没有登录String token = CookieUtils.getCookieValue(request, Constants.COOKIE_LOGIN_KEY, true);if(StringUtils.isNotBlank(token)){//根据接口远程调用认证服务,获取用户身份信息String jsonUser = remoteClient.userInfoByToken(token);if(StringUtils.isNotBlank(jsonUser)){//转换对象R r = JSON.parseObject(jsonUser, R.class);// 判断if(r.getCode() == 0){//获取用户身份信息对象//UserEntity result = (UserEntity) r.get("result");UserEntity result = r.getData("result", new TypeReference<UserEntity>() {});//用户处于登录状态userInfoDTO.setUserId(result.getId());}}}// 如果没有登录,标记此用户为一个临时用户//1.从cookie中获取购物车临时用户信息,判断此用户是否存在String userKey = CookieUtils.getCookieValue(request, Constants.COOKIE_TEMP_CART_KEY, true);//如果这个key存在,标记此用户为一个临时用户if(StringUtils.isNotBlank(userKey)){userInfoDTO.setUserKey(userKey);userInfoDTO.setTempUser(true);}//如果用户第一次来网站,没有登录,必须分配一个临时用户if(StringUtils.isBlank(userInfoDTO.getUserKey())){String userToken = UUID.randomUUID().toString();userInfoDTO.setUserKey(userToken);}//使用ThreadLocal存储用户信息dtoThreadLocal.set(userInfoDTO);//用户无论登录与否return true;}/*** 业务执行之后完成执行的方法* @param request* @param response* @param handler* @param modelAndView* @throws Exception*/@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {//获取用户当前身份信息UserInfoDTO userInfoDTO = dtoThreadLocal.get();//如果没有临时用户,需要保存临时用户if(!userInfoDTO.getTempUser()){//把用户身份信息存储在cookieCookieUtils.setCookie(request,response,Constants.COOKIE_TEMP_CART_KEY,userInfoDTO.getUserKey(),Constants.COOKIE_TEMP_CART_KEY_TIMEOUT,true);}}/*** 整个任务全部完成,执行方法* @param request* @param response* @param handler* @param ex* @throws Exception*/@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {HandlerInterceptor.super.afterCompletion(request, response, handler, ex);}
}

InterceptorConfig.java

package com.xd.cubemall.cart.interceptor;import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class InterceptorConfig implements WebMvcConfigurer {//实现拦截器注册@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new CartInterceptor()).addPathPatterns("/**");}
}

rpc

AuthRemoteClient.java

package com.xd.cubemall.cart.rpc;import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;@FeignClient("cubemall-auth")
public interface AuthRemoteClient {/*** 根据token查询用户信息*/@RequestMapping("/user/info/{token}")public String userInfoByToken(@PathVariable("token") String token);}

ProductRemoteClient.java

package com.xd.cubemall.cart.rpc;import com.xd.cubemall.common.utils.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;import java.util.List;@FeignClient("cubemall-product")
public interface ProductRemoteClient {@RequestMapping("product/skuinfo/info/{skuId}")public R getSkuInfo(@PathVariable("skuId") Long skuId);// 查询商品规格属性@RequestMapping("/product/skusaleattrvalue/sale/{skuId}")public List<String> getSkuSaleAttrs(@PathVariable("skuId") Long skuId);}

service

CartService.java

package com.xd.cubemall.cart.service;import com.xd.cubemall.cart.vo.CartItemVo;
import com.xd.cubemall.cart.vo.CartVo;/*** 购物车实现服务端接口*/
public interface CartService {/*** 购物车添加的接口*/public CartItemVo addToCart(Long skuId,Integer num);// 查询此次添加的购物车数据CartItemVo getCartItemData(Long skuId);/*** 购物车结算页面 购物车列表页面*/public CartVo getCartList();/*** 购物车商品删除实现*/public void deleteCart(Long skuId);/*** 购物车数量的改变* @param skuId* @param num*/public void changeItemNum(Long skuId,Integer num);}

CartServiceImpl.java

package com.xd.cubemall.cart.service.impl;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.xd.cubemall.cart.dto.UserInfoDTO;
import com.xd.cubemall.cart.interceptor.CartInterceptor;
import com.xd.cubemall.cart.rpc.ProductRemoteClient;
import com.xd.cubemall.cart.service.CartService;
import com.xd.cubemall.cart.utils.Constants;
import com.xd.cubemall.cart.vo.CartItemVo;
import com.xd.cubemall.cart.vo.CartVo;
import com.xd.cubemall.cart.vo.SkuInfoVo;
import com.xd.cubemall.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;@Slf4j
@Service
public class CartServiceImpl implements CartService {// 注入redistemplate@Autowiredprivate RedisTemplate redisTemplate;// 注入线程池对象@Autowiredprivate ThreadPoolExecutor executor;// 注入商品远程feign调用接口@Autowiredprivate ProductRemoteClient productRemoteClient;/*** 购物车数量的改变* @param skuId* @param num*/@Overridepublic void changeItemNum(Long skuId, Integer num) {CartItemVo cartItemData = this.getCartItemData(skuId);// 添加商品数量cartItemData.setCount(num);// 获取购物车数据BoundHashOperations<String, Long, Object> cartFromRedis = this.getCartFromRedis();// 把购物车数据转换JOSN字符串String cartJSON = JSON.toJSONString(cartItemData);// 放回购物车数据cartFromRedis.put(skuId,cartJSON);}/*** 购物车添加的接口* 业务步骤:* 1.获取购物车中已经存在的数据* 2.判断当前添加的商品是否在购物车中已经存在,如果已经存在这个商品,此时添加商品的数量相加即可* 3.如果此时购物车不存在这个商品,需要新添加商品进入购物车*/@Overridepublic CartItemVo addToCart(Long skuId, Integer num) {// 1.获取购物车数据,不论用户是否登录BoundHashOperations<String,Long,Object> cartOps = this.getCartFromRedis();// 2.判断当前添加的商品是否在购物车中已经存在String str = (String) cartOps.get(skuId);if(StringUtils.isBlank(str)){// 此时添加的商品在购物车中并不存在// 新创建购物车商品对象,组装购物车数据CartItemVo itemVo = new CartItemVo();// 异步编排CompletableFuture<Void> skuInfoFuture = CompletableFuture.runAsync(() -> {//远程调用商品服务,获取商品信息R r = productRemoteClient.getSkuInfo(skuId);//获取购物车数据SkuInfoVo skuInfoVo = r.getData("skuInfo", new TypeReference<SkuInfoVo>() {});// 给购物车数据赋值itemVo.setTitle(skuInfoVo.getSkuTitle());itemVo.setSkuId(skuInfoVo.getId());itemVo.setImage(skuInfoVo.getSkuDefaultImg());itemVo.setPrice(skuInfoVo.getPrice());itemVo.setCount(num);}, executor);// 查询商品规格属性值CompletableFuture<Void> attrFuture = CompletableFuture.runAsync(() -> {// 远程调用商品服务接口,获取属性组合List<String> skuSaleAttrs = productRemoteClient.getSkuSaleAttrs(skuId);itemVo.setSkuAttr(skuSaleAttrs);}, executor);// 等到所有的异步任务全部完成try {CompletableFuture.allOf(skuInfoFuture,attrFuture).get();// 把组装的数据添加到购物车:redisString cartJson = JSON.toJSONString(itemVo);cartOps.put(skuId,cartJson);} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}return itemVo;}else{// 此时添加的商品在购物车中存在CartItemVo itemVo = JSON.parseObject(str, CartItemVo.class);// 商品数量相加即可itemVo.setCount(itemVo.getCount() + num);// 更新购物车中数据即可:redisString cartJsonStr = JSON.toJSONString(itemVo);// 放入购物车即可cartOps.put(skuId,cartJsonStr);return itemVo;}}/*** 获取购物车数据* @return*/private BoundHashOperations<String, Long, Object> getCartFromRedis() {//1.获取购物车中已经存在的数据UserInfoDTO userInfoDTO = CartInterceptor.dtoThreadLocal.get();String cartKey = "";//判断是否登录if(userInfoDTO.getUserId()!=null){cartKey = Constants.CART_PREFIX + userInfoDTO.getUserId();}else{cartKey = Constants.CART_PREFIX + userInfoDTO.getUserKey();}//从redis中获取购物车相关的数据BoundHashOperations<String,Long,Object> cartOps = redisTemplate.boundHashOps(cartKey);return cartOps;}// 查询此次添加的购物车数据@Overridepublic CartItemVo getCartItemData(Long skuId) {BoundHashOperations<String, Long, Object> cartFromRedis = this.getCartFromRedis();// 根据skuId获取用户数据String itemJson = (String) cartFromRedis.get(skuId);// 把json字符串变成一个对象CartItemVo cartItemVo = JSON.parseObject(itemJson, CartItemVo.class);return cartItemVo;}/*** 购物车结算页面 购物车列表页面* @return*/@Overridepublic CartVo getCartList() {// 创建购物车数据对象CartVo cartVo = new CartVo();// 获取用户信息UserInfoDTO userInfoDTO = CartInterceptor.dtoThreadLocal.get();// 判断用户是登录还是未登录if(userInfoDTO.getUserId() != null){// 用户登录状态String loginCartKey = Constants.CART_PREFIX + userInfoDTO.getUserId();//  临时用户key,在用户登录状态,合并购物车数据String tempCartKey = Constants.CART_PREFIX + userInfoDTO.getUserKey();// 获取临时用户购物车数据List<CartItemVo> tempCartList = this.getCartListFromRedis(tempCartKey);// 判断临时购物车数据是否存在,如果存在,合并购物车if(tempCartList != null){for (CartItemVo cartItemVo : tempCartList) {// 添加购物车方法,直接合并即可addToCart(cartItemVo.getSkuId(), cartItemVo.getCount());}// 清除掉临时购物车redisTemplate.delete(tempCartKey);}// 用户处于登录状态,获取合并后购物车的所有的数据List<CartItemVo> cartList = getCartListFromRedis(loginCartKey);cartVo.setItems(cartList);}else{// 用户未登录String tempCartKey = Constants.CART_PREFIX + userInfoDTO.getUserKey();// 获取临时购物车数据List<CartItemVo> cartList = this.getCartListFromRedis(tempCartKey);cartVo.setItems(cartList);}return cartVo;}/*** 根据key获取购物车数据* @param cartKey* @return*/private List<CartItemVo> getCartListFromRedis(String cartKey) {// 获取的临时购物车所有的数据BoundHashOperations<String,Long,Object> boundHashOperations = redisTemplate.boundHashOps(cartKey);// 获取所有的值List<Object> values = boundHashOperations.values();// 判断这个值是否存在if(values!=null && values.size()>0){List<CartItemVo> collectList =  values.stream().map(obj -> {// 把字符串数据转换成对象String cartItemJson = (String)obj;CartItemVo cartItemVo = JSON.parseObject(cartItemJson, CartItemVo.class);return cartItemVo;}).collect(Collectors.toList());return collectList;}return null;}/*** 购物车商品删除实现* @param skuId*/@Overridepublic void deleteCart(Long skuId) {// 获取购物车数据对象BoundHashOperations<String, Long, Object> cartFromRedis = this.getCartFromRedis();// 清除购物车中数据cartFromRedis.delete(skuId);}
}

utils

Constants.java

package com.xd.cubemall.cart.utils;public class Constants {//用户身份信息存储的key:redis存储的public static final String REDIS_LOGIN_KEY="CUBE_LOGIN_TOKEN:";// 存储cookie中token的keypublic static final String COOKIE_LOGIN_KEY="COOKIE_LOGIN_KEY";//存储临时用户cookie keypublic static final String COOKIE_TEMP_CART_KEY="TEMP_USER_KEY";//存储临时用户cookie key 超时时间public static final int COOKIE_TEMP_CART_KEY_TIMEOUT= 24*60*60;//购物车keypublic static final String CART_PREFIX="CART_KEY:";}

CookieUtils.java

package com.xd.cubemall.cart.utils;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;/*** * Cookie 工具类**/
public final class CookieUtils {protected static final Logger logger = LoggerFactory.getLogger(CookieUtils.class);/*** 得到Cookie的值, 不编码* * @param request* @param cookieName* @return*/public static String getCookieValue(HttpServletRequest request, String cookieName) {return getCookieValue(request, cookieName, false);}/*** 得到Cookie的值,* * @param request* @param cookieName* @return*/public static String getCookieValue(HttpServletRequest request, String cookieName, boolean isDecoder) {Cookie[] cookieList = request.getCookies();if (cookieList == null || cookieName == null) {return null;}String retValue = null;try {for (int i = 0; i < cookieList.length; i++) {if (cookieList[i].getName().equals(cookieName)) {if (isDecoder) {retValue = URLDecoder.decode(cookieList[i].getValue(), "UTF-8");} else {retValue = cookieList[i].getValue();}break;}}} catch (UnsupportedEncodingException e) {logger.error("Cookie Decode Error.", e);}return retValue;}/*** 得到Cookie的值,* * @param request* @param cookieName* @return*/public static String getCookieValue(HttpServletRequest request, String cookieName, String encodeString) {Cookie[] cookieList = request.getCookies();if (cookieList == null || cookieName == null) {return null;}String retValue = null;try {for (int i = 0; i < cookieList.length; i++) {if (cookieList[i].getName().equals(cookieName)) {retValue = URLDecoder.decode(cookieList[i].getValue(), encodeString);break;}}} catch (UnsupportedEncodingException e) {logger.error("Cookie Decode Error.", e);}return retValue;}/*** 设置Cookie的值 不设置生效时间默认浏览器关闭即失效,也不编码*/public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,String cookieValue) {setCookie(request, response, cookieName, cookieValue, -1);}/*** 设置Cookie的值 在指定时间内生效,但不编码*/public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,String cookieValue, int cookieMaxage) {setCookie(request, response, cookieName, cookieValue, cookieMaxage, false);}/*** 设置Cookie的值 不设置生效时间,但编码*/public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,String cookieValue, boolean isEncode) {setCookie(request, response, cookieName, cookieValue, -1, isEncode);}/*** 设置Cookie的值 在指定时间内生效, 编码参数*/public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,String cookieValue, int cookieMaxage, boolean isEncode) {doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, isEncode);}/*** 设置Cookie的值 在指定时间内生效, 编码参数(指定编码)*/public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,String cookieValue, int cookieMaxage, String encodeString) {doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, encodeString);}/*** 删除Cookie带cookie域名*/public static void deleteCookie(HttpServletRequest request, HttpServletResponse response,String cookieName) {doSetCookie(request, response, cookieName, "", -1, false);}/*** 设置Cookie的值,并使其在指定时间内生效* * @param cookieMaxage cookie生效的最大秒数*/private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response,String cookieName, String cookieValue, int cookieMaxage, boolean isEncode) {try {if (cookieValue == null) {cookieValue = "";} else if (isEncode) {cookieValue = URLEncoder.encode(cookieValue, "utf-8");}Cookie cookie = new Cookie(cookieName, cookieValue);if (cookieMaxage > 0)cookie.setMaxAge(cookieMaxage);if (null != request)// 设置域名的cookiecookie.setDomain(getDomainName(request));cookie.setPath("/");response.addCookie(cookie);} catch (Exception e) {logger.error("Cookie Encode Error.", e);}}/*** 设置Cookie的值,并使其在指定时间内生效* * @param cookieMaxage cookie生效的最大秒数*/private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response,String cookieName, String cookieValue, int cookieMaxage, String encodeString) {try {if (cookieValue == null) {cookieValue = "";} else {cookieValue = URLEncoder.encode(cookieValue, encodeString);}Cookie cookie = new Cookie(cookieName, cookieValue);if (cookieMaxage > 0)cookie.setMaxAge(cookieMaxage);if (null != request)// 设置域名的cookiecookie.setDomain(getDomainName(request));cookie.setPath("/");response.addCookie(cookie);} catch (Exception e) {logger.error("Cookie Encode Error.", e);}}/*** 得到cookie的域名*/private static final String getDomainName(HttpServletRequest request) {String domainName = null;String serverName = request.getRequestURL().toString();if (serverName == null || serverName.equals("")) {domainName = "";} else {serverName = serverName.toLowerCase();serverName = serverName.substring(7);final int end = serverName.indexOf("/");serverName = serverName.substring(0, end);final String[] domains = serverName.split("\\.");int len = domains.length;if (len > 3) {// www.xxx.com.cndomainName = "." + domains[len - 3] + "." + domains[len - 2] + "." + domains[len - 1];} else if (len <= 3 && len > 1) {// xxx.com or xxx.cndomainName = "." + domains[len - 2] + "." + domains[len - 1];} else {domainName = serverName;}}if (domainName != null && domainName.indexOf(":") > 0) {String[] ary = domainName.split("\\:");domainName = ary[0];}return domainName;}}

vo

CartItemVo.java

package com.xd.cubemall.cart.vo;import lombok.Data;
import lombok.ToString;import java.math.BigDecimal;
import java.util.List;@ToString
@Data
public class CartItemVo {// sku商品idprivate Long skuId;//商品标题private String title;//商品图片private String image;//商品属性private List<String> skuAttr;//商品价格private BigDecimal price;//商品数量private Integer count;//总价格private BigDecimal totalPrice;// 是否选中private boolean check = true;//计算单价*数量的商品总价public BigDecimal getTotalPrice(){return this.price.multiply(new BigDecimal(count+""));}}

CartVo.java

package com.xd.cubemall.cart.vo;import lombok.Data;
import lombok.ToString;import java.math.BigDecimal;
import java.util.List;@ToString
@Data
public class CartVo {//商品详细选项private List<CartItemVo> items;//商品总数量private Integer countNum;//商品总价private BigDecimal totalAccount;//属性,减免价格private BigDecimal reducePrice = new BigDecimal("0");//计算总价格public BigDecimal getTotalAccount() {// 定义变量实现总价的叠加BigDecimal account = new BigDecimal("0");// 循环获取商品详情,计算总价if(items!=null && items.size()>0){for (CartItemVo item : items) {//判断商品是否被选中if(item.isCheck()){//获取单个商品总价BigDecimal totalPrice = item.getTotalPrice();account = account.add(totalPrice);}}}//减免优惠价格BigDecimal subtract = account.subtract(getReducePrice());return subtract;}public Integer getCountNum(){Integer count = 0;if(items!=null && items.size()>0){for (CartItemVo item: items) {//判断商品是否被选中if(item.isCheck()){count += item.getCount();}}}return count;}}

SkuInfoVo.java

package com.xd.cubemall.cart.vo;import lombok.Data;import java.io.Serializable;
import java.math.BigDecimal;/*** sku??Ϣ* * @author xuedong* @email email@gmail.com* @date 2024-08-13 01:36:04*/
@Data
public class SkuInfoVo implements Serializable {private static final long serialVersionUID = 1L;/*** 自增ID*/private Long id;/*** spuId*/private Long spuId;/*** sku名称*/private String skuName;/*** sku描述*/private String skuDesc;/*** 分类id*/private Long categoryId;/*** 品牌id*/private Long brandId;/*** 默认sku图片*/private String skuDefaultImg;/*** sku名称*/private String skuTitle;/*** sku子名称*/private String skuSubtitle;/*** 价格*/private BigDecimal price;/*** 销售数量*/private Long saleCount;}

web

CartController.java

package com.xd.cubemall.cart.web;import com.xd.cubemall.cart.service.CartService;
import com.xd.cubemall.cart.vo.CartItemVo;
import com.xd.cubemall.cart.vo.CartVo;
import com.xd.cubemall.common.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;@Controller
public class CartController {// 注入购物车服务对象@Autowiredprivate CartService cartService;/*** 购物车数量的改变* @param skuId* @param num* @return*/@GetMapping("cart/changeItem")public String changeItemNum(@RequestParam("skuId") Long skuId,@RequestParam("num") Integer num){//调用服务端更新购物车数量方法cartService.changeItemNum(skuId,num);return "redirect:http://localhost:8083/cart/list";}/*** 添加购物车* @param num* @param skuId* @param attributes* @return*/@RequestMapping("/cart/addCart")public String addCart(@RequestParam("num") Integer num,@RequestParam("skuId") Long skuId,RedirectAttributes attributes){//调用添加购物车方法,实现购物车添加CartItemVo itemVo = cartService.addToCart(skuId, num);// 属性将会自动追加重定向请求后面attributes.addAttribute("skuId",skuId);return "redirect:http://localhost:8083/cart/successPage";}/*** 跳转到添加购物车成功的页面*/@GetMapping("/cart/successPage")public String successPage(@RequestParam("skuId") Long skuId, Model model){// 查询此次添加的购物车数据CartItemVo cartItem = cartService.getCartItemData(skuId);// 放入作用域model.addAttribute("item", cartItem);return "success-cart";}/*** 购物车结算页面,购物车列表页面*/@RequestMapping("cart/list")public String getCartList(Model model){// 调用服务层方法CartVo cartVo = cartService.getCartList();model.addAttribute("cart",cartVo);return "cart";}/*** 购物车商品删除实现*/@RequestMapping("/cart/delete")public String deleteCart(@RequestParam("skuId") Long skuId){// 调用服务层接口,实现购物车数据删除即可cartService.deleteCart(skuId);return "redirect:http://localhost:8083/cart/list";}}

application.yml

spring:cloud:nacos:discovery:server-addr: 127.0.0.1:8848ip: 127.0.0.1redis:port: 6379host: 127.0.0.1application:name: cubemall-cart
server:port: 8083global-config:db-config:id-type: autologic-delete-value: 1 #逻辑删除值(默认为1)logic-not-delete-value: 0 #逻辑未删除值(默认为0)logging:level:com.xd.cubemall: debug
# 配置连接池
cubemall:thread:coreSize: 20maxSize: 100keepAliveTime: 10

CubemallCartApplication.java

package com.xd.cubemall.cart;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class CubemallCartApplication {public static void main(String[] args) {SpringApplication.run(CubemallCartApplication.class, args);}}

pom.xml

<?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/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.18.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.xd.cubemall</groupId><artifactId>cubemall-cart</artifactId><version>0.0.1-SNAPSHOT</version><name>cubemall-cart</name><description>cubemall-cart</description><properties><java.version>1.8</java.version><spring-cloud.version>Greenwich.SR3</spring-cloud.version></properties><dependencies><!--引入common公共模块--><dependency><groupId>com.xd.cubemall</groupId><artifactId>cubemall-common</artifactId><version>0.0.1-SNAPSHOT</version><exclusions><exclusion><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></exclusion><exclusion><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></exclusion></exclusions></dependency><!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.16</version><scope>provided</scope></dependency><!--添加模板技术渲染页面--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!--阿里云OSS--><!--        <dependency>--><!--            <groupId>com.aliyun.oss</groupId>--><!--            <artifactId>aliyun-sdk-oss</artifactId>--><!--            <version>3.17.4</version>--><!--        </dependency>--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.1.0.RELEASE</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
关键字:上海官网建设费用_网站架构图怎么画_网络销售的工作内容_无线网络优化工程师

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: