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

 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;//用户idprivate 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 {@Autowiredprivate AddressBookService addressBookService;/*** 新增地址** @param addressBook* @return*/@ApiOperation("新增地址")@PostMappingpublic Result save(@RequestBody AddressBook addressBook) {// 这里要进行处理:// 1.设置 userId,因为传过来的addressBook无法拿到用户 idaddressBook.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 {@Autowiredprivate AddressBookMapper addressBookMapper;/*** 新增地址*/@Overridepublic void save(AddressBook addressBook) {addressBookMapper.save(addressBook);}/*** 查询地址** @return*/@Overridepublic List<AddressBook> list() {List<AddressBook> list = addressBookMapper.list();return list;}/*** 查询默认地址** @return*/@Overridepublic AddressBook getDefault() {return addressBookMapper.getDefault();}/*** 修改地址** @param addressBook*/@Overridepublic void update(AddressBook addressBook) {addressBookMapper.update(addressBook);}/*** 根据id删除地址** @param id*/@Overridepublic void deleteById(Long id) {addressBookMapper.deleteById(id);}/*** 根据id查询地址** @param id* @return*/@Overridepublic AddressBook getById(Long id) {AddressBook addressBook = addressBookMapper.getById(id);return addressBook;}/*** 设置默认地址** @param addressBook*/@Overridepublic 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 {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate OrderDetailMapper orderDetailMapper;@Autowiredprivate AddressBookMapper addressBookMapper;@Autowiredprivate 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.mzph.cn/pingmian/53230.shtml

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

相关文章

001集——CAD—C#二次开发入门——开发环境基本设置

CAD C#二次开发首先需要搭建一个舒服的开发环境&#xff0c;软件安装后&#xff0c;需要修改相关设置。本文为保姆级入门搭建开发环境教程&#xff0c;默认已成功安装vs和cad 。 第一步&#xff1a;创建类库 第二步&#xff1a;进行相关设置&#xff0c;如图&#xff1a; 下一…

JavaEE:多线程进阶(CAS)

文章目录 CAS什么是 CASCAS 伪代码 CAS有哪些应用CAS的ABA问题什么是ABA问题ABA问题带来的BUG解决方案 CAS 什么是 CAS CAS: 全称Compare and swap&#xff0c;字面意思:”比较并交换“&#xff0c;一个 CAS 涉及到以下操作: 我们假设内存中的原数据V&#xff0c;旧的预期值A…

刷题记录(2)

1. HWOD机试 - 模拟消息队列(100) package com.yue.test;import org.junit.Test;import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List;/*** Author: 夜雨* Date: 2021-12-08-10:31* Description:* Version 1.0*/ public…

【Android】ViewPager基本用法总结

文章目录 一、添加ViewPager控件二、构建适配器类三、在 MainActivity 中设置适配器示例一&#xff1a;图片切换适配器MainActivity 示例二&#xff1a;Fragment切换适配器FragmentMainActivity ViewPager 是 Android 中一个用于在同一屏幕上滑动不同页面&#xff08;通常是左右…

OBS怎么设置录制配置?3个电脑录屏小技巧妥妥教会你

OBS Studio是一款广受好评的开源录屏和直播软件&#xff0c;它以其强大的功能和用户友好的操作界面而闻名。对于初次接触OBS的用户来说&#xff0c;可能会对软件的众多按钮感到困惑。本文将为你提供一份简洁明了的OBS录屏指南&#xff0c;帮助你快速上手。 演示机型&#xff1a…

Hive数据库与表操作全指南

目录 Hive数据库操作详解 创建数据库 1&#xff09;语法 2&#xff09;案例 查询数据库 1&#xff09;展示所有数据库 &#xff08;1&#xff09;语法 &#xff08;2&#xff09;案例 2&#xff09;查看数据库信息 &#xff08;1&#xff09;语法 &#xff08;2&#…

Simulink:循环计数器 Counter Free-Running

原文&#xff1a;Matlab生成stm32代码_matlab stm32-CSDN博客 使用“Counter Free-Running”模块进行计数&#xff0c;参数配置如下 此配置的意思为每0.5秒计数一次&#xff0c;计数的最大值为2^Nbits – 1&#xff0c;其中Nbits为所填的2&#xff0c;所以这里最大值为3。 示波…

【多线程】死锁

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 文章目录 1. 死锁的三种情况1.1 一个线程一把锁&#xff08;同一个线程给同一个对象加两次锁的情况&#xff09;1.2 两…

彻底解决 node/npm, Electron下载失败相关问题, 从底层源码详解node electron 加速配置

最近玩了一下electron项目, 总是会遇到electron的下载失败问题, 于是看了一下node源码, 做一个记录. node/npm 加速配置 这个配置通过设置node配置里面的registry 这个配置项来完成加速. 配置方法 npm config set registry https://registry.npmmirror.com上面的命令就是将当…

【全网最全】2024年数学建模国赛C题超详细保奖思路+可视化图表+成品论文+matlab/python代码等(后续会更新

您的点赞收藏是我继续更新的最大动力&#xff01; 一定要点击如下的卡片&#xff0c;那是获取资料的入口&#xff01; 基于优化模型的农作物的种植策略 摘要 随着农业生产向集约化和智能化方向发展&#xff0c;优化种植策略以最大化经济收益成为当前农业研究中的重要问题。本…

车载测试协议:ISO-14229、ISO-15765、ISO-11898、ISO-26262【车企项目实操学习】②

FOTA模块中OTA的知识点&#xff1a;1.测试过程中发现哪几类问题&#xff1f; 可能就是一个单键的ecu&#xff0c;比如升了一个门的ecu&#xff0c;他的升了之后就关不上&#xff0c;还有就是升级组合ecu的时候&#xff0c;c屏上不显示进度条。 2.在做ota测试的过程中&#xff…

已入职华为!!关于我成功拿下华为大模型算法岗经验总结

方向:大模型算法工程师 整个面试持续了1小时10分钟&#xff0c;能够看出面试官是典型搞技术的&#xff0c;问的很专业又很细&#xff0c;全程感觉压力好大&#xff0c;面完后感觉丝丝凉意&#xff0c;不过幸好还是成功拿下了Offer 一面: 自我介绍 简历项目深度交流 1.项目的背…

Java笔试面试题AI答之JDBC(2)

文章目录 7. 列出Java应该遵循的JDBC最佳实践&#xff1f;8. Statement与PreparedStatement的区别,什么是SQL注入&#xff0c;如何防止SQL注入Statement与PreparedStatement的区别什么是SQL注入如何防止SQL注入 9. JDBC如何连接数据库&#xff1f;1. 加载JDBC驱动程序2. 建立数…

[网络原理]关于网络的基本概念 及 协议

文章目录 一. 关于网络的概念介绍1. 局域⽹LAN2. ⼴域⽹WAN3. 主机4. 路由器5. 交换机IP地址端口号 二. 协议协议分层TCP/IP五层模型(或四层)OSI七层模型封装分用 一. 关于网络的概念介绍 1. 局域⽹LAN 局域⽹&#xff0c;即 Local Area Network&#xff0c;简称LAN。 Local …

二叉树的层次遍历(10道)

&#xff08;写给未来遗忘的自己&#xff09; 102.二叉数的层序遍历&#xff08;从上到下&#xff09; 题目&#xff1a; 代码&#xff1a; class Solution { public: vector<vector<int>> levelOrder(TreeNode* root) { vector<vector<int>> r…

JVM系列(十) -垃圾收集器介绍

一、摘要 在之前的几篇文章中,我们介绍了 JVM 内部布局、对象的创建过程、运行期的相关优化手段以及垃圾对象的回收算法等相关知识。 今天通过这篇文章,结合之前的知识,我们一起来了解一下 JVM 中的垃圾收集器。 二、垃圾收集器 如果说收集算法是内存回收的方法论,那么…

稀土废水回收硫酸铵树脂技术

稀土废水回收硫酸铵的过程主要涉及到化学沉淀法、离子交换法和蒸发结晶法等技术。这些方法可以有效地从稀土废水中回收硫酸铵&#xff0c;同时降低废水中的氨氮含量&#xff0c;实现资源的循环利用。以下是具体的技术介绍&#xff1a; 稀土废水回收硫酸铵的技术 ● 化学沉淀…

【MATLAB】矩阵的合并

矩阵的合并是指将两个或者多个矩阵合并到一起构成一个新的矩阵。矩阵标识符方括号 [ ]&#xff0c;不仅可以用来创建新的矩阵&#xff0c;还可以用来将若干个矩阵合并到一起。表达式 C [A B] 将矩阵A和B在水平方向上合并到一起&#xff0c;而表达式C[A;B]则将矩阵A和B在竖直方…

java项目docker部署时进行热部署

本文需要pontwiner进行配合操作 1.上传文件到对应服务器&#xff0c;可以通过xftp等文件上传工具进行文件上传 2.获取docker imagId XX为项目部署名称 例如&#xff1a;test-server docker ps -a |grep XX 3.复制文件到docker容器的/tmp目录下 docker cp XXXX.class im…

WEB服务与虚拟主机/IIS中间件部署

WWW&#xff08;庞大的信息系统&#xff09;是基于客户机/服务器⽅式的信息发现技术和超⽂本技术的综合。网页浏览器//网页服务器 WWW的构建基于三项核⼼技术&#xff1a; HTTP&#xff1a;超文本传输协议&#xff0c;⽤于在Web服务器和客户端之间传输数据。HTML&#xff1a;⽤…