练竹园何平安

企业级开发项目“苍穹外卖”(三)

Toretto·2023-09-17 16:35·287 次阅读

企业级开发项目“苍穹外卖”(三)

设置店铺营业状态#

先去我之前写的博客“Redis数据库学习笔记"学习Redis的基本操作。

在config层下创建Redis的配置类,里面编写:

@Configuration
@Slf4j
public class RedisConfiguration {

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
        log.info("开始创建redis对象:{}",redisConnectionFactory);
        RedisTemplate redisTemplate  = new RedisTemplate();
        //设置redis工厂对象
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //设置redis序列化器
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        return redisTemplate;
    }
}

 然后再在controller层里面创建shop店铺管理的类,里面编写设置店铺状态和查询店铺状态的代码:

@RestController("adminShopController")
@Slf4j
@Api(tags = "店铺管理")
@RequestMapping("/admin/shop")
public class ShopController {

    @Autowired
    private RedisTemplate redisTemplate;

    @PutMapping("/{status}")
    @ApiOperation("设置店铺营业状态")
    public Result setStaus(@PathVariable Integer status){
        log.info("设置店铺营业状态:{}",status ==1 ?"营业中": "打烊中");
        redisTemplate.opsForValue().set("SHOP_STATUS",status);
        return Result.success();
    }

    @GetMapping("/status")
    @ApiOperation("获取店铺营业状态")
    public Result<Integer> getStatus(){
        Integer shopStatus = (Integer) redisTemplate.opsForValue().get("SHOP_STATUS");
        log.info("获取店铺营业状态:{}",shopStatus ==1 ?"营业中": "打烊中");
        return Result.success(shopStatus);
    }
}

记得在yml和的-dev yml里面配置redis的用户连接信息:

redis:
    host: localhost
    port: 6379
    password: 123456
    database: 1

 接口管理分开管理端和用户端#

·  在WebMvcConfiguration里面复制一个bean注解下的代码,并在new Docket下编写.groupName("管理端接口/用户端接口"),具体代码如下:

/**
     * 通过knife4j生成接口文档
     * @return
     */
    @Bean
    public Docket docket1() {
        log.info("准备生成接口文档...");
        ApiInfo apiInfo = new ApiInfoBuilder()
                .title("苍穹外卖项目接口文档")
                .version("2.0")
                .description("苍穹外卖项目接口文档")
                .build();
        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .groupName("管理端接口")
                .apiInfo(apiInfo)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.sky.controller.admin"))
                .paths(PathSelectors.any())
                .build();
        return docket;
    }

    @Bean
    public Docket docket2() {
        log.info("准备生成接口文档...");
        ApiInfo apiInfo = new ApiInfoBuilder()
                .title("苍穹外卖项目接口文档")
                .version("2.0")
                .description("苍穹外卖项目接口文档")
                .build();
        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .groupName("用户端接口")
                .apiInfo(apiInfo)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.sky.controller.user"))
                .paths(PathSelectors.any())
                .build();
        return docket;
    }

这样在项目接口文档里面就可以区分开这两个端了。

微信小程序开发#

下载微信开发者工具,然后将资料里面的前端文件导入进来,输入自己的openid(openid和小程序appid和secret自己去网上搜),微信小程序开发我博客之前也写过。

将资料里面的用户端文件导入进对应server文件夹里

Spring Cache#

maven坐标:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

常用注解:

 在苍穹外卖项目中的应用:用于缓存套餐数据,只需在启动类上加入@EnableCaching注解,在admin的SetmealController里面的删改和启动禁用上加上@CacheEvict(cacheNames = "setmealCache",allEntries = true)注解,增加套餐上添加@CacheEvict(cacheNames = "setmealCache",key="#setmealDTO.categoryId")注解。在user的SetmealController的根据id查询套餐上添加@Cacheable(cacheNames ="setmealCache",key="#categoryId")

购物车管理#

后面的购物车管理就跟之前的差不多了,直接上impl的代码:

    @Autowired
    private ShoppingCartMapper shoppingCartMapper;
    @Autowired
    private SetmealMapper setmealMapper;
    @Autowired
    private DishMapper dishMapper;

    /**
     * 添加物品
     * @param shoppingCartDTO
     */
    public void addShoppingCart(ShoppingCartDTO shoppingCartDTO) {
        //判断当前加入购物车的商品是否存在
        ShoppingCart shoppingCart=new ShoppingCart();
        BeanUtils.copyProperties(shoppingCartDTO,shoppingCart);
        Long userId= BaseContext.getCurrentId();
        shoppingCart.setUserId(userId);

        List<ShoppingCart> list =shoppingCartMapper.list(shoppingCart);
        //如果已经存在了,只需要将数量增加
        if (list !=null&& list.size()>0){
            ShoppingCart cart=list.get(0);
            cart.setNumber(cart.getNumber()+1);
            shoppingCartMapper.updateById(cart);
        }else {
            //判断是为菜品还是套餐
            Long dishId = shoppingCart.getDishId();
            if (dishId !=null){
                Dish dish=dishMapper.getById(dishId);
                shoppingCart.setName(dish.getName());
                shoppingCart.setImage(dish.getImage());
                shoppingCart.setAmount(dish.getPrice());

                shoppingCart.setNumber(1);
                shoppingCart.setCreateTime(LocalDateTime.now());

            }else {
                //为套餐
                Long setmealId=shoppingCart.getSetmealId();
                Setmeal setmeal=setmealMapper.pageById(setmealId);
                shoppingCart.setName(setmeal.getName());
                shoppingCart.setImage(setmeal.getImage());
                shoppingCart.setAmount(setmeal.getPrice());

                shoppingCart.setNumber(1);
                shoppingCart.setCreateTime(LocalDateTime.now());

            }
            shoppingCartMapper.insert(shoppingCart);
        }

    }

导入收货地址接口(AdressBook)和用户下单接口代码(Order),代码的话就自己去下载看看吧,没啥新技术。

除了用户下单的 ServiceImpl的代码有点难:其他的还将就 

/**
     * 用户下单
     *
     * @param ordersSubmitDTO
     * @return
     */
    @Transactional
    public OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO) {
        //异常情况的处理(收货地址为空、购物车为空)
        AddressBook addressBook = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId());
        if (addressBook == null) {
            throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }

        Long userId = BaseContext.getCurrentId();
        ShoppingCart shoppingCart = new ShoppingCart();
        shoppingCart.setUserId(userId);

        //查询当前用户的购物车数据
        List<ShoppingCart> shoppingCartList = shoppingCartMapper.list(shoppingCart);
        if (shoppingCartList == null || shoppingCartList.size() == 0) {
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }

        //构造订单数据
        Orders order = new Orders();
        BeanUtils.copyProperties(ordersSubmitDTO,order);
        order.setPhone(addressBook.getPhone());
        order.setAddress(addressBook.getDetail());
        order.setConsignee(addressBook.getConsignee());
        order.setNumber(String.valueOf(System.currentTimeMillis()));
        order.setUserId(userId);
        order.setStatus(Orders.PENDING_PAYMENT);
        order.setPayStatus(Orders.UN_PAID);
        order.setOrderTime(LocalDateTime.now());

        //向订单表插入1条数据
        orderMapper.insert(order);

        //订单明细数据
        List<OrderDetail> orderDetailList = new ArrayList<>();
        for (ShoppingCart cart : shoppingCartList) {
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(cart, orderDetail);
            orderDetail.setOrderId(order.getId());
            orderDetailList.add(orderDetail);
        }

        //向明细表插入n条数据
        orderDetailMapper.insertBatch(orderDetailList);

        //清理购物车中的数据
        shoppingCartMapper.deleteByUserId(userId);

        //封装返回结果
        OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder()
                .id(order.getId())
                .orderNumber(order.getNumber())
                .orderAmount(order.getAmount())
                .orderTime(order.getOrderTime())
                .build();

        return orderSubmitVO;
    }

这里就顺便补充下@Transactional注解:

事务处理translational
概念:指一组原子性的操作序列,这些操作要么全部执行,要么全部不执行

特性:原子性、一致性、隔离性和持久性

应用场景:当一组操作需要同时执行时。–金融行业、电商平台、物流行业

开发流程:在需要事务管理的方法上加注解:@Transactional()

rollbackFor属性:回滚指定类型的异常:@Transactional(rollbackFor =
Exception.class)

Propagation属性 :

事务传播:当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行事务控制。

REQUIRED – 【默认值】需要事务,有则加入,无则创建新事务

REQUIRES_NEW --总是创建新事务

内网穿透#

封面图就是内网穿透的原理图:

进入临时域名的使用网站:https://dashboard.cpolar.com/,注册一个账户登进去选择免费的临时域名,下载cpolar的安装exe,按照步骤安装好就行。然后回到cpolar网站选择验证,复制你的Authtoken,然后运行刚刚安装好的cpolar.exe,输入cpolar.exe authtoken 【刚刚复制的】 ,再输入cpolar.exe http 8080然后回车,这时您的公网域名就创建好了,别人的电脑和手机就可以访问你的苍穹外卖了。可以输入https://xxxx/doc.html访问你的接口文档。

其他的接口就参考day9的资料吧:

 

微信小程序备案上线#

剩下的催单接口和表格输出就自己去看黑马的吧~

苍穹外卖,完结!

 

 

posted @   何平安  阅读(325)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
浏览器标题切换end
点击右上角即可分享
微信分享提示
目录