慕慕生鲜代码的详细讲解
一、用户模块
1.注册功能
controller层:
判断用户名、密码是否为空,密码不能少于八位。
server层:
查询数据库中用户是否存在,不允许重名。密码使用MD5加密工具加盐值保存到数据库
2.登录功能
controller层:
判断用户名、密码是否为空,
用session进行登录状态保存用户信息session.setAttribute(Constant.IMOOC_MALL_USER,user);
保存用户信息时不保存密码。
server层:
调用数据库查询匹配用户名和密码。
3.更新个性签名
controller层:
判断用户是否登录
server层:
调用userMapper层的更新方法
4.登出功能
controller层:session.removeAttribute(Constant.IMOOC_MALL_USER);
5.管理员登录功能
controller层:
判断用户名、密码是否为空,调用登录功能
校验是否五味管理员userService.checkAdminRole(user)
server层:
调用userMapper层的更新方法
二、商品目录模块
1.后台添加目录
controller层:
利用注解进行参数校验
public ApiRestResponse addCategory(HttpSession session, @Valid @RequestBody AddCategoryReq addCategoryReq)
统一异常处理,判断用户是否登录,校验是否为管理员
User currentUser = (User) session.getAttribute(Constant.IMOOC_MALL_USER);
if (currentUser == null) {
return ApiRestResponse.error(ImoocMallExceptionEnum.NEED_LOGIN);
}
//校验是否是管理员
boolean adminRole = userService.checkAdminRole(currentUser);
server层:
BeanUtils.copyProperties(addCategoryReq, category);//一次性拷贝四个字段
Category categoryOld = categoryMapper.selectByName(addCategoryReq.getName());
if (categoryOld != null) {//如果新增目录名不为空抛出异常
throw new ImoocMallException(ImoocMallExceptionEnum.NAME_EXISTED);
}
int count = categoryMapper.insertSelective(category);
if (count == 0) {
throw new ImoocMallException(ImoocMallExceptionEnum.CREATE_FAILED);
}
2.后台更新目录
controller层:
利用注解进行参数校验
public ApiRestResponse updateCategory(@Valid @RequestBody UpdateCategoryReq updateCategoryReq, HttpSession session)
统一异常处理,判断用户是否登录,校验是否为管理员
//校验是否是管理员
boolean adminRole = userService.checkAdminRole(currentUser);
if (adminRole) {
Category category = new Category();
BeanUtils.copyProperties(updateCategoryReq, category);
categoryService.update(category);
return ApiRestResponse.success();
} else {
return ApiRestResponse.error(ImoocMallExceptionEnum.NEED_ADMIN);
}
server层:
@Override
public void update(Category updateCategory) {
if (updateCategory.getName() != null) {
Category categoryOld = categoryMapper.selectByName(updateCategory.getName());
if (categoryOld != null && !categoryOld.getId().equals(updateCategory.getId())) {
//如果更新目录的id不等于原目录id则存在重复抛出异常
throw new ImoocMallException(ImoocMallExceptionEnum.NAME_EXISTED);
}
int count = categoryMapper.updateByPrimaryKeySelective(updateCategory);
if (count == 0) {
throw new ImoocMallException(ImoocMallExceptionEnum.UPDATE_FAILED);
}
}
}
3.后台删除目录
controller层:
public ApiRestResponse deleteCategory(@RequestParam Integer id) {
categoryService.delete(id);
return ApiRestResponse.success();
}
server层:
@Override
public void delete(Integer id) {
Category categoryOld = categoryMapper.selectByPrimaryKey(id);
if (categoryOld == null) {//查不到记录,无法删除,删除失败
throw new ImoocMallException(ImoocMallExceptionEnum.DELETE_FAILED);
}
int count = categoryMapper.deleteByPrimaryKey(id);
if (count == 0) {
throw new ImoocMallException(ImoocMallExceptionEnum.DELETE_FAILED);
}
}
4.后台目录列表(管理员看)
controller层:
@ApiOperation("后台目录列表")//管理员看
@GetMapping("/admin/category/list")
@ResponseBody
public ApiRestResponse listCategoryForAdmin(@RequestParam Integer pageNum, @RequestParam Integer pageSize) {
PageInfo pageInfo = categoryService.listForAdmin(pageNum, pageSize);
return ApiRestResponse.success(pageInfo);
}
server层:
@Override
public PageInfo listForAdmin(@RequestParam Integer pageNum, @RequestParam Integer pageSize) {
PageHelper.startPage(pageNum, pageSize, "type,order_num");
List<Category> categoryList = categoryMapper.selectList();
PageInfo pageInfo = new PageInfo(categoryList);
return pageInfo;
}
5.前台目录列表
controller层:
@ApiOperation("前台目录列表")//用户看,里面的递归实现目录树比较难
@GetMapping("category/list")
@ResponseBody
public ApiRestResponse listCategoryForCustomer() {
List<CategoryVO> categoryVOS= categoryService.listCategoryForCustomer(0);
return ApiRestResponse.success(categoryVOS);
}
server层:
使用 Redis 数据库对网页静态资源进行缓存,网页加载提速
@Override
@Cacheable(value = "listCategoryForCustomer")
public List<CategoryVO> listCategoryForCustomer(Integer parentId) {
ArrayList<CategoryVO> categoryVOList = new ArrayList<>();
recursivelyFindCategories(categoryVOList, parentId);
return categoryVOList;
}
private void recursivelyFindCategories(List<CategoryVO> categoryVOList, Integer parentId) {
//递归获取所有子类别,并组合成为一个“目录树”
List<Category> categoryList = categoryMapper.selectCategoriesByParentId(parentId);
if (!CollectionUtils.isEmpty(categoryList)) {
for (int i = 0; i < categoryList.size(); i++) {
Category category = categoryList.get(i);
CategoryVO categoryVO = new CategoryVO();
BeanUtils.copyProperties(category, categoryVO);
categoryVOList.add(categoryVO);
recursivelyFindCategories(categoryVO.getChildCategory(), categoryVO.getId());
}
}
}
另外,统一鉴权:用户过滤器,避免重复代码
1.用户过滤器
public class UserFilter implements Filter {
public static User currentUser;
@Autowired
UserService userService;
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpSession session = request.getSession();
currentUser = (User) session.getAttribute(Constant.IMOOC_MALL_USER);
if (currentUser == null) {
PrintWriter out = new HttpServletResponseWrapper((HttpServletResponse) servletResponse).getWriter();
out.write("{\n" +
" \"status\": 10007,\n" +
" \"msg\": \"NEED_LOGIN\",\n" +
" \"data\": null\n" +
"}");
out.flush();
out.close();
return;
}
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}
2.User过滤器的配置
@Configuration
public class UserFilterConfig {
@Bean
public UserFilter userFilter(){
return new UserFilter();
}
@Bean(name = "userFilterConf")
public FilterRegistrationBean adminFilterConfig(){
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(userFilter());
filterRegistrationBean.addUrlPatterns("/cart/*");
filterRegistrationBean.addUrlPatterns("/order/*");
filterRegistrationBean.setName("userFilterConf");
return filterRegistrationBean;
}
}
3.管理员校验过滤器
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpSession session = request.getSession();
User currentUser = (User) session.getAttribute(Constant.IMOOC_MALL_USER);
if (currentUser == null) {
PrintWriter out = new HttpServletResponseWrapper((HttpServletResponse) servletResponse).getWriter();
out.write("{\n" +
" \"status\": 10007,\n" +
" \"msg\": \"NEED_LOGIN\",\n" +
" \"data\": null\n" +
"}");
out.flush();
out.close();
return;
}
//校验是否是管理员
boolean adminRole = userService.checkAdminRole(currentUser);
if (adminRole) {
filterChain.doFilter(servletRequest, servletResponse);
} else {
PrintWriter out = new HttpServletResponseWrapper((HttpServletResponse) servletResponse).getWriter();
out.write("{\n" +
" \"status\": 10009,\n" +
" \"msg\": \"NEED_ADMIN\",\n" +
" \"data\": null\n" +
"}");
out.flush();
out.close();
}
}
4.Admin过滤器的配置
@Configuration
public class AdminFilterConfig {
@Bean
public AdminFilter adminFilter(){
return new AdminFilter();
}
@Bean(name = "adminFilterConf")
public FilterRegistrationBean adminFilterConfig(){
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(adminFilter());
filterRegistrationBean.addUrlPatterns("/admin/category/*");
filterRegistrationBean.addUrlPatterns("/admin/product/*");
filterRegistrationBean.addUrlPatterns("/admin/order/*");
filterRegistrationBean.setName("adminFilterConf");
return filterRegistrationBean;
}
}
5.缓存的配置类
public class CachingConfig {
@Bean
public RedisCacheManager redisCacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheWriter redisCacheWriter = RedisCacheWriter.lockingRedisCacheWriter(connectionFactory);
RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
cacheConfiguration = cacheConfiguration.entryTtl(Duration.ofSeconds(30));
RedisCacheManager redisCacheManager = new RedisCacheManager(redisCacheWriter,
cacheConfiguration);
return redisCacheManager;
}
}
三、商品模块
1.后台添加商品
public ApiRestResponse addProduct(@Valid @RequestBody AddProductReq addProductReq) {
productService.add(addProductReq);
return ApiRestResponse.success();
}
@Override
public void add(AddProductReq addProductReq){
Product product = new Product();
BeanUtils.copyProperties(addProductReq,product);
Product productOld = productMapper.selectByName(addProductReq.getName());
if (productOld!=null){
throw new ImoocMallException(ImoocMallExceptionEnum.NAME_EXISTED);
}
int count = productMapper.insertSelective(product);
if (count==0){
throw new ImoocMallException(ImoocMallExceptionEnum.CREATE_FAILED);
}
}
2.后台上传图片
public ApiRestResponse upload(HttpServletRequest httpServletRequest,@RequestParam("file") MultipartFile file){
String filename = file.getOriginalFilename();
String suffixName = filename.substring(filename.lastIndexOf("."));//截取后缀
//生成文件名称UUID
UUID uuid = UUID.randomUUID();
String newFileName= uuid.toString()+suffixName;
//创建文件
File fileDirectory = new File(Constant.FILE_UPLOAD_DIR);//文件夹
File destFile = new File(Constant.FILE_UPLOAD_DIR + newFileName);//目标文件
if (!fileDirectory.exists()){
if (!fileDirectory.mkdirs()){
throw new ImoocMallException(ImoocMallExceptionEnum.MKDIR_FAILED);
}
}
try {
file.transferTo(destFile);
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
return ApiRestResponse.success(getHost(new URI(httpServletRequest.getRequestURL()+""))+"/images/" + newFileName);
} catch (URISyntaxException e) {
return ApiRestResponse.error(ImoocMallExceptionEnum.UPLOAD_FAILED);
}
}
private URI getHost(URI uri){
URI effectiveURI;
try {//scheme(协议类型,如 http、https)、userInfo(用户信息),host(主机名)、port(端口号)、path(路径)、query(查询字符串)和 fragment(片段标识符)
effectiveURI=new URI(uri.getScheme(),uri.getUserInfo(),uri.getHost(),uri.getPort(),null,null,null);
} catch (URISyntaxException e) {
effectiveURI=null;
}
return effectiveURI;
}
3.后台更新商品
public ApiRestResponse updateProduct(@Valid @RequestBody UpdateProductReq updateProductReq){
Product product = new Product();
BeanUtils.copyProperties(updateProductReq,product);
productService.update(product);
return ApiRestResponse.success();
}
@Override
public void update(Product updateProduct){
Product productOld = productMapper.selectByName(updateProduct.getName());
//同名且不同id,不能继续修改
if (productOld!=null&&!productOld.getId().equals(updateProduct.getId())){
throw new ImoocMallException(ImoocMallExceptionEnum.NAME_EXISTED);
}
int count = productMapper.updateByPrimaryKeySelective(updateProduct);
if (count==0){
throw new ImoocMallException(ImoocMallExceptionEnum.UPDATE_FAILED);
}
}
4.后台删除商品
public ApiRestResponse deleteProduct(@RequestParam Integer id){
productService.delete(id);
return ApiRestResponse.success();
}
public void delete(Integer id) {
Product productOld = productMapper.selectByPrimaryKey(id);
if (productOld == null) {//查不到记录,无法删除,删除失败
throw new ImoocMallException(ImoocMallExceptionEnum.DELETE_FAILED);
}
int count = productMapper.deleteByPrimaryKey(id);
if (count == 0) {
throw new ImoocMallException(ImoocMallExceptionEnum.DELETE_FAILED);
}
}
5.后台批量上下架
public ApiRestResponse batchUpdateSellStatus( @RequestParam Integer[] ids,@RequestParam Integer sellStatus){
productService.batchUpdateSellStatus(ids,sellStatus);
return ApiRestResponse.success();
}
public void batchUpdateSellStatus(Integer[] ids, Integer sellStatus){
productMapper.batchUpdateSellStatus(ids, sellStatus);
}
6.商品列表(后台)
public ApiRestResponse list( @RequestParam Integer pageNumber,@RequestParam Integer pageSize){
PageInfo pageInfo = productService.listForAdmin(pageNumber, pageSize);
return ApiRestResponse.success(pageInfo);
}
public PageInfo listForAdmin(Integer pageNumber, Integer pageSize){
PageHelper.startPage(pageNumber,pageSize);
List<Product> products = productMapper.selectlistForAdmin();
PageInfo pageInfo = new PageInfo(products);
return pageInfo;
}
7.前台商品详情
public ApiRestResponse detail(@RequestParam Integer id){
Product product = productService.detail(id);
return ApiRestResponse.success(product);
}
public Product detail(Integer id){
Product product = productMapper.selectByPrimaryKey(id);
return product;
}
8.前台商品列表
public ApiRestResponse list(ProductListReq productListReq){
PageInfo list = productService.list(productListReq);
return ApiRestResponse.success(list);
}
可以根据关键字,目录id,升降序
public PageInfo list(ProductListReq productListReq){
//构建Query对象
ProductListQuery productListQuery = new ProductListQuery();
//搜索处理
if (!StringUtils.isEmpty(productListReq.getKeyword())){
String keyword = new StringBuilder().append("%").append(productListReq.getKeyword()).append("%").toString();
productListQuery.setKeyword(keyword);
}
//目录处理:如果查某个目录下的商品,不仅是需要查该目录下的,还要把所有子目录的所有商品都查出来,所以要拿到一个目录id的List
if (productListReq.getCategoryId()!=null){
List<CategoryVO> categoryVOList = categoryService.listCategoryForCustomer(productListReq.getCategoryId());
//平铺展开
ArrayList<Integer> categoryIds = new ArrayList<>();
categoryIds.add(productListReq.getCategoryId());//
getCategoryIds(categoryVOList,categoryIds);
productListQuery.setCategoryIds(categoryIds);
}
//排序处理
String orderBy = productListReq.getOrderBy();
if (Constant.ProductListOrder.PRICE_ASC_DESC.contains(orderBy)){//排序使用枚举
PageHelper.startPage(productListReq.getPageNum(),productListReq.getPageSize(),orderBy);
}else {
PageHelper.startPage(productListReq.getPageNum(),productListReq.getPageSize());
}
List<Product> productList = productMapper.selectList(productListQuery);
PageInfo pageInfo = new PageInfo(productList);
return pageInfo;
}
private void getCategoryIds(List<CategoryVO> categoryVOList, ArrayList<Integer> categoryIds){
for (CategoryVO categoryVO : categoryVOList) {
if (categoryVO!=null){
categoryIds.add(categoryVO.getId());
getCategoryIds(categoryVO.getChildCategory(),categoryIds);
}
}
}
查询商品列表的Query
public class ProductListQuery {
private String keyword;
private List<Integer> categoryIds;
public String getKeyword() {
return keyword;
}
public void setKeyword(String keyword) {
this.keyword = keyword;
}
public List<Integer> getCategoryIds() {
return categoryIds;
}
public void setCategoryIds(List<Integer> categoryIds) {
this.categoryIds = categoryIds;
}
}
四、购物车模块
1.购物车列表
public ApiRestResponse list(){
//内部获取用户Id,防止横向越权
List<CartVO> cartList = cartService.list(UserFilter.currentUser.getId());
return ApiRestResponse.success(cartList);
}
public List<CartVO> list(Integer userId){
List<CartVO> cartVOS = cartMapper.selectList(userId);
for (CartVO cartVO : cartVOS) {
cartVO.setTotalPrice(cartVO.getPrice()*cartVO.getQuantity());
}
return cartVOS;
}
2.添加商品到购物车
public ApiRestResponse add(@RequestParam Integer productId, @RequestParam Integer count){
List<CartVO> cartVOList = cartService.add(UserFilter.currentUser.getId(), productId, count);
return ApiRestResponse.success(cartVOList);
}
public List<CartVO> add(Integer userId, Integer productId, Integer count){
validProduct(productId,count);//判断商品是否存在
Cart cart = cartMapper.selectCartByUserIdAndProductId(userId, productId);
if (cart==null){
//这商品之前不在购物车,需要新增一个记录
cart = new Cart();
cart.setProductId(productId);
cart.setUserId(userId);
cart.setQuantity(count);
cart.setSelected(Constant.Cart.CHECKED);
cartMapper.insertSelective(cart);
}else {
//这个商品已经在购物车里,则数量想加
count=cart.getQuantity()+count;
Cart cartNew = new Cart();
cartNew.setQuantity(count);
cartNew.setId(cart.getId());
cartNew.setProductId(cart.getProductId());
cartNew.setUserId(cart.getUserId());
cartNew.setSelected(Constant.Cart.CHECKED);
cartMapper.updateByPrimaryKeySelective(cartNew);
}
return this.list(userId);
}
private void validProduct(Integer productId, Integer count){
Product product = productMapper.selectByPrimaryKey(productId);
//判断商品是否存在,商品是否上架
if (product==null||product.getStatus().equals(Constant.SaleStatus.NOT_SALE)){
throw new ImoocMallException(ImoocMallExceptionEnum.NOT_SALE);
}
//判断商品库存
if (count>product.getStock()){
throw new ImoocMallException(ImoocMallExceptionEnum.NOT_ENOUGH);
}
}
3.更新购物车
public ApiRestResponse update(@RequestParam Integer productId, @RequestParam Integer count){
List<CartVO> cartVOList = cartService.update(UserFilter.currentUser.getId(), productId, count);
return ApiRestResponse.success(cartVOList);
}
public List<CartVO> update(Integer userId, Integer productId, Integer count){
validProduct(productId,count);
Cart cart = cartMapper.selectCartByUserIdAndProductId(userId, productId);
if (cart==null){
//这商品之前不在购物车,无法更新
throw new ImoocMallException(ImoocMallExceptionEnum.UPDATE_FAILED);
}else {
//这个商品已经在购物车里,则更新数量
Cart cartNew = new Cart();
cartNew.setQuantity(count);
cartNew.setId(cart.getId());
cartNew.setProductId(cart.getProductId());
cartNew.setUserId(cart.getUserId());
cartNew.setSelected(Constant.Cart.CHECKED);
cartMapper.updateByPrimaryKeySelective(cartNew);
}
return this.list(userId);
}
4.删除购物车
public ApiRestResponse delete(@RequestParam Integer productId){
//不能传入userId,cartId,否则可以删除其他人的购物车
List<CartVO> cartVOList = cartService.delete(UserFilter.currentUser.getId(), productId);
return ApiRestResponse.success(cartVOList);
}
public List<CartVO> delete(Integer userId, Integer productId){
Cart cart = cartMapper.selectCartByUserIdAndProductId(userId, productId);
if (cart==null){
//这商品之前不在购物车,无法删除
throw new ImoocMallException(ImoocMallExceptionEnum.DELETE_FAILED);
}else {
//这个商品已经在购物车里,则可以删除
cartMapper.deleteByPrimaryKey(cart.getId());
}
return this.list(userId);
}
5.选中/不选择购物车的某商品
public ApiRestResponse select(@RequestParam Integer productId,@RequestParam Integer selected){
List<CartVO> cartVOList = cartService.selectOrNot(UserFilter.currentUser.getId(), productId,selected);
return ApiRestResponse.success(cartVOList);
}
public List<CartVO> selectOrNot(Integer userId, Integer productId, Integer selected){
Cart cart = cartMapper.selectCartByUserIdAndProductId(userId, productId);
if (cart==null){
//这商品之前不在购物车,选中失败
throw new ImoocMallException(ImoocMallExceptionEnum.UPDATE_FAILED);
}else {
//这个商品已经在购物车里,则可以选中/不选中
cartMapper.selectOrNot(userId,productId,selected);
}
return this.list(userId);
}
6.全选中/全不选择购物车的某商品
public ApiRestResponse select(@RequestParam Integer selected){
List<CartVO> cartVOList = cartService.selectAllOrNot(UserFilter.currentUser.getId(),selected);
return ApiRestResponse.success(cartVOList);
}
public List<CartVO> selectAllOrNot(Integer userId,Integer selected){
//改变选中状态
cartMapper.selectOrNot(userId,null,selected);
return this.list(userId);
}
五、订单模块
1.前台创建订单
controller层:
public ApiRestResponse create(@RequestBody CreateOrderReq createOrderReq){
String orderNo = orderService.create(createOrderReq);
return ApiRestResponse.success(orderNo);
}
server层:
public String create(CreateOrderReq createOrderReq) {
//拿到用户ID
Integer userId = UserFilter.currentUser.getId();
//从购物车查找已经勾选的商品
List<CartVO> cartVOList = cartService.list(userId);//根据用户id查看购物车
ArrayList<CartVO> cartVOListTemp = new ArrayList<>();//临时存贮
for (CartVO cartVO : cartVOList) {
if (cartVO.getSelected().equals(Constant.Cart.CHECKED)) {
cartVOListTemp.add(cartVO);
}
}
cartVOList = cartVOListTemp;
//如果购物车已勾选的为空,报错
if (CollectionUtils.isEmpty(cartVOList)) {
throw new ImoocMallException(ImoocMallExceptionEnum.CART_EMPTY);
}
//判断商品是否存在,上下架状态,库存
ValidSaleStatusAndStock(cartVOList);
//把购物车对象转为订单item对象
List<OrderItem> orderItemList = cartVOListToOrderItemList(cartVOList);
//扣库存
for (OrderItem orderItem : orderItemList) {
Product product = productMapper.selectByPrimaryKey(orderItem.getProductId());
int stock = product.getStock() - orderItem.getQuantity();
if (stock < 0) {
throw new ImoocMallException(ImoocMallExceptionEnum.NOT_ENOUGH);
}
product.setStock(stock);
productMapper.updateByPrimaryKeySelective(product);
}
//把购物车中的已勾选的商品删除
cleanCart(cartVOList);
//生成订单
Order order = new Order();
//生成订单号,有独立的规则
String orderNo = OrderCodeFactory.getOrderCode(Long.valueOf(userId));
order.setOrderNo(orderNo);
order.setUserId(userId);
order.setTotalPrice(totalPrice(orderItemList));
order.setReceiverName(createOrderReq.getReceiverName());
order.setReceiverMobile(createOrderReq.getReceiverMobile());
order.setReceiverAddress(createOrderReq.getReceiverAddress());
order.setOrderStatus(Constant.OrderStatusEnum.NOT_PAID.getCode());
order.setPostage(0);
order.setPaymentType(1);
//插入到Order表
orderMapper.insertSelective(order);
//循环保存每个商品到order_item表
for (OrderItem orderItem : orderItemList) {
orderItem.setOrderNo(order.getOrderNo());
orderItemMapper.insertSelective(orderItem);
// throw new ImoocMallException(ImoocMallExceptionEnum.CART_EMPTY);
}
//结果返回
return orderNo;
}
private Integer totalPrice(List<OrderItem> orderItemList) {
Integer totalPrice = 0;
for (OrderItem orderItem : orderItemList) {
totalPrice += orderItem.getTotalPrice();
}
return totalPrice;
}
private void cleanCart(List<CartVO> cartVOList) {
for (CartVO cartVO : cartVOList) {
cartMapper.deleteByPrimaryKey(cartVO.getId());
}
}
private List<OrderItem> cartVOListToOrderItemList(List<CartVO> cartVOList) {
ArrayList<OrderItem> orderItemList = new ArrayList<>();
for (CartVO cartVO : cartVOList) {
OrderItem orderItem = new OrderItem();
orderItem.setProductId(cartVO.getProductId());
//记录商品快照信息
orderItem.setProductName(cartVO.getProductName());
orderItem.setProductImg(cartVO.getProductImage());
orderItem.setUnitPrice(cartVO.getPrice());
orderItem.setQuantity(cartVO.getQuantity());
orderItem.setTotalPrice(cartVO.getTotalPrice());
orderItemList.add(orderItem);
}
return orderItemList;
}
private void ValidSaleStatusAndStock(List<CartVO> cartVOList) {
for (CartVO cartVO : cartVOList) {
Product product = productMapper.selectByPrimaryKey(cartVO.getProductId());
//判断商品是否存在,商品是否上架
if (product == null || product.getStatus().equals(Constant.SaleStatus.NOT_SALE)) {
throw new ImoocMallException(ImoocMallExceptionEnum.NOT_SALE);
}
//判断商品库存
if (cartVO.getQuantity() > product.getStock()) {
throw new ImoocMallException(ImoocMallExceptionEnum.NOT_ENOUGH);
}
}
}
2.前台订单详情
public ApiRestResponse detail(@RequestParam String orderNo){
OrderVO orderVO = orderService.detail(orderNo);
return ApiRestResponse.success(orderVO);
}
@Override
public OrderVO detail(String orderNo) {
Order order = orderMapper.selectByOrderNo(orderNo);
//订单不存在,则报错
if (order == null) {
throw new ImoocMallException(ImoocMallExceptionEnum.NO_ORDER);
}
//订单存在,判断所属
Integer userId = UserFilter.currentUser.getId();
if (!order.getUserId().equals(userId)) {
throw new ImoocMallException(ImoocMallExceptionEnum.NOT_YOUR_ORDER);
}
OrderVO orderVO = getOrderVO(order);//拼装
return orderVO;
}
private OrderVO getOrderVO(Order order) {
OrderVO orderVO = new OrderVO();
BeanUtils.copyProperties(order, orderVO);
//获取订单对应的orderItemVOList
List<OrderItem> orderItemList = orderItemMapper.selectByOrderNo(order.getOrderNo());
ArrayList<OrderItemVO> orderItemVOList = new ArrayList<>();
for (OrderItem orderItem : orderItemList) {
OrderItemVO orderItemVO = new OrderItemVO();
BeanUtils.copyProperties(orderItem, orderItemVO);
orderItemVOList.add(orderItemVO);
}
orderVO.setOrderItemVOList(orderItemVOList);
orderVO.setOrderStatusName(Constant.OrderStatusEnum.codeOf(orderVO.getOrderStatus()).getValue());
return orderVO;
}
3.前台订单列表
public ApiRestResponse list(@RequestParam Integer pageNum,@RequestParam Integer pageSize){
PageInfo pageInfo = orderService.listForCustomer(pageNum, pageSize);
return ApiRestResponse.success(pageInfo);
}
@Override
public PageInfo listForCustomer(Integer pageNum, Integer pageSize) {
Integer userId = UserFilter.currentUser.getId();
PageHelper.startPage(pageNum, pageSize);
List<Order> orderList = orderMapper.selectForCustomer(userId);
List<OrderVO> orderVOList = orderListToOrderVOList(orderList);
PageInfo PageInfo = new PageInfo<>(orderList);
PageInfo.setList(orderVOList);
return PageInfo;
}
private List<OrderVO> orderListToOrderVOList(List<Order> orderList) {
List<OrderVO> orderVOList = new ArrayList<>();
for (Order order : orderList) {
OrderVO orderVO = getOrderVO(order);
orderVOList.add(orderVO);
}
return orderVOList;
}
4.前台取消订单
public ApiRestResponse cancel(@RequestParam String orderNo){
orderService.cancel(orderNo);
return ApiRestResponse.success();
}
@Override
public void cancel(String orderNo) {
Order order = orderMapper.selectByOrderNo(orderNo);
//查不到订单
if (order == null) {
throw new ImoocMallException(ImoocMallExceptionEnum.NO_ORDER);
}
//查到了也要验证用户身份
Integer userId = UserFilter.currentUser.getId();
if (!order.getUserId().equals(userId)) {
throw new ImoocMallException(ImoocMallExceptionEnum.NOT_YOUR_ORDER);
}
if (order.getOrderStatus().equals(Constant.OrderStatusEnum.NOT_PAID.getCode())) {
order.setOrderStatus(Constant.OrderStatusEnum.CANCELED.getCode());
order.setEndTime(new Date());
orderMapper.updateByPrimaryKeySelective(order);
} else {
throw new ImoocMallException(ImoocMallExceptionEnum.WRONG_ORDER_STATUS);
}
}
5.生成支付二维码
public ApiRestResponse qrcode(@RequestParam String orderNo){
String pngAddress = orderService.qrcode(orderNo);
return ApiRestResponse.success(pngAddress);
}
public String qrcode(String orderNo) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
/*try {
ip=InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}*/
String address = ip + ":" + request.getLocalPort();
String payUrl = "http://" + address + "/pay?orderNo=" + orderNo;
try {
QRCodeGenerator.generateQRCodeImage(payUrl, 350, 350, Constant.FILE_UPLOAD_DIR + orderNo + ".png");
} catch (WriterException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
String pngAddress = "http://" + address + "/images/" + orderNo + ".png";
return pngAddress;
}
6.支付订单
public ApiRestResponse pay(@RequestParam String orderNo){
orderService.pay(orderNo);
return ApiRestResponse.success();
}
@Override
public void pay(String orderNo){
Order order = orderMapper.selectByOrderNo(orderNo);
//查不到订单
if (order == null) {
throw new ImoocMallException(ImoocMallExceptionEnum.NO_ORDER);
}
if (order.getOrderStatus()== Constant.OrderStatusEnum.NOT_PAID.getCode()){
order.setOrderStatus(Constant.OrderStatusEnum.PAID.getCode());
order.setPayTime(new Date());
orderMapper.updateByPrimaryKeySelective(order);
}else {
throw new ImoocMallException(ImoocMallExceptionEnum.WRONG_ORDER_STATUS);
}
}
7.后台:订单列表
@GetMapping("/admin/order/list")
@ApiOperation("管理员订单列表")
public ApiRestResponse listForAdmin(@RequestParam Integer pageNum, @RequestParam Integer pageSize) {
PageInfo pageInfo = orderService.listForAdmin(pageNum, pageSize);
return ApiRestResponse.success(pageInfo);
}
@Override
public PageInfo listForAdmin(Integer pageNum, Integer pageSize) {
PageHelper.startPage(pageNum, pageSize);
List<Order> orderList = orderMapper.selectAllForAdmin();
List<OrderVO> orderVOList = orderListToOrderVOList(orderList);
PageInfo PageInfo = new PageInfo<>(orderList);
PageInfo.setList(orderVOList);
return PageInfo;
}
8.后台:订单发货
@PostMapping("/admin/order/delivered")
@ApiOperation("管理员发货")
//订单状态: 0用户已取消,10未付款(初始状态),20已付款,30已发货,40交易完成
public ApiRestResponse delivered(@RequestParam String orderNo) {
orderService.deliver(orderNo);
return ApiRestResponse.success();
}
@Override
public void deliver(String orderNo){
Order order = orderMapper.selectByOrderNo(orderNo);
//查不到订单
if (order == null) {
throw new ImoocMallException(ImoocMallExceptionEnum.NO_ORDER);
}
if (order.getOrderStatus()== Constant.OrderStatusEnum.PAID.getCode()){
order.setOrderStatus(Constant.OrderStatusEnum.DELIVERED.getCode());
order.setDeliveryTime(new Date());
orderMapper.updateByPrimaryKeySelective(order);
}else {
throw new ImoocMallException(ImoocMallExceptionEnum.WRONG_ORDER_STATUS);
}
}
9.前后台通用-订单完结
public ApiRestResponse finish(@RequestParam String orderNo) {
orderService.finish(orderNo);
return ApiRestResponse.success();
}
@Override
public void finish(String orderNo){
Order order = orderMapper.selectByOrderNo(orderNo);
//查不到订单
if (order == null) {
throw new ImoocMallException(ImoocMallExceptionEnum.NO_ORDER);
}
//如果是普通用户,校验订单所属
if (!userService.checkAdminRole(UserFilter.currentUser)&& order.getUserId().equals(UserFilter.currentUser.getId())) {
throw new ImoocMallException(ImoocMallExceptionEnum.NOT_YOUR_ORDER);
}
//发货后可以完结订单
if (order.getOrderStatus()== Constant.OrderStatusEnum.DELIVERED.getCode()){
order.setOrderStatus(Constant.OrderStatusEnum.FINISHED.getCode());
order.setEndTime(new Date());
orderMapper.updateByPrimaryKeySelective(order);
}else {
throw new ImoocMallException(ImoocMallExceptionEnum.WRONG_ORDER_STATUS);
}
}