SpringCloud商城day10 购物车-2021-10-18

SpringCloud商城day10 购物车-2021-10-18,第1张

SpringCloud商城day10 购物车-2021-10-18

一. SpringSecurity权限控制

1. 用户授权-> 获取令牌-> 网关鉴权-> 登录角色的权限控制-> JWT自定义数据(角色+权限)-> 访问资源微服务-> 判断令牌的数据-> 普通用户/管理员用户

(1). 用户权限加载: com.changgou.user.oauth.config.UserDetailsServiceImpl.java

//创建User对象
String permission = "salesman, accountant, user";

(2). User微服务: com.changgou.user.config.ResourceServerConfig.java

//开启SpringSecurity的权限注解 激活方法的@PreAuthorize
@EnableGlobalMethodSecurity(prePostEnabled=true, secureEnabled=true)

(3). 用户登录携带角色信息 com.changgou.user.controller.UserController.java

@PreAuthorize("hasAnyAuthority(accountant)")  //必须携带权限

二. 购物车流程

1. 京东: 用户未登录-> 添加购物车-> 数据保存到coolie-> 用户登录后-> 数据保存到redis

2. 天猫: 用户登录后-> 添加购物车-> 存到redis

3. 实现思路: 用户点击添加购物车-> 传入商品SKU和数量-> 存入redis-> 查询购物车->返回redis数据

4. 组成: 

        (1). 表: tb_order_item

        (2). 添加购物车-> 订单微服务-> feign调用-> 商品微服务

(1) changgou_service_goods_api中: com.changgou.goods.feign.SkuFeign.java
 
    @GetMapping("/sku/{id}")
    public Result findById(@PathVariable("id") String id);

     (3) user微服务: 

(1) 依赖: goods-api

(2) OrderApplication.java开启feign:          
    @EnableFeignClients(basePackages="com.changgou.goods.feign")

(3) com.changgou.order.service.CartService.java
    void addCart(String skuId, Integer num, String username);
    //查询购物车数据
    Map list(String username);

(4) service.impl.CartServiceImpl.java
@Service
public class CartServiceImpl implements CartService {
    private static final String CART ="cart_";
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SkuFeign skuFeign;   
    @Autowired
    private SpuFeign spuFeign;
    @Override
    public void addCart(String skuId, Integer num, String username) {
        //1.查询redis中相对应的商品信息
        //hash形式保存数据格式: key(cart_) (filed value)==(map)
        OrderItem orderItem = (OrderItem) redisTemplate.boundHashOps(CART + username).get(skuId);
        if (orderItem != null) {
            //2. 当前商品在redis中存在, 则更新商品数量与价钱
            orderItem.setNum(orderItem.getNum() + num);
            if (orderItem.getNum()<=0){
                //删除该商品
                redisTemplate.boundHashOps(CART+username).delete(skuId);
                return;
            }
            orderItem.setMoney(orderItem.getNum() * orderItem.getPrice());
            orderItem.setPayMoney(orderItem.getNum() * orderItem.getPrice());
        } else {
            //3. 当前商品在redis中不存在, 则添加商品到redis中
            Sku sku = skuFeign.findById(skuId).getData();
            Spu spu = spuFeign.findSpuById(sku.getSpuId()).getData();
            //4. 封装orderItem
            orderItem = this.sku2OrderItem(sku, spu, num);
        }
        //5. 将orderItem添加到redis中
        redisTemplate.boundHashOps(CART+username).put(skuId,orderItem);
    }
    //查询购物车列表数据
    @Override
    public Map list(String username) {
        HashMap map = new HashMap<>();
        List orderItemList = redisTemplate.boundHashOps(CART + username).values();
        map.put("orderItemList", orderItemList);
        //商品总数量和总价格
        Integer totalNum = 0;
        Integer totalMoney = 0;
        for (OrderItem orderItem : orderItemList) {
            totalNum += orderItem.getNum();
            totalMoney += orderItem.getMoney();
        }
        map.put("totalNum",totalNum);
        map.put("totalMoney", totalMoney);
        return map;
    }
    //sku转换为orderItem
    private OrderItem sku2OrderItem(Sku sku, Spu spu, Integer num) {
        OrderItem orderItem = new OrderItem();
        orderItem.setSpuId(sku.getSpuId());
        orderItem.setSkuId(sku.getId());
        orderItem.setName(sku.getName());
        orderItem.setPrice(sku.getPrice());
        orderItem.setNum(num);
        orderItem.setMoney(num*orderItem.getPrice());       //单价*数量
        orderItem.setPayMoney(num*orderItem.getPrice());    //实付金额
        orderItem.setImage(sku.getImage());
        orderItem.setWeight(sku.getWeight()*num);           //重量=单个重量*数量
        //分类ID设置
        orderItem.setCategoryId1(spu.getCategory1Id());
        orderItem.setCategoryId2(spu.getCategory2Id());
        orderItem.setCategoryId3(spu.getCategory3Id());
        return orderItem;
    }
}  

(5) CartController.java
@GetMapping("/addCart")
public Result addCart(@RequestParam("skuId")String skuId, @RequestParam("num")Integer num) {
        //静态获取登录人信息  String username = "itcast";
        //动态获取登录人信息
        String username = tokenDecode.getUserInfo().get("username");
        cartService.addCart(skuId, num, username);
        return new Result(true,StatusCode.OK,"添加购物车成功");
    }

三. 购物车渲染

1. 用户请求网关-> 转发到购物车渲染-> 渲染服务调用order微服务-> 获取购物车数据->Thymelaf渲染购物车列表

2. changgou_web_order订单渲染服务

(1) 依赖: order-api / changgou_common / thymeleaf
(2) yml配置: server / spring / feign / eureka / hystrix / ribbon
(3) 启动类: 
    @SpringBootApplication
    @EnableEurekaClient
    @EnableFeignClients(basePackages = {"com.changgou.order.feign","com.changgou.user.feign", "com.changgou.pay.feign"})  
    WebOrderApplication.java

(4) changgou_service_order_api.CartFeign.java
    @FeignClient(name = "order")
public interface CartFeign {
    @GetMapping("/cart/addCart")
    public Result addCart(@RequestParam("skuId")String skuId, @RequestParam("num")Integer num);
    @GetMapping("/cart/list")
    public Map list();
}

(5)com.changgou.web.order.controller.CartController.java
    @Controller
@RequestMapping("/wcart")
public class CartController {
    @Autowired
    private CartFeign cartFeign;
    //查询购物车
    @GetMapping("/list")
    public String list(Model model) {
        Map map = cartFeign.list();
        model.addAttribute("items",map);
        return "cart";
    }
    //添加购物车
    @GetMapping("/add")
    @ResponseBody
    public Result add(String id, Integer num) {
        cartFeign.addCart(id, num);
        Map map = cartFeign.list();
        return new Result<>(true, StatusCode.OK, "添加购物车成功",map);
    }
}

四. 微服务间的认证访问

1. order服务对接oauth2认证服务-

(1) 公钥public.key 放入order服务的resources目录下
(2) 导入依赖: oauth2
(3)配置类: ResourceServerConfig.java

2. 用户访问购物车数据-> 访问前端网关->登录则增强请求头-> 包含JWT令牌信息-> 转发到web_order渲染服务-> FeignIntercepter拦截器传递令牌-> 远程调用order微服务

(1)changgou_common: com.changgou.interceptor.FeignInterceptor.java

3. 动态获取当前登录人

(1) 登录人信息 -> 封装在JWT令牌 -> 工具类TokenDecode.java
(2) TokenDecode.java放入changgou_common服务
(3) JJWT依赖放入 changgou_service_order.CartController.java
    //静态获取登录人信息  String username = "itcast";
    //动态获取登录人信息
    String username = tokenDecode.getUserInfo().get("username");

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/3982519.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-10-21
下一篇2022-10-21

发表评论

登录后才能评论

评论列表(0条)

    保存