苍穹外卖学习day09—学习日记

今日完结任务:

学习了HttpClient是什么

学习了微信小程序的开发流程

完成了苍穹外卖用户端的用户微信登录接口

完成了商品数据查看,并使它们到Redis缓存

今日收获:

1.完成了用户端的微信登录接口

微信登录流程

流程图:

步骤分析:

  1. 小程序端,调用wx.login()获取code,就是授权码。
  2. 小程序端,调用wx.request()发送请求并携带code,请求开发者服务器(自己编写的后端服务)。
  3. 开发者服务端,通过HttpClient向微信接口服务发送请求,并携带appId+appsecret+code三个参数。
  4. 开发者服务端,接收微信接口服务返回的数据,session_key+opendId等。opendId是微信用户的唯一标识。
  5. 开发者服务端,自定义登录态,生成令牌(token)和openid等数据返回给小程序端,方便后绪请求身份校验。
  6. 小程序端,收到自定义登录态,存储storage。
  7. 小程序端,后绪通过wx.request()发起业务请求时,携带token。
  8. 开发者服务端,收到请求后,通过携带的token,解析当前登录用户的id。
  9. 开发者服务端,身份校验通过后,继续相关的业务逻辑处理,最终返回业务数据。
接口设计

通过微信登录的流程,如果要完成微信登录的话,最终就要获得微信用户的openid。在小程序端获取授权码后,向后端服务发送请求,并携带授权码,这样后端服务在收到授权码后,就可以去请求微信接口服务。最终,后端向小程序返回openid和token等数据。

服务器端:

调用微信接口服务,获取用户唯一ID:

UserService层:

除此之外,我们也需要拦截器把未登录状态时候的一切请求进行拦截(查询餐厅状态和登录请求除外)

 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //判断当前拦截到的是Controller的方法还是其他资源
        if (!(handler instanceof HandlerMethod)) {
            //当前拦截到的不是动态方法,直接放行
            return true;
        }

        //1、从请求头中获取令牌
        String token = request.getHeader(jwtProperties.getAdminTokenName());

        //2、校验令牌
        try {
            log.info("jwt校验:{}", token);
            Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token);
            Long empId = Long.valueOf(claims.get(JwtClaimsConstant.EMP_ID).toString());
            log.info("当前员工id:", empId);

            //通过ThreadLocal来存储empId,使得它在同一个线程的其他包中可以使用
            BaseContext.setCurrentId(empId);
            //3、通过,放行
            return true;
        } catch (Exception ex) {
            //4、不通过,响应401状态码
            response.setStatus(401);
            return false;
        }
    }

拦截器的思想就是校验下发的token令牌,如果令牌无法被解析或者没有令牌,说明当前用户处于未登陆状态,就不可以访问未开放的网络请求

最后我们还需要在配置类中注册拦截器

  registry.addInterceptor(jwtTokenUserInterceptor)
                .addPathPatterns("/user/**")
                .excludePathPatterns("/user/user/login")
                .excludePathPatterns("/user/shop/status");

2.学习了对菜品数据缓存的功能 

用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大。就会导致用户在访问时系统响应慢、用户体验差。

实现思路

因此为了提高我们的用户效率,我们采用这样一种思想:建立一块缓存区,在用户查询对应数据的时候,先看看缓存区有没有,如果缓存区有,直接发送缓存区中的数据,如果缓存区没有,再查询数据库,并且把查询到的数据同时存到缓冲区中,便捷下次查询的效率。

而我们建立缓存区的方法是使用Redis数据库,在前面我们就介绍过Redis,他是一个存储在内存中的键值类型的数据库,这大大优化了查询效率。

代码开发

修改用户端接口 DishController 的 list 方法,加入缓存处理逻辑:

@Autowired
    private RedisTemplate redisTemplate;
	/**
     * 根据分类id查询菜品
     *
     * @param categoryId
     * @return
     */
    @GetMapping("/list")
    @ApiOperation("根据分类id查询菜品")
    public Result<List<DishVO>> list(Long categoryId) {

        //构造redis中的key,规则:dish_分类id
        String key = "dish_" + categoryId;

        //查询redis中是否存在菜品数据
        List<DishVO> list = (List<DishVO>) redisTemplate.opsForValue().get(key);
        if(list != null && list.size() > 0){
            //如果存在,直接返回,无须查询数据库
            return Result.success(list);
        }
		////////////////////////////////////////////////////////
        Dish dish = new Dish();
        dish.setCategoryId(categoryId);
        dish.setStatus(StatusConstant.ENABLE);//查询起售中的菜品

        //如果不存在,查询数据库,将查询到的数据放入redis中
        list = dishService.listWithFlavor(dish);
        ////////////////////////////////////////////////////////
        redisTemplate.opsForValue().set(key, list);

        return Result.success(list);
    }

如果我的内容对你有帮助,请点赞,评论,收藏创作不易,大家的支持就是我坚持下去的动力! 

                       

 

苍穹外卖项目 Day3 的学习内容主要集中在菜品管理的业务逻辑上,特别是删除菜品时的相关规则与处理。具体来说,在删除菜品时,需要首先判断该菜品是否处于起售状态。如果该菜品正处于起售状态,则不允许被删除[^1]。 此外,还需要检查该菜品是否包含在某个套餐中。如果该菜品已经被包含在一个或多个套餐中,则同样不允许删除该菜品。只有在满足可以删除的情况下,才能执行删除操作,并且在删除菜品的同时,也需要删除与之相关的口味信息[^1]。 ### 删除菜品的主要步骤 1. 判断菜品是否为起售状态,起售状态的菜品不能够被删除。 2. 检查菜品是否属于一个或多个套餐的一部分,如果是,则不能删除。 3. 如果以上两个条件都不满足,则允许删除该菜品及其关联的口味数据。 这些逻辑确保了系统的数据一致性,并避免了在业务运行过程中出现不一致或错误的状态。 ### 示例代码片段 以下是一个伪代码示例,用于展示删除菜品的基本逻辑: ```java public void deleteDish(Dish dish) { // 检查菜品是否处于起售状态 if (dish.getStatus() == 1) { // 假设1表示起售状态 throw new RuntimeException("起售状态的菜品不能删除"); } // 检查菜品是否被包含在套餐中 List<Setmeal> setmeals = setmealService.findSetmealsByDishId(dish.getId()); if (!setmeals.isEmpty()) { throw new RuntimeException("该菜品已被包含在套餐中,不能删除"); } // 删除菜品及其相关口味 dishRepository.deleteById(dish.getId()); flavorRepository.deleteByDishId(dish.getId()); } ``` ### 扩展知识点 除了上述基本逻辑外,还可以扩展一些其他功能,例如: - 添加日志记录,以便追踪删除操作的具体情况。 - 引入事务管理机制,确保删除菜品和对应口味的操作具有原子性。 - 在删除之前进行权限验证,确保用户有权限执行删除操作。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值