Coverage Summary for Class: BuyerService (cn.edu.ecnu.stu.bookstore.service.impl)

Class Method, % Line, %
BuyerService 100% (10/10) 85.1% (63/74)
BuyerService$$EnhancerBySpringCGLIB$$38590581
BuyerService$$EnhancerBySpringCGLIB$$38590581$$FastClassBySpringCGLIB$$e70917e7
BuyerService$$EnhancerBySpringCGLIB$$7b9f9cbc
BuyerService$$EnhancerBySpringCGLIB$$7b9f9cbc$$FastClassBySpringCGLIB$$3da5d183
BuyerService$$FastClassBySpringCGLIB$$f1ad8679
Total 100% (10/10) 85.1% (63/74)


 package cn.edu.ecnu.stu.bookstore.service.impl;
 
 import cn.edu.ecnu.stu.bookstore.component.AppException;
 import cn.edu.ecnu.stu.bookstore.component.Constants;
 import cn.edu.ecnu.stu.bookstore.config.RabbitMqConfig;
 import cn.edu.ecnu.stu.bookstore.mapper.BookMapper;
 import cn.edu.ecnu.stu.bookstore.mapper.OrderMapper;
 import cn.edu.ecnu.stu.bookstore.mapper.StoreMapper;
 import cn.edu.ecnu.stu.bookstore.mapper.UserMapper;
 import cn.edu.ecnu.stu.bookstore.pojo.*;
 import cn.edu.ecnu.stu.bookstore.pojo.vo.NewOrderVO;
 import org.springframework.amqp.rabbit.core.RabbitTemplate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
 import java.util.*;
 import java.util.stream.Collectors;
 
 @Service
 public class BuyerService {
 
     @Autowired
     private BookMapper bookMapper;
 
     @Autowired
     private OrderMapper orderMapper;
 
     @Autowired
     private UserMapper userMapper;
 
     @Autowired
     private StoreMapper storeMapper;
 
     @Autowired
     private PasswordEncoder encoder;
 
     @Autowired
     @Lazy
     private BuyerService buyerService;
 
     @Autowired
     private RabbitTemplate rabbitTemplate;
 
     public void newOrder(NewOrderVO newOrderVO) {
         List<Map<String, Object>> bookList = newOrderVO.getBooks();
         if(bookList.size() < 1)
             throw new AppException(Constants.CLIENT_ERROR, Constants.ORDER_IS_NULL_ERROR);
         HashMap<String, Integer> bookMap = new HashMap<>();
         for(Map<String, Object> map : bookList) {
             bookMap.put((String) map.get("id"), (Integer) map.get("count"));
         }
         String storeId = newOrderVO.getStoreId();
         Store store = storeMapper.getStoreById(storeId);
         if(store == null)
             throw new AppException(Constants.CLIENT_ERROR, Constants.STORE_NON_EXIST_ERROR);
 
         buyerService.insertOrder(store, bookMap, bookList);
     }
 
     @Transactional
     public void insertOrder(Store store, HashMap<String, Integer> bookMap, List<Map<String, Object>> bookList) {
         String storeId = store.getStoreId();
         List<Book> books = bookMapper.batchSelect(storeId, bookMap.keySet());
         if(books.size() != bookList.size())
             throw new AppException(Constants.CLIENT_ERROR, Constants.BOOK_ERROR);
         List<Map<String, Object>> list = books.stream().map(book -> {
             int count = bookMap.get(book.getBookId());
             if(count > book.getStockLevel())
                 throw new AppException(Constants.CLIENT_ERROR, Constants.STOCK_LEVEL_ERROR);
             Map<String, Object> map = new HashMap<>();
             map.put("count", count);
             map.put("book", book);
             return map;
         }).collect(Collectors.toList());
         BigDecimal sum = new BigDecimal(0);
         for(Book book : books) {
             sum = sum.add(book.getPrice().multiply(BigDecimal.valueOf(bookMap.get(book.getBookId()))));
         }
         User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
         String orderId = UUID.randomUUID().toString();
         Order order = Order.builder().orderId(orderId).buyerId(user.getId()).storeId(storeId)
                         .price(sum).status(OrderStatus.WAIT_PAYMENT)
                         .build();
         orderMapper.insert(order);
         orderMapper.insertOrderBook(orderId, list);
         for (Map<String, Object> map : list) {
             Book book = (Book)map.get("book");
             bookMapper.minusStockLevel(book.getBookId(), (int)map.get("count"));
         }
         rabbitTemplate.convertAndSend(RabbitMqConfig.EXPIRED_ORDER_EXCHANGE, RabbitMqConfig.EXPIRED_ORDER_ROUTING_KEY,
                 orderId, message -> {
                     message.getMessageProperties().setDelay(10000);
                     return message;
                 });
     }
 
     public void payment(Integer userId, String orderId, String password) {
         User user = userMapper.selectOneById(userId);
         if(!encoder.matches(password, user.getPassword()))
             throw new AppException(Constants.CLIENT_ERROR, Constants.PASSWORD_ERROR);
         Order order = orderMapper.selectById(orderId);
         if(order == null)
             throw new AppException(Constants.CLIENT_ERROR, Constants.ORDER_NON_EXIST_ERROR);
         if(!order.getStatus().equals(OrderStatus.WAIT_PAYMENT))
             throw new AppException(Constants.CLIENT_ERROR, Constants.ORDER_HAS_PAID_ERROR);
         if(order.getPrice().compareTo(user.getBalance()) > 0)
             throw new AppException(Constants.CLIENT_ERROR, Constants.BALANCE_ERROR);
         buyerService.updateBalanceAndOrder(storeMapper.getStoreById(order.getStoreId()).getSellerId(), order);
     }
 
     @Transactional
     public void updateBalanceAndOrder(Integer sellerId, Order order) {
         orderMapper.updateOrderStatus(order.getOrderId(), OrderStatus.WAIT_SEND);
         BigDecimal price = order.getPrice();
         userMapper.minusBalance(order.getBuyerId(), price);
         userMapper.addBalance(sellerId, price);
     }
 
     public void addFunds(String username, String password, BigDecimal addValue) {
         User user = userMapper.selectOneByName(username);
         if(!encoder.matches(password, user.getPassword()))
             throw new AppException(Constants.CLIENT_ERROR, Constants.PASSWORD_ERROR);
         userMapper.addBalance(user.getId(), addValue);
 
     }
 
     public List<Order> getOrderList() {
         User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
         return orderMapper.select(user.getId(), OrderStatus.WAIT_PAYMENT);
 
     }
 
 
     public void takeDelivery(String orderId) {
         Order order = orderMapper.selectById(orderId);
         if(order == null)
             throw new AppException(Constants.CLIENT_ERROR, Constants.ORDER_NON_EXIST_ERROR);
         User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
         if(!order.getBuyerId().equals(user.getId()))
             throw new AppException(Constants.CLIENT_ERROR, Constants.AUTHORITY_ERROR);
         if(!order.getStatus().equals(OrderStatus.WAIT_RECEIVE))
             throw new AppException(Constants.CLIENT_ERROR, Constants.STATUS_ERROR);
         orderMapper.updateOrderStatus(orderId, OrderStatus.COMPLETED);
 
     }
 }