Java Web项目—餐饮管理系统Day09-用户端开发(二)

文章目录

      • 1. 地址簿管理
        • 1-1. 新增地址
        • 1-2 查询当前用户的地址簿
        • 1-3. 更新默认地址
        • 1-4. 获取默认地址
        • 1-5. 修改地址
      • 2. 订单管理
        • 2-1. 表结构
        • 2-2 提交订单

本章节主要完成地址簿的管理以及订单管理, 同时完善系统的部分细节, Reggie TakeAway 系统篇章基础篇告一段落.

1. 地址簿管理

地址簿记录了每个用户的地址信息, 每个用户可以设置多个地址, 但默认地址有且仅有一个.
实体类如下:

@Data
public class AddressBook implements Serializable {private static final long serialVersionUID = 1L;private Long id;private Long userId;            //用户idprivate String consignee;       //收货人private String phone;           //手机号private String sex;             //性别 0 女 1 男private String provinceCode;    //省级区划编号private String provinceName;    //省级名称private String cityCode;        //市级区划编号private String cityName;        //市级名称private String districtCode;    //区级区划编号private String districtName;    //区级名称private String detail;          //详细地址private String label;           //标签private Integer isDefault;      //是否默认 0 否 1是@TableField(fill = FieldFill.INSERT)private LocalDateTime createTime;@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime updateTime;@TableField(fill = FieldFill.INSERT)private Long createUser;@TableField(fill = FieldFill.INSERT_UPDATE)private Long updateUser;private Integer isDeleted;      //是否删除
}

为他建立对应的 mapper 和 service 层.

1-1. 新增地址

POST

@RestController
@RequestMapping("addressBook")
@Slf4j
public class AddressBookController {@Autowiredprivate AddressBookService addressBookService;@PostMappingpublic R<String> add(@RequestBody AddressBook address){log.info("新增地址: {}", address);Long userId = BaseContext.getId();address.setUserId(userId);address.setIsDefault(0);addressBookService.save(address);return R.success("地址新增成功");}
}
1-2 查询当前用户的地址簿
@GetMapping("list")
public R<List<AddressBook>> list(){Long userId = BaseContext.getId();log.info("查询当前用户所有的地址信息: {}", userId);List<AddressBook> books = addressBookService.listByUser(userId);return R.success(books);
}// AddressBookServiceImpl
@Override
public List<AddressBook> listByUser(Long userId) {LambdaQueryWrapper<AddressBook> wrapper = new LambdaQueryWrapper<>();wrapper.eq(AddressBook::getUserId, userId);wrapper.orderByDesc(AddressBook::getUpdateTime);return this.list(wrapper);
}
1-3. 更新默认地址

设置默认地址, 注意需要先把原默认地址取消, 这里有一个 trick, 就是如果一个实体类的字段为空, 那么在更新时该字段不会被写入到数据库中.

@PutMapping("default")
public R<String> defAddr(@RequestBody AddressBook newBook){log.info("设置默认地址");// 假如已经存在一个默认地址, 则先把它设为0LambdaQueryWrapper<AddressBook> bookWrapper = new LambdaQueryWrapper<>();bookWrapper.eq(AddressBook::getIsDefault, 1);AddressBook bookNoDefault = new AddressBook();bookNoDefault.setIsDefault(0);addressBookService.update(bookNoDefault, bookWrapper);newBook.setIsDefault(1);addressBookService.updateById(newBook);return R.success("设置默认地址成功");
}
1-4. 获取默认地址
@GetMapping("default")
public R<AddressBook> getDefAddr(){log.info("获取默认地址");LambdaQueryWrapper<AddressBook> bookWrapper = new LambdaQueryWrapper<>();bookWrapper.eq(AddressBook::getIsDefault, 1);bookWrapper.eq(AddressBook::getUserId, BaseContext.getId());AddressBook addressBook = addressBookService.getOne(bookWrapper);if (addressBook == null)return null;elsereturn R.success(addressBook);
}
1-5. 修改地址

地址信息回显:

@GetMapping("{addrId}")
public R<AddressBook> getById(@PathVariable Long addrId){log.info("获取地址: {}", addrId);return R.success(addressBookService.getById(addrId));
}

更新表格:

@PutMapping
public R<String> update(@RequestBody AddressBook book){log.info("修改地址: {}", book);addressBookService.updateById(book);return R.success("修改成功");
}

2. 订单管理

2-1. 表结构

Orders 和 OrderDetail
第一个存放订单的基本信息, 包括 订单号 订单所属用户 订单配送地址 等等

@Data
public class Orders implements Serializable {private static final long serialVersionUID = 1L;private Long id;private String number;                  // 订单号private Integer status;                 // 订单状态 1待付款,2待派送,3已派送,4已完成,5已取消private Long userId;                    // 下单用户idprivate Long addressBookId;             // 地址idprivate LocalDateTime orderTime;        // 下单时间private LocalDateTime checkoutTime;     // 结账时间private Integer payMethod;              // 支付方式 1 微信, 2 支付宝private BigDecimal amount;              // 实收金额private String remark;                  // 备注private String userName;                // 用户名private String phone;                   // 手机号private String address;                 // 地址private String consignee;               // 收货人
}

第二个是订单明细表, 它以订单号为关联键值, 存放该订单中包含的所有菜品或套餐的信息

@Data
public class OrderDetail implements Serializable {private static final long serialVersionUID = 1L;private Long id;private String name;    //名称private Long orderId;   //订单idprivate Long dishId;    //菜品idprivate Long setmealId; //套餐idprivate String dishFlavor;      //口味private Integer number;         //数量private BigDecimal amount;      //金额private String image;           //图片
}

为他们创建 service 和 mapper.

2-2 提交订单

如下为请求信息:

请求 URL:
http://localhost:8080/order/submit
请求方法:
POST
请求体:
{"remark": "","payMethod": 1,"addressBookId": "1746045643976040449"
}

订单生成的步骤包括:

  1. 获取当前登录用户
  2. 获取用户地址信息
  3. 获取购物车菜品信息
  4. 创建订单实体
  5. 保存订单明细表到数据库
  6. 清空购物车
  7. 填充订单实体的必要字段, 保存订单信息到数据库

如下为 controller 层的处理方法:

@RestController
@RequestMapping("order")
@Slf4j
public class OrderController {@Autowiredprivate OrdersService ordersService;@PostMapping("submit")public R<String> submit(@RequestBody Orders orders) {log.info("用户下单: {}", orders);ordersService.submit(orders);return R.success("下单成功");}
}

OrdersServiceImpl.submit 方法如下:

@Override
public void submit(Orders orders) {Long userId = BaseContext.getId();User user = userService.getById(userId);Long addressBookId = orders.getAddressBookId();AddressBook addressBook = addressBookService.getById(addressBookId);if (addressBook == null)throw new BusinessException("地址信息有误, 无法下单");Long orderId = IdWorker.getId();orders.setId(orderId);int amount = orderDetailService.saveCurrentShoppingCart(orderId);orders.setOrderTime(LocalDateTime.now());orders.setCheckoutTime(LocalDateTime.now());orders.setStatus(2);orders.setAmount(new BigDecimal(amount));orders.setUserId(userId);orders.setNumber(String.valueOf(orderId));orders.setUserName(user.getName());orders.setConsignee(addressBook.getConsignee());orders.setPhone(addressBook.getPhone());orders.setAddress((addressBook.getProvinceName() == null ? "": addressBook.getProvinceName()) +(addressBook.getCityName() == null ? "": addressBook.getCityName()) +(addressBook.getDistrictName() == null ? "": addressBook.getDistrictName()) +(addressBook.getDetail() == null ? "": addressBook.getDetail()));this.save(orders);
}

保存订单明细表到数据库的代码如下:

@Transactional
@Override
public Integer saveCurrentShoppingCart(Long orderId) {// 将当前用户购物车内的套餐或菜品全部存入订单明细表中, 并与订单号 orderId 关联// 返回购物车内商品总金额 amount, 同时清除购物车.AtomicInteger amount = new AtomicInteger(0);Long userId = BaseContext.getId();LambdaQueryWrapper<ShoppingCart> wrapper = new LambdaQueryWrapper<>();wrapper.eq(ShoppingCart::getUserId, userId);List<ShoppingCart> shoppingCarts = shoppingCartService.list(wrapper);if (shoppingCarts==null || shoppingCarts.size()==0)throw new BusinessException("购物车为空, 无法下单");for (ShoppingCart cart: shoppingCarts){OrderDetail detail = new OrderDetail();BeanUtils.copyProperties(cart, detail);detail.setOrderId(orderId);amount.addAndGet(detail.getAmount().multiply(new BigDecimal(detail.getNumber())).intValue());this.save(detail);}shoppingCartService.remove(wrapper);return amount.get();
}

实际上还有一些请求待处理, 例如点击套餐图片展示套餐明细、点击历史订单展示订单列表及其明细等等, 由于请求路径和方法以及返回数据格式等未知, 且未新增技术点, 故暂时不进行讨论. 至此, Reggie 外卖项目的基本内容就完结了。

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

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

相关文章

重要JVM参数和监控指令、工具

一、重要JVM参数 堆内存相关 1.显式指定堆内存–Xms和-Xmx -Xms<heap size>[unit] -Xmx<heap size>[unit] //如果我们要为 JVM 分配最小 2 GB 和最大 5 GB 的堆内存大小 -Xms2G -Xmx5G2.显式新生代内存(Young Generation) -XX:NewSize<young size>[unit]…

SpringBoot异常:类文件具有错误的版本 61.0, 应为 52.0的解决办法

问题&#xff1a; java: 无法访问org.mybatis.spring.annotation.MapperScan 错误的类文件: /D:/Program Files/apache-maven-3.6.0/repository/org/mybatis/mybatis-spring/3.0.3/mybatis-spring-3.0.3.jar!/org/mybatis/spring/annotation/MapperScan.class 类文件具有错误的…

实体门店加盟全解析:如何选择加盟项目与避免风险

对于想要开实体店或创业的人来说&#xff0c;拥有一个全面的运营方案是成功的关键。作为一名开鲜奶吧5年的创业者&#xff0c;我将为大家详细分享从选址到日常管理的实体店运营要点&#xff0c;帮助创业者少走弯路。 一、选择加盟项目 1.行业前景&#xff1a;选择一个有发展前…

Flutter第五弹:Flutter布局

目标&#xff1a; 1&#xff09;Flutter常用的布局容器小组件有哪些&#xff1f; 2&#xff09;Flutter列表组件的小例子。 一、Flutter常用的容器组件 1.1 Container组件 Container 部件有许多可用的属性&#xff0c;以下是一些常用的属性&#xff1a; 属性说明alignmen…

【华为OD机试】小明找位置【C卷|100分】

【华为OD机试】-真题 !!点这里!! 【华为OD机试】真题考点分类 !!点这里 !! 题目描述 小朋友出操,按学号从小到大排成一列;小明来迟了,请你给小明出个主意,让他尽快找到他应该排的位置。 算法复杂度要求不高于 nLog(n);学号为整数类型,队列规模<=10000; 输入描述 1…

java15~17 密封类

密封类是java15第一次预览&#xff0c;java17正式确定。Java15的密封类是一种确定了子类的类。这个改变是巨大的&#xff0c;以往的Java版本根本无法确定到底有哪些子类。而在java15中&#xff0c;如果定义了一个类为密封类就可以确定有哪些直接子类了。如下面的例子&#xff1…

Vue2(五):收集表单数据、过滤器、自定义指令、Vue的生命周期

一、收集表单数据 爱好&#xff1a;学习<input type"checkbox" value"study" v-model"hobby">打游戏<input type"checkbox" value"games" v-model"hobby">吃饭<input type"checkbox" v…

独立维基和验收测试框架 Fitnesse 入门介绍

拓展阅读 junit5 系列教程 基于 junit5 实现 junitperf 源码分析 Auto generate mock data for java test.(便于 Java 测试自动生成对象信息) Junit performance rely on junit5 and jdk8.(java 性能测试框架。压测测试报告生成。) Fitnesse 完全集成的独立维基和验收测试…

大数据开发--01.初步认识了解

一.环境准备 1.使用虚拟机构建至少三台linux服务器 2.使用公有云来部署服务器 二.大数据相关概念 大数据是指处理和分析大规模数据集的一系列技术、工具和方法。这些数据集通常涉及海量的数据&#xff0c;包括结构化数据&#xff08;如关系型数据库中的表格&#xff09;以及…

美联社报道波场与亚马逊云计算重磅合作 称符合其去中心化使命

近日,波场TRON宣布已集成亚马逊云计算服务(AWS),引发美联社、金融时报、费加罗报等多家海外主流媒体高度关注。报道表示,此次集成旨在利用AWS 强大的云计算资源,降低用户和开发者参与波场网络的准入门槛,打造更加去中心化、更强大的区块链生态系统。 报道内容显示,通过此次合作…

基于spring boot的民宿预约管理系统的设计与实现

目录 摘要 I Abstract II 一、绪论 1 &#xff08;一&#xff09;研究背景 1 &#xff08;二&#xff09;社会调查 1 &#xff08;三&#xff09;研究意义 2 &#xff08;四&#xff09;研究内容 2 二、关键技术介绍 3 &#xff08;一&#xff09;Spring Boot框架 3 &#xff…

GESP2024年3月C++语言三级答案(均为自己的想法,C++没学太多,有不对的地方欢迎指正)

选择题&#xff08;每题2分&#xff0c;共30分&#xff09; 第 1 题 整数-5的16位补码表示是(D)。 A. 1005 B. 1006 C. FFFA D. FFFB 解析&#xff1a;0是FFFF&#xff0c;用0-5&#xff08;即FFFF-5&#xff09;得到是FFFB。 第 2 题 如果16位短整数-2的二进制是“FFFE”&…

蓝桥杯-带分数

法一 /* 再每一个a里去找c,他们共用一个st数组,可以解决重复出现数字 通过ac确定b,b不能出现<0 b出现的数不能和ac重复*/import java.util.Scanner;public class Main {static int n,res;static boolean[] st new boolean[15];static boolean[] backup new boolean[15];…

YOLOv9改进策略:注意力机制 | 用于微小目标检测的上下文增强和特征细化网络ContextAggregation,助力小目标检测,暴力涨点

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文改进内容&#xff1a;用于微小目标检测的上下文增强和特征细化网络ContextAggregation&#xff0c;助力小目标检测 yolov9-c-ContextAggregation summary: 971 layers, 51002153 parameters, 51002121 gradients, 238.9 GFLOPs 改…

springboot277流浪动物管理系统

流浪动物管理系统设计与实现 摘 要 在如今社会上&#xff0c;关于信息上面的处理&#xff0c;没有任何一个企业或者个人会忽视&#xff0c;如何让信息急速传递&#xff0c;并且归档储存查询&#xff0c;采用之前的纸张记录模式已经不符合当前使用要求了。所以&#xff0c;对流…

PSCA系统控制集成之复位层次结构

PPU 提供以下对复位控制的支持。 • 复位信号Reset signals&#xff1a;PPU 提供冷复位和热复位输出信号。PPU 还为实现部分保留的电源域管理提供了额外的热复位输出信号。 • 电源模式控制Power mode control&#xff1a;PPU 硬件适当地管理每个支持的电源模式转换的复位信号…

2024蓝桥杯每日一题(DFS)

备战2024年蓝桥杯 -- 每日一题 Python大学A组 试题一&#xff1a;奶牛选美 试题二&#xff1a;树的重心 试题三&#xff1a;大臣的差旅费 试题四&#xff1a;扫雷 试题一&#xff1a;奶牛选美 【题目描述】 听说最近两斑点的奶牛最受欢迎&#xff0c;…

面试经典-34-验证回文串

题目 如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后&#xff0c;短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。 字母和数字都属于字母数字字符。 给你一个字符串 s&#xff0c;如果它是 回文串 &#xff0c;返回 true &#xff1b;否则…

航迹数据优化方案

文章目录 引言I 轨迹数据模型II 轨迹信息索引III 数据同步方案3.1 多服务器多表同步3.2 增量数据同步3.3 执行IV 动态表的同步4.1 利用变量进行动态日期表名拼接其他方案引言 重点: ES索引的设计:航迹索引和船的最新位置信息索引梳理出存储航迹的主服务器,测试多服务器多动…

uniapp 兼容pc与手机的样式方法

在h5的开发中&#xff0c;做视窗的样式兼容和适配&#xff0c;大家肯定都知道移动端使用自适应单位rpx,pc端可以使用媒体查询的方法来适配&#xff0c;但是在uniapp 项目开发中&#xff0c;有时在移动端展示的样式会被在桌面端打开&#xff0c;渲染在浏览器&#xff0c;这时候你…