Demo购物车

新增sku到购物车

上次课我们开发到了显示商品详情

有点击"添加到购物车"的按钮

但是没有反应,我们完成添加购物车的功能就能实现这个效果了

打开mall-order-webapi模块

业务逻辑中一些基本的注意事项

  • * 判断用户是否登录,只有登录后才能将商品新增到购物车
  • * 验证购物车信息的完整性
  • * 业务逻辑层要判断新增的sku是否在当前用户的购物车表中已经存在
  • * 如果不存在是新增sku流程
  • * 如果已经存在,是修改数量的流程

开发持久层

持久层要按上面分析的业务逻辑,开发多个方法

  1. 判断当前登录用户购物车中是否包含指定skuid商品的方法
  2. 新增sku到购物车表中
  3. 修改购物车指定sku数量的方法

mapper包创建OmsCartMapper接口,编写代码如下

@Repository
public interface OmsCartMapper {
// 判断当前用户的购物车列表中是否包含指定sku商品的方法
OmsCart selectExistsCart(@Param("userId") Long userId,@Param("skuId") Long skuId);
// 新增商品到购物车表中
void saveCart(OmsCart omsCart);
// 修改指定购物车商品的数量的方法
void updateQuantityById(OmsCart omsCart);
}

对应的Mapper.xml文件

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



















id,
user_id,
sku_id,
title,
main_picture,
price,
quantity,
gmt_create,
gmt_modified






insert into oms_cart(
user_id,
sku_id,
title,
main_picture,
price,
quantity
) values(
#{userId},
#{skuId},
#{title},
#{mainPicture},
#{price},
#{quantity}
)



update
oms_cart
set
quantity=#{quantity}
where
id=#{id}

开发业务逻辑层

创建OmsCartServiceImpl类实现IOmsCartService接口

实现其中方法,先实现新增购物车的方法即可

需要注意,我们在业务逻辑层中需要使用用户的信息

要单独编写一个方法获取用户信息,

@Service
public class OmsCartServiceImpl implements IOmsCartService {
@Autowired
private OmsCartMapper omsCartMapper;
@Override
public void addCart(CartAddDTO cartDTO) {
// 获取当前登录用户的userId
Long userId=getUserId();
// 查询这个userId的用户是否已经将指定的sku添加到购物车
OmsCart omsCart=omsCartMapper.selectExistsCart(userId,cartDTO.getSkuId());
// 判断查询结果是否为null
if(omsCart!=null){
// 不等于null,表示当前用户这个sku已经添加在购物车列表中
// 我们需要做的就是修改它的数量,根据cartDTO对象的quantity属性值添加
omsCart.setQuantity(omsCart.getQuantity()+cartDTO.getQuantity());
// 调用持久层方法修改数量
omsCartMapper.updateQuantityById(omsCart);
}else{
// 如果omsCart是null 会运行else代码块
// 去完成购物车对象的新增,先实例化OmsCart对象
OmsCart newOmsCart=new OmsCart();
// 将参数cartDTO的同名属性赋值给newOmsCart
BeanUtils.copyProperties(cartDTO,newOmsCart);
// cartDTO对象中没有userId属性,需要单独赋
newOmsCart.setUserId(userId);
// 执行新增
omsCartMapper.saveCart(newOmsCart);
}
}

@Override
public JsonPage listCarts(Integer page, Integer pageSize) {
return null;
}

@Override
public void removeCart(Long[] ids) {
}

@Override
public void removeAllCarts() {
}

@Override
public void removeUserCarts(OmsCart omsCart) {
}

@Override
public void updateQuantity(CartUpdateDTO cartUpdateDTO) {
}

// 业务逻辑层获得用户信息的方法,因为多个方法需要获得用户信息,所以单独编写一个方法
// 这个方法的实现是SpringSecurity提供的登录用户的容器
// 方法的目标是获得SpringSecurity用户容器,从容器中获得用户信息
public CsmallAuthenticationInfo getUserInfo(){
// 获得SpringSecurity容器对象
UsernamePasswordAuthenticationToken authenticationToken=
(UsernamePasswordAuthenticationToken)SecurityContextHolder.
getContext().getAuthentication();
// 判断获取的容器信息是否为空
if(authenticationToken!=null){
// 如果容器中有内容,证明当前容器中有登录用户信息
// 我们获取这个用户信息并返回
CsmallAuthenticationInfo csmallAuthenticationInfo=
(CsmallAuthenticationInfo)authenticationToken.getCredentials();
return csmallAuthenticationInfo;
}
throw new CoolSharkServiceException(ResponseCode.UNAUTHORIZED,"没有登录信息");
}

// 业务逻辑层中大多数方法都是获得用户id,所以编写一个返回用户id的方法
public Long getUserId(){
return getUserInfo().getId();
}
}

开发控制层

创建OmsCartController

@RestController
@RequestMapping("/oms/cart")
@Api(tags = "购物车管理模块")
public class OmsCartController {
@Autowired
private IOmsCartService omsCartService;
// 新增购物车信息的控制层方法
@PostMapping("/add")
@ApiOperation("新增购物车信息")
// 判断当前用户是否具有普通用户权限ROLE_user
// sso模块登录时,会在用户的权限列表中添加ROLE_user权限
@PreAuthorize("hasRole('ROLE_user')")
// cartAddDTO参数是需要经过SpringValidation框架验证的
// @Validated就是激活框架验证功能,如果cartAddDTO不满足验证要求,会自动运行
// 统一由异常处理类中的BingingException异常处理
public JsonResult addCart(@Validated CartAddDTO cartAddDTO){
omsCartService.addCart(cartAddDTO);
return JsonResult.ok("成功添加到购物车");
}
}

先注意sso模块application-test.yml的地址和端口号(密码有两个)

也要注意order模块application-test.yml的地址和端口号

都保证正确的前提下

启动 leaf passport order

sso:10002

order:10005

先访问10002登录获得JWT 用户名jackson密码123456

先登录看到JWT 然后复制JWT

转到10005 order模块 文档管理->全局参数设置->添加参数

参数名:Authorization

参数值:Bearer [粘贴JWT]

然后刷新当前10005的界面

然后进行发送请求即可成功!


javax.xml.bind
jaxb-api
2.3.0

SpringSecurity验证规则

SpringSecurity框架登录后,一定会有一个权限列表

在userDetails对象中

我们登录用户的这个对象的值可能是

{"authorities":["ROLE_user"],"id":1,"userType":"USER","username":"jackson"}

sso模块前台用户登录时,会authorities属性中添加ROLE_user权限

而后台管理用户登录时会向authorities属性中添加下面属性

["/pms/product/read","/pms/product/update","/pms/product/delete"]

所以想要在控制器运行前判断权限时就可以使用下面的写法

@PreAuthorize("hasAuthority('ROLE_user')")

hasRole判断是专用于判断当前用户角色的指令

hasRole会自动在我们判断的内容前添加ROLE_

@PreAuthorize("hasRole('ROLE_user')")

开发查询购物车功能

开发持久层

OmsCartMapper添加方法如下

// 根据当前用户id查询购物车列表
List selectCartsByUserId(Long userId);

OmsCartMapper.xml添加对应内容


开发业务逻辑层

OmsCartServiceImpl业务实现

返回值支持分页结果,按分页条件查询

// 根据用户id分页查询当前用户的购物车列表
@Override
public JsonPage listCarts(Integer page, Integer pageSize) {
// 获得用户id
Long userId=getUserId();
// 执行查询前设置分页条件
PageHelper.startPage(page,pageSize);
// 执行分页查询
List list=omsCartMapper.selectCartsByUserId(userId);
// 实例化PageInfo对象获得分页信息后将它转换为JsonPage返回
return JsonPage.restPage(new PageInfo<>(list));
}

下面开发控制层,调用方法进行测试

OmsCartController添加方法如下

// 分页查询当前用户购物车中的信息
@GetMapping("/list")
@ApiOperation("分页查询当前用户购物车中的信息")
@ApiImplicitParams({
@ApiImplicitParam(value = "页码",name = "page",dataType = "int",example = "1"),
@ApiImplicitParam(value = "每页条数",name = "pageSize",
dataType = "int",example = "5")
})
  @PreAuthorize("hasRole('ROLE_user')")
public JsonResult> listCartByPage(
  // 当控制器参数可能为空,当空时,我们要给它赋默认值时,可以用下面的格式
  @RequestParam(required = false,defaultValue = WebConsts.DEFAULT_PAGE)
  Integer page,
  @RequestParam(required = false,defaultValue = WebConsts.DEFAULT_PAGE_SIZE)
Integer pageSize
){
  // 控制层调用业务逻辑层代码
  JsonPage jsonPage=omsCartService.listCarts(page,pageSize);
  return JsonResult.ok(jsonPage);
}

启动nacos\seata

启动leaf\sso\order模块

测试http://localhost:10005/doc.html

删除\清空购物车

删除购物车的持久层

我们删除购物车的功能支持同时删除一个或多个购物车中的商品

基本思路就是将一个要删除的购物车商品的id数组传入到Mapper中进行删除

在OmsCartMapper接口中添加放方法

// 根据购物车的id删除商品(支持删除多个商品)
int deleteCartsByIds(Long[] ids);

对应的mapper.xml



delete from
oms_cart
where
id in

#{id}

删除购物车的业务逻辑层

OmsCartServiceImpl添加方法

// 按ids数组中的id值删除cart表中信息
@Override
public void removeCart(Long[] ids) {
// 删除是包含返回值的
int rows=omsCartMapper.deleteCartsByIds(ids);
if(rows==0){
throw new CoolSharkServiceException(ResponseCode.NOT_FOUND,
"购物车中没有您要删除的商品");
}
}

开发控制层代码

OmsCartController

@PostMapping("/delete")
@ApiOperation("根据用户选择的购物车商品删除(支持批量)")
@ApiImplicitParam(value = "删除购物车的id",name="ids",required = true,
dataType = "array")
@PreAuthorize("hasRole('ROLE_user')")
public JsonResult removeCartsByIds(Long[] ids){
omsCartService.removeCart(ids);
return JsonResult.ok();
}

开发清空当前登录用户购物车的功能


delete from
oms_cart
where
user_id=#{userId}
@Override
public void removeAllCarts() {
}

清空购物车功能

Mapper接口

// 删除当前用户购物车中所有内容
int deleteCartsByUserId(Long userId);

mapper.xml



delete from
oms_cart
where
user_id=#{userId}

OmsCartServiceImpl

// 清空当前登录用户购物车
@Override
public void removeAllCarts() {
Long userId=getUserId();
int rows=omsCartMapper.deleteCartsByUserId(userId);
if(rows==0){
throw new CoolSharkServiceException(ResponseCode.NOT_FOUND,"您的购物车中没有商品");
}
}

OmsCartController

// 根据用户id清空购物车
@PostMapping("/delete/all")
@ApiOperation("根据用户id清空购物车")
@PreAuthorize("hasRole('ROLE_user')")
public JsonResult removeCartsByUserId(){
omsCartService.removeAllCarts();;
return JsonResult.ok("购物车已清空");
}

修改购物车商品数量

开发业务逻辑层

因为前面我们已经完成了修改购物车数量的持久层,所以不需要再编写了,直接从业务层开始

// 修改购物车商品数量的方法
@Override
public void updateQuantity(CartUpdateDTO cartUpdateDTO) {
// 持久层中已经包含了修改数量的方法,但是参数是OmsCart
// 将本方法的cartUpdateDTO参数值赋值给OmsCart再调用持久层方法即可
OmsCart omsCart=new OmsCart();
BeanUtils.copyProperties(cartUpdateDTO,omsCart);
// 调用持久层实施修改
omsCartMapper.updateQuantityById(omsCart);
}

控制层OmsCartController

// 修改购物车数量
@PostMapping("/update/quantity")
@ApiOperation("修改购物车数量")
@PreAuthorize("hasRole('ROLE_user')")
public JsonResult updateQuantity(@Validated CartUpdateDTO cartUpdateDTO){
omsCartService.updateQuantity(cartUpdateDTO);
return JsonResult.ok("修改完成");
}

重启order测试清空和修改购物车数量的功能

学习记录,如有侵权请联系删除

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章