zoukankan      html  css  js  c++  java
  • 购物车(登录后)

    添加商品sku到购物车,我们需要用fegin调用商品微服务完成根据商品id查询商品sku的操作
    **
    【商品微服务】把根据商品id查询商品sku的操作定义出来
    用fegin对外暴露
    【订单微服务】操作添加购物车
    **
    数据结构:

    1)前端浏览器发送携带skuId,num(cookie)的请求
    --------------------网关gateway-web-------------------
    2)网关拦截请求&请求参数,判断书否拦截请求,拦截请求后根据请求cookie获得jwt,并将令牌添加的请求头和请求放行,路由到对应微服务(web-order)
    --------------------前端web-order---------------------
    3)前端工程接收到网关转发到的请求&请求参数,校验用户携带的jwt,校验通过则访问controller
    controller中会根据需要调用对应的微服务工程(service-order里在order-api中定义的的cart fegin),获取数据或者执行增删改操作。
    --------------------远程调用接口service-order-api-----------
    --------------------后端微服务service-order-----------
    4)controller控制层接收前台请求&请求参数,获取登录人的用户名,把skuId,num,username传递给service,调用service完成业务逻辑处理,返回给前端浏览器。
    5)service业务层,根据用户名name,skuId查询redis,获取当前用户购物车信息cart中指定的orderitem的信息,
    如果orderitem没有就把skuId转换为orderitem并存入购物车
    如果orderitem已经存在,就只需要对orderitem做数量增减和金额变动。

    fegin功能接口:

    fegin的调用

    购物车接口

    购物车实现

    @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中相对应的商品信息
            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();
    
                //封装orderItem
               orderItem = this.sku2OrderItem(sku,spu,num);
            }
    
            //3.将orderitem添加到redis中
            redisTemplate.boundHashOps(CART+username).put(skuId,orderItem);
        }
    
        //查询购物车列表数据
        @Override
        public Map list(String username) {
            Map map = new HashMap();
    
            List<OrderItem> 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;
        }
    
        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(orderItem.getPrice()*num);
            orderItem.setPayMoney(orderItem.getPrice()*num);
            orderItem.setImage(sku.getImage());
            orderItem.setWeight(sku.getWeight()*num);
            //分类信息
            orderItem.setCategoryId1(spu.getCategory1Id());
            orderItem.setCategoryId2(spu.getCategory2Id());
            orderItem.setCategoryId3(spu.getCategory3Id());
            return orderItem;
        }
    }
    

    购物车渲染 web

    用户想获得购物车列表- 请求前端网关
    前端网关把用户请求转发到【订单购物车渲染服务】
    【订单购物车渲染服务】调用【购物车订单微服务】获取购物车列表数据
    【订单购物车渲染服务】得到了购物车列表数据,进行thymeleaf进行页面渲染
    页面渲染后返回页面给用户

    配置文件:

    server:
      port: 9011
    spring:
      application:
        name: order-web
      main:
        allow-bean-definition-overriding: true   #当遇到同样名字的时候,是否允许覆盖注册
      thymeleaf:
        cache: false
    eureka:
      client:
        service-url:
          defaultZone: http://127.0.0.1:6868/eureka
      instance:
        prefer-ip-address: true
    feign:
      hystrix:
        enabled: true
      client:
        config:
          default:   #配置全局的feign的调用超时时间  如果 有指定的服务配置 默认的配置不会生效
            connectTimeout: 60000 # 指定的是 消费者 连接服务提供者的连接超时时间 是否能连接  单位是毫秒
            readTimeout: 80000  # 指定的是调用服务提供者的 服务 的超时时间()  单位是毫秒
    #hystrix 配置
    hystrix:
      command:
        default:
          execution:
            timeout:
              #如果enabled设置为false,则请求超时交给ribbon控制
              enabled: true
            isolation:
              strategy: SEMAPHORE
              thread:
                # 熔断器超时时间,默认:1000/毫秒
                timeoutInMilliseconds: 80000
    #请求处理的超时时间
    ribbon:
      ReadTimeout: 4000
      #请求连接的超时时间
      ConnectTimeout: 3000
    

    使用方法:

    实现方法

    以fegin形式暴露方法:

    前端:

        <li class="yui3-u-1-8">
    	<a href="javascript:void(0)" class="increment mins" @click="add(item.skuId,-1)">-</a>
    	<input autocomplete="off" type="text" v-model="item.num" @blur="add(item.skuId,item.num)" minnum="1" class="itxt" />
    	<a href="javascript:void(0)" class="increment plus" @click="add(item.skuId,1)">+</a>
        </li>
    
    ... 
    
    	<script th:inline="javascript">
    		var app = new Vue({
    			el:"#app",
    			data:{
    				items:[[${items}]]
    			},
    			methods:{
    				add:function (skuId,num) {
    					axios.get("/api/wcart/add?id="+skuId+"&num="+num).then(function (response) {
    						if (response.data.flag){
    							app.items=response.data.data;
    						}
    					})
    				}
    			}
    		})
    	</script>
    

    订单服务对接Oauth:
    公钥:

    配置类:

    @Configuration
    @EnableResourceServer
    @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)//激活方法上的PreAuthorize注解
    public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    
        //公钥
        private static final String PUBLIC_KEY = "public.key";
    
        /***
         * 定义JwtTokenStore
         * @param jwtAccessTokenConverter
         * @return
         */
        @Bean
        public TokenStore tokenStore(JwtAccessTokenConverter jwtAccessTokenConverter) {
            return new JwtTokenStore(jwtAccessTokenConverter);
        }
    
        /***
         * 定义JJwtAccessTokenConverter
         * @return
         */
        @Bean
        public JwtAccessTokenConverter jwtAccessTokenConverter() {
            JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
            converter.setVerifierKey(getPubKey());
            return converter;
        }
        /**
         * 获取非对称加密公钥 Key
         * @return 公钥 Key
         */
        private String getPubKey() {
            Resource resource = new ClassPathResource(PUBLIC_KEY);
            try {
                InputStreamReader inputStreamReader = new InputStreamReader(resource.getInputStream());
                BufferedReader br = new BufferedReader(inputStreamReader);
                return br.lines().collect(Collectors.joining("
    "));
            } catch (IOException ioe) {
                return null;
            }
        }
    
        /***
         * Http安全配置,对每个到达系统的http请求链接进行校验
         * @param http
         * @throws Exception
         */
        @Override
        public void configure(HttpSecurity http) throws Exception {
            //所有请求必须认证通过
            http.authorizeRequests()
                    //下边的路径放行
                    .antMatchers(
                            "/user/add","/user/load/**"). //配置地址放行
                    permitAll()
                    .anyRequest().
                    authenticated();    //其他地址需要认证授权
        }
    }
    
    
  • 相关阅读:
    Nginx的安装与部署
    什么是Nginx?为什么使用Nginx?
    spark 中的RDD编程 -以下基于Java api
    java反射
    POST-GET请求
    Spring Boot 专栏
    【Shiro】Apache Shiro架构之身份认证(Authentication)
    maven项目如何启动运行---发布到tomcat中
    一位资深程序员大牛给予Java初学者的学习路线建议
    SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
  • 原文地址:https://www.cnblogs.com/maomaodesu/p/12749450.html
Copyright © 2011-2022 走看看