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);
}
}