【苍穹外卖】Day 7 地址簿、下单、定时处理

news2024/11/15 3:36:51

 1 地址簿模块

地址簿实体对象:

package com.sky.entity;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * 地址簿
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AddressBook implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;

    //用户id
    private Long userId;

    //收货人
    private String consignee;

    //手机号
    private String phone;

    //性别 0 女 1 男
    private String sex;

    //省级区划编号
    private String provinceCode;

    //省级名称
    private String provinceName;

    //市级区划编号
    private String cityCode;

    //市级名称
    private String cityName;

    //区级区划编号
    private String districtCode;

    //区级名称
    private String districtName;

    //详细地址
    private String detail;

    //标签
    private String label;

    //是否默认 0否 1是
    private Integer isDefault;
}

 数据库地址簿表

1.1 Path 和 Method 设计

 

1.2 实现

controller

package com.sky.controller.user;

import com.sky.context.BaseContext;
import com.sky.entity.AddressBook;
import com.sky.result.Result;
import com.sky.service.AddressBookService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/user/addressBook")
@Api(tags = "地址簿相关代码")
public class AddressBookController {
    @Autowired
    private AddressBookService addressBookService;

    /**
     * 新增地址
     *
     * @param addressBook
     * @return
     */
    @ApiOperation("新增地址")
    @PostMapping
    public Result save(@RequestBody AddressBook addressBook) {
        // 这里要进行处理:
        // 1.设置 userId,因为传过来的addressBook无法拿到用户 id
        addressBook.setUserId(BaseContext.getCurrentId());
        // 2.设置默认状态为 0,因为在新增地址模块不能先设置默认地址
        addressBook.setIsDefault(0);
        addressBookService.save(addressBook);
        return Result.success();
    }
    
    /**
     * 查询地址
     *
     * @return
     */
    @ApiOperation("查询地址")
    @GetMapping("/list")
    public Result<List<AddressBook>> list() {
        List<AddressBook> list = addressBookService.list();
        return Result.success(list);
    }

    /**
     * 查询默认地址
     *
     * @return
     */
    @ApiOperation("查询默认地址")
    @GetMapping("/default")
    public Result<AddressBook> getDefault() {
        AddressBook addressBook = addressBookService.getDefault();
        return Result.success(addressBook);
    }

    /**
     * 修改地址
     *
     * @return
     */
    @PutMapping
    @ApiOperation("修改地址")
    public Result update(@RequestBody AddressBook addressBook) {
        addressBookService.update(addressBook);
        return Result.success();
    }

    /**
     * 根据id删除地址
     *
     * @param id
     * @return
     */
    @DeleteMapping
    @ApiOperation("根据id删除地址")
    public Result deleteById(Long id) {
        addressBookService.deleteById(id);
        return Result.success();
    }

    /**
     * 根据id查询地址
     *
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    @ApiOperation("根据id查询地址")
    public Result<AddressBook> getById(@PathVariable Long id) {
        AddressBook addressBook = addressBookService.getById(id);
        return Result.success(addressBook);
    }

    /**
     * 设置默认地址
     *
     * @param addressBook
     * @return
     */
    @PutMapping("/default")
    @ApiOperation("设置默认地址")
    public Result setDefault(@RequestBody AddressBook addressBook) {
        addressBookService.setDefault(addressBook);
        return Result.success();
    }
}

service

package com.sky.service.impl;

import com.sky.context.BaseContext;
import com.sky.entity.AddressBook;
import com.sky.mapper.AddressBookMapper;
import com.sky.service.AddressBookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class AddressBookServiceImpl implements AddressBookService {
    @Autowired
    private AddressBookMapper addressBookMapper;


    /**
     * 新增地址
     */
    @Override
    public void save(AddressBook addressBook) {
        addressBookMapper.save(addressBook);
    }

    /**
     * 查询地址
     *
     * @return
     */
    @Override
    public List<AddressBook> list() {
        List<AddressBook> list = addressBookMapper.list();
        return list;
    }

    /**
     * 查询默认地址
     *
     * @return
     */
    @Override
    public AddressBook getDefault() {
        return addressBookMapper.getDefault();
    }

    /**
     * 修改地址
     *
     * @param addressBook
     */
    @Override
    public void update(AddressBook addressBook) {
        addressBookMapper.update(addressBook);
    }

    /**
     * 根据id删除地址
     *
     * @param id
     */
    @Override
    public void deleteById(Long id) {
        addressBookMapper.deleteById(id);
    }

    /**
     * 根据id查询地址
     *
     * @param id
     * @return
     */
    @Override
    public AddressBook getById(Long id) {
        AddressBook addressBook = addressBookMapper.getById(id);
        return addressBook;
    }

    /**
     * 设置默认地址
     *
     * @param addressBook
     */
    @Override
    public void setDefault(AddressBook addressBook) {
        //1、将当前用户的所有地址修改为非默认地址 update address_book set is_default = ? where user_id = ?
        addressBook.setIsDefault(0);
        addressBook.setUserId(BaseContext.getCurrentId());
        addressBookMapper.updateIsDefaultByUserId(addressBook);

        //2、将当前地址改为默认地址 update address_book set is_default = ? where id = ?
        addressBook.setIsDefault(1);
        addressBookMapper.update(addressBook);
    }
}

mapper

package com.sky.mapper;

import com.sky.entity.AddressBook;
import org.apache.ibatis.annotations.*;

import java.util.List;

@Mapper
public interface AddressBookMapper {
    /**
     * 新增地址
     *
     * @param addressBook
     */
    @Insert("insert into sky_take_out.address_book" +
            "(user_id, consignee, sex, phone, province_code, province_name, city_code, city_name, district_code, district_name, detail, label,is_default)" +
            "values " +
            "(#{userId}, #{consignee}, #{sex},#{phone}, #{provinceCode}, #{provinceName}, #{cityCode}, #{cityName}, #{districtCode}, #{districtName}, #{detail}, #{label}, #{isDefault})")
    void save(AddressBook addressBook);

    /**
     * 查询地址
     *
     * @return
     */
// 这里应该条件查询,代码复用
//    @Select("select * from sky_take_out.address_book")
    List<AddressBook> list();

    /**
     * 查询默认地址
     *
     * @return
     */
    @Select("select * from sky_take_out.address_book where is_default = 1")
    AddressBook getDefault();

    /**
     * 修改地址
     *
     * @param addressBook
     */
    void update(AddressBook addressBook);

    /**
     * 根据id删除地址
     *
     * @param id
     */
    @Delete("delete from sky_take_out.address_book where id = #{id}")
    void deleteById(Long id);

    /**
     * 根据id查询地址
     *
     * @param id
     * @return
     */
    @Select("select * from sky_take_out.address_book where id = #{id}")
    AddressBook getById(Long id);


    /**
     * 根据 用户id修改 是否默认地址
     *
     * @param addressBook
     */
    @Update("update sky_take_out.address_book set is_default = #{isDefault} where user_id = #{userId}")
    void updateIsDefaultByUserId(AddressBook addressBook);
}

xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >

<mapper namespace="com.sky.mapper.AddressBookMapper">
    <select id="list" parameterType="AddressBook" resultType="AddressBook">
        select * from sky_take_out.address_book
        <where>
            <if test="userId != null">and user_id = #{userId}</if>
            <if test="phone != null">and phone = #{phone}</if>
            <if test="isDefault != null">and is_default = #{isDefault}</if>
        </where>
    </select>

    <update id="update" parameterType="addressBook">
        update sky_take_out.address_book
        <set>
            <if test="consignee != null">consignee = #{consignee},</if>
            <if test="sex != null">sex = #{sex},</if>
            <if test="phone != null">phone = #{phone},</if>
            <if test="detail != null">detail = #{detail},</if>
            <if test="label != null">label = #{label},</if>
            <if test="isDefault != null">is_default = #{isDefault},</if>
        </set>
        where id = #{id}
    </update>

</mapper>

1.3 测试

2 下单

为什么两张表:

订单表 是描述订单的

订单明细表 是描述订单里面的商品

2.1 实现

controller

service

package com.sky.service.impl;

import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.OrdersSubmitDTO;
import com.sky.entity.AddressBook;
import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.entity.ShoppingCart;
import com.sky.exception.AddressBookBusinessException;
import com.sky.exception.ShoppingCartBusinessException;
import com.sky.mapper.AddressBookMapper;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.ShoppingCartMapper;
import com.sky.service.OrderService;
import com.sky.vo.OrderSubmitVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private AddressBookMapper addressBookMapper;
    @Autowired
    private ShoppingCartMapper shoppingCartMapper;

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

        ShoppingCart shoppingCart = new ShoppingCart();
        shoppingCart.setUserId(BaseContext.getCurrentId());
        List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);
        if (list == null || list.isEmpty()) {
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }

        // 订单表插入1条数据
        Orders order = new Orders();
        BeanUtils.copyProperties(ordersSubmitDTO, order);
        order.setOrderTime(LocalDateTime.now());
        order.setPayStatus(Orders.UN_PAID);
        order.setStatus(Orders.PENDING_PAYMENT);
        order.setNumber(String.valueOf(System.currentTimeMillis()));
        order.setPhone(addressBook.getPhone());
        order.setConsignee(addressBook.getConsignee());
        order.setUserId(BaseContext.getCurrentId());


        orderMapper.insert(order);
        // 订单明细表插入n条数据
        for (ShoppingCart cart :
                list) {
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(cart, orderDetail);
            orderDetail.setOrderId(order.getId()); // useGeneratedKeys="true" keyProperty="id"才可以获得主键值

            orderDetailMapper.insert(orderDetail);
        }

        // 清空购物车
        shoppingCartMapper.clean();
        // 封装VO返回
        OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder()
                .id(order.getId())
                .orderNumber(order.getNumber())
                .orderAmount(order.getAmount())
                .orderTime(order.getOrderTime())
                .build();
        return orderSubmitVO;
    }
}

mapper 略

2.2 测试

3 订单定时处理

3.1 定时处理 - - - Spring Task

        Spring Task 是 spring 框架提供的任务调度工具,可以按照约定的时间 自动执行某个代码逻辑

        cron 表达式 是一个字符串,通过 cron 表达式可以定义任务触发的时间,构成规则:分为 6 或 7 个域,由空格分隔开,每个域代表一个含义

        每个域的含义分别为:分钟小时(可选)

在线Cron表达式生成器 (qqe2.com)

        使用时,在启动类上加

@EnableScheduling 注解

        然后在定时任务类上加注解

@Scheduled(cron = " ")

在控制台每一秒输出当前时间

对于订单超时任务,每一分钟检查一次,如果超时则自动取消订单

4 WebSocket //Todo

(回过头再看)

        WebSocket 是基于 TCP 的一种新的 网络协议。它实现了 浏览器 与 服务器 全双工通信——浏览器和服务器只需要完成一次握手,两者之间就可以创建 持久性 的连接,并进行 双向数据传输

来单提醒:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2111080.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

docker基础知识-docker0网桥

文章目录 示意图Docker 网桥的工作原理Docker 网桥的优势Docker 网桥的局限性自定义网桥网络 Docker 网桥&#xff08;Docker bridge network&#xff09;是 Docker 默认的一种网络模式&#xff0c;它允许 Docker 容器之间通过一个虚拟的交换机进行通信。Docker 网桥网络为容器…

Java并发编程实战 03 | Java线程状态

在本文中&#xff0c;我们将深入探讨 Java 线程的六种状态以及它们之间的转换过程。其实线程状态之间的转换就如同生物生命从诞生、成长到最终死亡的过程一样。也是一个完整的生命周期。 首先我们来看看操作系统中线程的生命周期是如何转换的。 操作系统中的线程状态转换 线…

Web安全之GroovyShell讲解:错误与正确示范,安全问题与解决方案

1. 引言 Groovy 是一门基于 Java 虚拟机&#xff08;JVM&#xff09;的动态语言&#xff0c;而 GroovyShell 是 Groovy 提供的一个灵活强大的脚本执行工具。通过 GroovyShell&#xff0c;开发者可以在运行时动态执行 Groovy 脚本&#xff0c;它的灵活性非常适合那些需要动态编…

本地使用Docker部署Nexus Maven私有仓库工具结合内网穿透实现远程管理

文章目录 前言1. Docker安装Nexus2. 本地访问Nexus3. Linux安装Cpolar4. 配置Nexus界面公网地址5. 远程访问 Nexus界面6. 固定Nexus公网地址7. 固定地址访问Nexus 前言 本文主要介绍在Linux中使用Docker来一键部署Nexus Maven私有仓库工具并结合Cpolar内网穿透实现远程访问Nex…

【Python】应用:pyproj地理计算库应用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍pyproj地理计算库应用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下…

中国传媒业人工智能应用发展图谱2024

易观分析&#xff1a;传媒产业是指以传播各类信息、知识为核心&#xff0c;通过多种媒介形式进行内容生产、发布和分发的综合性产业。技术的进步和应用对于传媒产业发展变革起到了核心驱动力的作用&#xff0c;2022年生成式AI进入应用爆发期&#xff0c;不仅带动了人工智能产业…

APP中断测试知多少

中断测试有助于移动测试人员识别与系统或用户行为相关的潜在风险&#xff0c;以便在发生流量干扰时能够识别出可能导致意想不到或不期望结果的问题。 让我们深入探讨中断测试的细节及其手动或程序化实现方式。本文还介绍了用于自动化测试过程、加快测试执行速度并向用户提供高…

士兰微 SC32F5432 通过配置寄存器方式 将管脚配成开漏输出模式和TTL输入模式

目录 前言&#xff1a; 士兰微电子介绍 士兰微 SC32F5432介绍 士兰微 SC32F5432 通过配置寄存器方式 将管脚配成开漏输出模式和TTL输入模式 开漏输出模式 TTL输入模式 前言&#xff1a; 下面是对我在工作时公司所使用的一款国产芯片&#xff08;士兰微 SC32F5432&#x…

【Qt】事件的处理

事件的处理 事件的处理&#xff0c;让一段代码和某个事件关联起来&#xff0c;当事件触发的时候&#xff0c;就能指定这段代码。在之前学习的信号槽是通过 connect 来完成上述关联的&#xff0c;对于事件来说&#xff0c;需要让当前的类&#xff0c;重写某个事件处理函数。这里…

【服务对接】✈️SpringBoot 项目整合华为云 obs 对象存储服务

目录 &#x1f44b;前言 &#x1f440;一、环境准备 &#x1f331;二、整合实现 1.依赖引入 2.准备 AK 和 SK ​ 3.配置类 4.obs 工具类封装 &#x1f49e;️三、测试使用 &#x1f37b;四、 obs 客户端 &#x1f4eb;五、章末 &#x1f44b;前言 小伙伴们大家好&…

2024国赛数学建模C题完整论文:农作物的种植策略

农作物种植策略优化的数学建模研究&#xff08;完整论文&#xff0c;持续更新&#xff0c;大家持续关注&#xff0c;更新见文末名片 &#xff09; 摘要 在本文中&#xff0c;建立了基于整数规划、动态规划、马尔科夫决策过程、不确定性建模、多目标优化、相关性分析、蒙特卡洛…

Packet Tracer - 单区域OSPFv2的配置方法以及思路

Packet Tracer - 单区域OSPFv2的配置思路 1、思路前夕查看 做这个的时候大家了解一下通配符&#xff0c;不然不理解这个东西为什么子网掩码为什么会取反 这里给大家简单演示一下 2、使用进程 ID 10 在所有路由器上激活 OSPF。 在 Headquarters 网络中的路由器上使用 network…

FxFactory 8 for Mac 视觉特效插件包安装

Mac分享吧 文章目录 介绍页面效果一、下载软件二、开始安装1、Install安装2、显示软件页面&#xff0c;表示安装成功3、补丁安装 三、注意事项1、若已安装过其他版本&#xff0c;需要使用软件自带的卸载功能进行软件卸载&#xff0c;再安装此版本 安装完成&#xff01;&#x…

pod install 报错处理

由于墙的原因&#xff0c;pod install 、 pod update经常报错 有效的解决方案(推荐)&#xff1a; 以SnapKit为例 找不报错的同事要以下两个文件&#xff08;指定的版本&#xff09; 1. /Users/xxx/Library/Caches/CocoaPods/Pods/Release/SnapKit 2. /Users/xxx/Library/Cac…

后缀表达式转中缀表达式

假定有后缀表达式1 2 3 4 * 5 – &#xff0c;请将它转化为前缀表达式。 利用表达式树&#xff1a; 1.从左到右扫面后缀表达式&#xff0c;一次一个符号读入表达式。2.如果符号是操作数&#xff0c;那么就建立一个单节点树并将它推入栈中。如果符号是操作符&#xff0c;那么…

针对不同区域的摄像头,完成不同的算法配置的智慧快消开源了

智慧快消视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒&#xff0c;省去繁琐重复的适配流程&#xff0c;实现芯片、算法、应用的全流程组合&#xff0c;从而大大减少企业级应用约95%的开发成本。 基于多年的深度…

JAVAEE初阶第六节——网络编程套接字

系列文章目录 JAVAEE初阶第六节——网络编程套接字 文章目录 系列文章目录JAVAEE初阶第六节——网络编程套接字 一. 网络编程基础1. 为什么需要网络编程2. 什么是网络编程3.网络编程中的基本概念 3.1 发送端和接收端 3.2 请求和响应 3.3 客户端和服务端 4. 常见的客户端服务…

求二叉树的深度——(力扣c语言)

题目如下&#xff1a; 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3示例 2&#xff1a; 输入&#xff1a…

[网络编程]TCP和UDP的比较 及 通过java用UDP实现网络编程

文章目录 一. 网络编程套接字TCP和UDP的特点有连接 vs 无连接可靠传输 vs 不可靠传输面向字节流 vs 面向数据报全双工 vs 半双工 二. java用UDP实现网络编程代码实现:运行代码:启动多个客户端别人能否使用?实现翻译功能 一. 网络编程套接字 网络编程套接字, 就是指操作系统提…

linux 部署Ollama本地大模型

简介 llama 是一个大模型的管理框架&#xff0c;其作用类似于 Docker&#xff1a;如果将每一个标准化的大模型视为“镜像”&#xff0c;那么 Ollama 就能够通过一行命令快速拉取并运行这些大模型。然而&#xff0c;Ollama 本身是基于命令行的服务&#xff0c;所以为了方便我们…