购物车结构说明
购物车java结构是List的集合形式。Cart中包含sellerId和sellerName以及List三个属性。
购物车模块搭建
一、搭建cart-interface模块,不使用骨架
二、搭建cart-service模块,使用骨架
1、在web-inf中添加web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!-- 加载spring容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
2、在resources中添加文件夹以及配置文件
applicationContext-service.xml全文如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 访问dubbo要占用的当前主机端口,默认端口不写是20880 -->
<dubbo:protocol name="dubbo" port="20887"></dubbo:protocol>
<dubbo:application name="myApplication-cart-service"/>
<dubbo:registry address="zookeeper://192.168.25.128:2181"/>
<dubbo:annotation package="com.myApplication.cart.service.impl" />
</beans>
3、在java文件夹中添加CartServiceImpl实现类
三、搭建cart-web模块
1、在web-inf的web.xml文件中添加springmvc配置和security配置
全文如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!-- 解决post乱码 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-security.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>cart.html</welcome-file>
</welcome-file-list>
</web-app>
2、在resources文件中添加文件夹及配置文件
spring-security.xml中配置security整合cas的配置,全文如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<http pattern="/css/**" security="none"></http>
<http pattern="/js/**" security="none"></http>
<http pattern="/img/**" security="none"></http>
<http pattern="/plugins/**" security="none"></http>
<http pattern="/cart.html" security="none"></http>
<!-- 添加购物车可以不用登录,存到cookie中 如果这样访问,未登录时获取name会崩 改在http中添加的第一句-->
<!--<http pattern="/cart/*.do" security="none"></http>-->
<!-- entry-point-ref 入口点引用 -->
<http use-expressions="false" entry-point-ref="casProcessingFilterEntryPoint">
<intercept-url pattern="/cart/*.do" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/**" access="ROLE_USER"/>
<csrf disabled="true"/>
<!-- custom-filter为过滤器, position 表示将过滤器放在指定的位置上,before表示放在指定位置之前 ,after表示放在指定的位置之后 -->
<custom-filter ref="casAuthenticationFilter" position="CAS_FILTER" />
<custom-filter ref="requestSingleLogoutFilter" before="LOGOUT_FILTER"/>
<custom-filter ref="singleLogoutFilter" before="CAS_FILTER"/>
</http>
<!-- CAS入口点 开始 -->
<beans:bean id="casProcessingFilterEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
<!-- cas登录服务器登录URL -->
<beans:property name="loginUrl" value="http://localhost:8080/cas/login"/>
<beans:property name="serviceProperties" ref="serviceProperties"/>
</beans:bean>
<beans:bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
<!--service 配置自身工程的根地址+/login/cas -->
<beans:property name="service" value="http://localhost:9107/login/cas"/>
</beans:bean>
<!-- CAS入口点 结束 -->
<!-- 认证过滤器 开始 -->
<beans:bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager"/>
</beans:bean>
<!-- 认证管理器 -->
<authentication-manager alias="authenticationManager">
<authentication-provider ref="casAuthenticationProvider">
</authentication-provider>
</authentication-manager>
<!-- 认证提供者 -->
<beans:bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
<beans:property name="authenticationUserDetailsService">
<beans:bean class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<beans:constructor-arg ref="userDetailService" />
</beans:bean>
</beans:property>
<beans:property name="serviceProperties" ref="serviceProperties"/>
<!-- ticketValidator 为票据验证器 -->
<beans:property name="ticketValidator">
<beans:bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
<!-- 设置cas票据验证地址 -->
<beans:constructor-arg index="0" value="http://localhost:8080/cas"/>
</beans:bean>
</beans:property>
<beans:property name="key" value="an_id_for_this_auth_provider_only"/>
</beans:bean>
<!-- springScurity认证类 -->
<beans:bean id="userDetailService" class="com.pinyougou.user.service.UserDetailServiceImpl"/>
<!-- 认证过滤器 结束 -->
<!-- 单点登出 开始 -->
<beans:bean id="singleLogoutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter"/>
<beans:bean id="requestSingleLogoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<beans:constructor-arg value="http://localhost:8080/cas/logout?service=http://localhost:9107/"/>
<beans:constructor-arg>
<beans:bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
</beans:constructor-arg>
<!-- 将本地/logout/cas和 64行退出后的部分进行绑定 -->
<beans:property name="filterProcessesUrl" value="/logout/cas"/>
</beans:bean>
<!-- 单点登出 结束 -->
</beans:beans>
springmvc.xml中配置引用的dubbo服务,全文如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean
class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json" />
<property name="features">
<array>
<value>WriteMapNullValue</value>
<value>WriteDateUseDateFormat</value>
</array>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 引用dubbo 服务 -->
<dubbo:application name="myApplication-cart-web" />
<dubbo:registry address="zookeeper://192.168.25.128:2181" />
<dubbo:annotation package="com.myApplication.cart.controller" />
</beans>
3、在java文件夹中添加controller以及用于用户验证的UserDetailServiceImpl
UserDetailServiceImpl中的全文如下:
//注意认证类的包名要和spring-security.xml文件中的包名一致
//该类可以拷贝shop-web子模块中的
//该类的目的已经不是为了进行用户认证,在调用该类前springSecurity已经从CAS做完认证后才调用,该类的执行只为了拿到角色"ROLE_USER"返回用户角色信息
public class UserDetailServiceImpl implements UserDetailsService {
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
System.out.println("经过认证类:"+username);
List<GrantedAuthority> authorities=new ArrayList();
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
return new User(username,"",authorities);
}
}
购物车商品列表添加新购物车
创建cart购物车pojo类
在CartServiceImpl实现类中添加新增方法(需要在interface中添加对应的方法略)
1、添加一个方法来判断新添加的购物车是否已经存在集合中
searchCartListBySellerId方法全文如下:
//查找原来的集合中有没有将要添加的购物车
private Cart searchCartListBySellerId(List<Cart> cartList, String sellerId) {
for (Cart cart : cartList) {
if (sellerId.equals(cart.getSellerId())) {
return cart;
}
}
return null;
}
2、如果集合中没有要添加的购物车,创建购物车,并根据上一步查找到的item数据写入数据
3、创建第2步中的addOrderItemToList方法
4、当购物车集合中已经存在我们要添加的购物车
同样调用addOrderItemToList方法。
uuid作为未登录下的key
我们需要操控cookie来实现将uuid存储到cookie中。在common模块中引入工具类
CookieUtil中的全文如下:
package util;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* Cookie 工具类
*
*/
public final class CookieUtil {
/**
* 得到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) {
e.printStackTrace();
}
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) {
e.printStackTrace();
}
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) {// 设置域名的cookie
String domainName = getDomainName(request);
System.out.println(domainName);
if (!"localhost".equals(domainName)) {
cookie.setDomain(domainName);
}
}
cookie.setPath("/");
response.addCookie(cookie);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 设置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) {// 设置域名的cookie
String domainName = getDomainName(request);
System.out.println(domainName);
if (!"localhost".equals(domainName)) {
cookie.setDomain(domainName);
}
}
cookie.setPath("/");
response.addCookie(cookie);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 得到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.cn
domainName = "." + domains[len - 3] + "." + domains[len - 2] + "." + domains[len - 1];
} else if (len <= 3 && len > 1) {
// xxx.com or xxx.cn
domainName = "." + domains[len - 2] + "." + domains[len - 1];
} else {
domainName = serverName;
}
}
if (domainName != null && domainName.indexOf(":") > 0) {
String[] ary = domainName.split("\\:");
domainName = ary[0];
}
return domainName;
}
}
在CartController中添加 获取uuid的方法getUuid:
public String getUuid() {
String uuid = CookieUtil.getCookieValue(request, "uuid", "utf-8");
if (uuid == null || uuid.equals("")) {
uuid = UUID.randomUUID().toString();
CookieUtil.setCookie(request, response, "uuid", uuid, 48 * 60 * 60, "utf-8");
}
return uuid;
}
未登录购物车验证功能后端代码
1、需要判断是否已经登录。需要修改springSecurity.xml文件,释放静态资源的方式不能是,这样的话,在后端通过security框架获取用户名访问的配置。
2、在后端判断是否登录,将购物车集合存入redis中。
如果没有登录,通过security框架获取到的是‘’anonymousUser‘’。
购物车前端显示
调用下面的findCartList方法。
前端操作。
前端数量增减实现
附:
js文件的controller全文如下:
app.controller('cartController',function ($scope,cartService) {
//获取购物车列表
$scope.findCartList =function () {
cartService.findCartList().success(
function (response) {
$scope.cartList = response;
}
)
}
//添加商品到购物车列表
$scope.addItemToCartList = function (itemId,num) {
cartService.addItemToCartList(itemId,num).success(
function (response) {
if(response.success){
$scope.findCartList(); //刷新列表
}else{
alert(response.message);
}
}
)
}
})
附:js文件的service全文如下:
app.service('cartService',function ($http) {
//获取购物车列表
this.findCartList = function () {
return $http.get('cart/findCartList.do');
}
//添加商品到购物车
//cart/addItemToCartList.do?itemId=1369360&num=1
this.addItemToCartList = function (itemId,num) {
return $http.get('cart/addItemToCartList.do?itemId='+itemId+"&num="+num);
}
})
登录后购物车列表
合并登录和没登录的购物车
添加一个合并两个购物车集合的方法mergeCartList
在controller类中通过判断,操作是否合并。如果未登录状态没有添加购物车,就不需要合并。
实现上边引用的两个方法,一个是添加到redis中,一个是从redis中删除。
附:
后端控制器CartController全文如下:
@RestController
@RequestMapping("/cart")
public class CartController {
@Reference
private CartService cartService;
@Autowired
private HttpServletRequest request;
@Autowired
private HttpServletResponse response;
public String getUuid() {
String uuid = CookieUtil.getCookieValue(request, "uuid", "utf-8");
if (uuid == null || uuid.equals("")) {
uuid = UUID.randomUUID().toString();
CookieUtil.setCookie(request, response, "uuid", uuid, 48 * 60 * 60, "utf-8");
}
return uuid;
}
@RequestMapping("/addItemToCartList")
public Result addItemToCartList(Long itemId, Integer num) {
try {
//通过在springSecurity.xml中的配置,如果是未登录状态的访问,返回值是anonymousUser
String uuid = SecurityContextHolder.getContext().getAuthentication().getName();
if ("anonymousUser".equals(uuid)) { //未登录的状态
uuid = getUuid();
}
//如果未登录
//String uuid = getUuid();
List<Cart> cartList = cartService.findCartListFromRedis(uuid);
cartList = cartService.addItemToCartList(cartList, itemId, num);
//将新数据保存回redis缓存中
cartService.saveCartListToRedis(uuid, cartList);
return new Result(true, "添加购物车成功!");
} catch (Exception e) {
e.printStackTrace();
return new Result(false, "添加购物车失败!");
}
}
@RequestMapping("/findCartList")
public List<Cart> findCartList() {
//通过在springSecurity.xml中的配置,如果是未登录状态的访问,返回值是anonymousUser
String loginName = SecurityContextHolder.getContext().getAuthentication().getName();
String uuid = getUuid();
//获取未登录的购物车
List<Cart> cartList = cartService.findCartListFromRedis(uuid);
if (!"anonymousUser".equals(loginName)) { //已经登录的状态 需要合并
//从redis中获取购物车(登录的购物车)
List<Cart> cartListLogin = cartService.findCartListFromRedis(loginName);
if (cartList.size() > 0) { //当未登录状态时存在购物车数据才合并,然后将合并后的数据存入到redis中
cartList = cartService.mergeCartList(cartList, cartListLogin);
cartService.saveCartListToRedis(loginName, cartList);
//将购物车从redis中删除
cartService.delCartListToRedis(uuid);
} else { //如果不需要合并,直接让cartList等于cartListLogin,返回。
cartList = cartListLogin;
}
}
return cartList;
}
}
附:后端CartService全文如下:
public interface CartService {
// 添加商品到购物车列表(1.要加商品的列表 2.加入商品的id 3.加入商品数量)
public List<Cart> addItemToCartList(List<Cart> cartList, Long itemId, Integer num);
//从redis缓存中查找购物车集合
public List<Cart> findCartListFromRedis(String name);
//将购物车集合保存到redis中
public void saveCartListToRedis(String name,List<Cart> cartList);
//合并购物车
public List<Cart> mergeCartList(List<Cart> cartList1, List<Cart> cartList2) ;
//删除未登录状态的购物车
public void delCartListToRedis(String key);
}
附:后端CartServiceImpl全文如下:
@Service
public class CartServiceImpl implements CartService {
@Autowired
private TbItemMapper itemMapper;
@Autowired
private RedisTemplate redisTemplate;
@Override
public List<Cart> addItemToCartList(List<Cart> cartList, Long itemId, Integer num) {
//根据itemID获取item对象
TbItem item = itemMapper.selectByPrimaryKey(itemId);
//查找之前的购物车集合中是否已经存在要添加的购物车
Cart cart = searchCartListBySellerId(cartList, item.getSellerId());
if (cart == null) { //如果之前的购物车集合中没有要添加的购物车
cart = new Cart();//创建一个购物车
cart.setSellerId(item.getSellerId());
cart.setSellerName(item.getSeller());
List<TbOrderItem> orderItemList = new ArrayList<>();
orderItemList = addOrderItemToList(orderItemList, item, num);
cart.setOrderItemList(orderItemList);
cartList.add(cart);
} else { //在之前的购物车中已经有要添加的购物车
List<TbOrderItem> orderItemList = addOrderItemToList(cart.getOrderItemList(), item, num);
cart.setOrderItemList(orderItemList);
//cartList.add(cart);//此处不需要再添加
//如果购物车中的购物明细的数量小于等于0,移除这个购物车
if (cart.getOrderItemList().size() <= 0) {
cartList.remove(cart);
}
}
return cartList;
}
//查找原来的集合中有没有将要添加的购物车
private Cart searchCartListBySellerId(List<Cart> cartList, String sellerId) {
for (Cart cart : cartList) {
if (sellerId.equals(cart.getSellerId())) {
return cart;
}
}
return null;
}
//将orderItem添加进集合中
private List<TbOrderItem> addOrderItemToList(List<TbOrderItem> orderItemList, TbItem item, Integer num) {
if (orderItemList.size() > 0) { //如果集合中有数据,说明不是新创建,判断是否存在要添加的数据
for (TbOrderItem orderItem : orderItemList) {
if (item.getId().equals(orderItem.getItemId())) { //说明集合中已经有要添加的数据
//直接进行数量的累加
orderItem.setNum(orderItem.getNum() + num);
//总价格的修改
orderItem.setTotalFee(new BigDecimal(orderItem.getNum() * orderItem.getPrice().doubleValue()));
//如果num的数量小于等于0,移除这条orderItem
if(orderItem.getNum()<=0){
orderItemList.remove(orderItem);
}
//将集合返回
return orderItemList;
}
}
}
//说明购物车集合是新创建的,或者是集合中没有找到要添加的数据,需要创建新的orderItem数据
TbOrderItem orderItem = new TbOrderItem();
orderItem.setItemId(item.getId());
orderItem.setNum(num);
orderItem.setGoodsId(item.getGoodsId());
orderItem.setPicPath(item.getImage());
orderItem.setTitle(item.getTitle());
orderItem.setPrice(item.getPrice());
orderItem.setSellerId(item.getSellerId());
orderItem.setTotalFee(new BigDecimal(orderItem.getNum() * orderItem.getPrice().doubleValue()));
orderItemList.add(orderItem);
return orderItemList;
}
//根据name从redis中获取购物车集合
@Override
public List<Cart> findCartListFromRedis(String name) {
List<Cart> cartList = (ArrayList<Cart>) redisTemplate.boundHashOps("cartList").get(name);
if (cartList == null){
cartList = new ArrayList<Cart>();
}
return cartList;
}
//将购物车集合保存到redis中
@Override
public void saveCartListToRedis(String name,List<Cart> cartList){
redisTemplate.boundHashOps("cartList").put(name, cartList);
}
//用来合并两个购物车(未登录状态的和已登录状态的
@Override
public List<Cart> mergeCartList(List<Cart> cartList1, List<Cart> cartList2) {
for(Cart cart: cartList2){
//需要一件一件的合并相同商品的数量
for(TbOrderItem orderItem:cart.getOrderItemList()){
cartList1= addItemToCartList(cartList1,orderItem.getItemId(),orderItem.getNum());
}
}
return cartList1;
}
@Override
public void delCartListToRedis(String key){
//System.out.println("删除redis购物车数据....."+key);
redisTemplate.boundHashOps("cartList").delete(key);
}
}