瑞吉外卖-第六天
课程内容
- 用户地址簿功能
- 菜品展示
- 购物车
- 下单
1. 用户地址簿功能
1.1 需求分析
地址簿,指的是移动端消费者用户的地址信息,用户登录成功后可以维护自己的地址信息。同一个用户可以有多个地址信息,但是只能有一个默认地址。
对于地址簿管理,我们需要实现以下几个功能:
- 新增地址
- 地址列表查询
- 设置默认地址
- 编辑地址
- 删除地址
1.2 数据模型
用户的地址信息会存储在address_book表,即地址簿表中。具体表结构如下:
这里面有一个字段is_default,实际上我们在设置默认地址时,只需要更新这个字段就可以了。
1.3 导入功能代码
对于这一类的单表的增删改查,我们已经写过很多了,基本的开发思路都是一样的,那么本小节的用户地址簿管理的增删改查功能,我们就不再一一实现了,基本的代码我们都已经提供了,直接导入进来,做一个测试即可。
对于下面的地址管理的代码,我们可以直接从资料拷贝,也可以直接从下面的讲义中复制。
1). 实体类 AddressBook(直接从课程资料中导入即可)
所属包: com.itheima.reggie.entity
package com.itheima.reggie.entity;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 地址簿
*/
@Data
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;
//创建时间
private LocalDateTime createTime;
//更新时间
private LocalDateTime updateTime;
//创建人
private Long createUser;
//修改人
private Long updateUser;
//是否删除
private Integer isDeleted;
}
2). Mapper接口 AddressBookMapper(直接从课程资料中导入即可)
所属包: com.itheima.reggie.mapper
package com.itheima.reggie.mapper;
import com.itheima.reggie.entity.AddressBook;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
@Mapper
public interface AddressBookMapper {
//添加地址
@Insert("insert into address_book(user_id,consignee,phone,sex,detail,label,create_time,update_time," +
"create_user,update_user) " +
"values(#{userId},#{consignee},#{phone},#{sex},#{detail},#{label},#{createTime},#{updateTime},#{createUser}," +
"#{updateUser})")
void save(AddressBook addressBook);
//查询地址列表
@Select("select * from address_book where user_id=#{userId} order by update_time desc")
List<AddressBook> queryAddressList(Long userId);
@Update("update address_book set is_default=0 where user_id=#{userId}")
void removeDefaultAddress(Long userId);
@Update("update address_book set is_default=1 where id=#{id}")
void updateDefaultAddress(AddressBook addressBook);
@Select("select * from address_book where id=#{id}")
AddressBook getById(Long id);
@Select("select * from address_book where user_id = #{userId} and is_default = 1")
AddressBook getDefaultAddress(Long userId);
}
3). 业务层接口 AddressBookService(直接从课程资料中导入即可)
所属包: com.itheima.reggie.service
package com.itheima.reggie.service;
import com.itheima.reggie.entity.AddressBook;
import java.util.List;
public interface AddressBookService {
//保存地址
void save(AddressBook addressBook);
//查询地址对象
List<AddressBook> queryAddressList(Long currentId);
//更新默认地址
void updateDefaultAddress(AddressBook addressBook);
//根据id查询
AddressBook getById(Long id);
//得到默认地址
AddressBook getDefaultAddress(Long currentId);
}
4). 业务层实现类 AddressBookServiceImpl(直接从课程资料中导入即可)
所属包: com.itheima.reggie.service.impl
package com.itheima.reggie.service.impl;
import com.itheima.reggie.entity.AddressBook;
import com.itheima.reggie.mapper.AddressBookMapper;
import com.itheima.reggie.service.AddressBookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class AddressBookServiceImpl implements AddressBookService{
@Autowired
private AddressBookMapper addressBookMapper;
@Override
public void save(AddressBook addressBook) {
addressBookMapper.save(addressBook);
}
@Override
public List<AddressBook> queryAddressList(Long userId) {
List<AddressBook> addressBookList = addressBookMapper.queryAddressList(userId);
return addressBookList;
}
//更新默认地址
@Override
@Transactional
public void updateDefaultAddress(AddressBook addressBook) {
//1. 把该用户地址全部修改为非默认
addressBookMapper.removeDefaultAddress(addressBook.getUserId());
//2 重新设置当前地址为默认地址
addressBookMapper.updateDefaultAddress(addressBook);
}
@Override
public AddressBook getById(Long id) {
return addressBookMapper.getById(id);
}
@Override
public AddressBook getDefaultAddress(Long currentId) {
return addressBookMapper.getDefaultAddress(currentId);
}
}
5). 控制层 AddressBookController(直接从课程资料中导入即可)
所属包: com.itheima.reggie.controller
controller主要开发的功能:
A. 新增地址逻辑说明:
- 需要记录当前是哪个用户的地址(关联当前登录用户)
B. 设置默认地址
-
每个用户可以有很多地址,但是默认地址只能有一个 ;
-
先将该用户所有地址的is_default更新为0 , 然后将当前的设置的默认地址的is_default设置为1
C. 根据ID查询地址
D. 查询默认地址
- 根据当前登录用户ID 以及 is_default进行查询,查询当前登录用户is_default为1的地址信息
E. 查询指定用户的全部地址
- 根据当前登录用户ID,查询所有的地址列表
代码实现如下:
package com.itheima.reggie.controller;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.AddressBook;
import com.itheima.reggie.service.AddressBookService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.List;
/**
* 地址簿管理
*/
@Slf4j
@RestController
@RequestMapping("/addressBook")
public class AddressBookController {
@Autowired
private AddressBookService addressBookService;
/**
* 新增
*/
@PostMapping
public R<AddressBook> save(@RequestBody AddressBook addressBook, HttpSession session) {
Long userId = (Long) session.getAttribute("user");
addressBook.setUserId(userId);
addressBook.setCreateUser(userId);
addressBook.setUpdateUser(userId);
addressBook.setCreateTime(LocalDateTime.now());
addressBook.setUpdateTime(LocalDateTime.now());
addressBookService.save(addressBook);
return R.success(addressBook);
}
/**
* 根据id查询地址
*/
@GetMapping("/{id}")
public R get(@PathVariable Long id) {
AddressBook addressBook = addressBookService.getById(id);
if (addressBook != null) {
return R.success(addressBook);
} else {
return R.error("没有找到该对象");
}
}
/**
* 查询默认地址
*/
@GetMapping("default")
public R<AddressBook> getDefault(HttpSession session) {
Long userId = (Long) session.getAttribute("user");
AddressBook addressBook = addressBookService.getDefaultAddress(userId);
if (null == addressBook) {
return R.error("没有找到该对象");
} else {
return R.success(addressBook);
}
}
/**
* 设置默认地址
*/
@PutMapping("default")
public R<AddressBook> setDefault(@RequestBody AddressBook addressBook,HttpSession session) {
Long userId = (Long) session.getAttribute("user");
addressBook.setUserId(userId);
addressBookService.updateDefaultAddress(addressBook);
return R.success(addressBook);
}
/**
* 查询指定用户的全部地址
*/
@GetMapping("/list")
public R<List<AddressBook>> list(HttpSession session) {
Long userId = (Long) session.getAttribute("user");
List<AddressBook> addressList = addressBookService.queryAddressList(userId);
//SQL:select * from address_book where user_id = ? order by update_time desc
return R.success(addressList);
}
}
1.4 功能测试
代码导入进来,并且去阅读了一下地址管理各个功能的逻辑实现,接下来,我们就可以启动项目,进行一个测试。测试过程中,通过debug断点调试观察服务端程序的执行过程,在浏览器中使用调试工具查看页面和服务端的交互过程和请求响应数据。
1). 新增
填写表单数据,点击保存地址,查看网络请求。
测试完毕之后,检查数据库中的数据,是否正常插入。
2). 列表查询
当新增地址完成后,页面会再次发送一个请求,来查询该用户的所有地址列表,在界面进行展示。
3). 设置默认
在地址列表页面中,勾选 “设为默认地址” ,此时会发送PUT请求,来设置默认地址。
测试完毕后,我们再次查看数据库表中的数据:
2. 菜品展示
2.1 需求分析
用户登录成功后跳转到系统首页,在首页需要根据分类来展示菜品和套餐。如果菜品设置了口味信息,需要展示按钮,否则显示按钮。
2.2 前端页面分析
在开发代码之前,需要梳理一下前端页面和服务端的交互过程:
1). 页面(front/index.html)发送ajax请求,获取分类数据(菜品分类和套餐分类)