Θα δημιουργήσουμε το Angular cart-page component, το οποίο θα αντιπροσωπεύει το καλάθι του χρήστη
Εάν ο χρήστης είναι συνδεδεμένος τότε, το καλάθι του θα αποθηκεύεται στη βάση δεδομένων. Αλλιώς αν είναι ανώνυμος, τότε θα αποθηκεύεται στο browser του στο localStorage.
Δημιουργούμε τον πίνακα Cart στη βάση
Δημιουργούμε το σύνθετο πρωτεύον κλειδί CartPrimaryKey και το entity Cart στο springeshop.model
@Embeddable
public class CartPrimaryKey implements Serializable{
private int userId;
private int productId;
public CartPrimaryKey() {}
//Getters - Setters ...
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof CartPrimaryKey)) return false;
CartPrimaryKey that = (CartPrimaryKey) o;
return Objects.equals(getUserId(), that.getUserId()) && Objects.equals(getProductId(), that.getProductId());
}
@Override
public int hashCode() {
return Objects.hash(getUserId(), getProductId());
}
}
@Entity
@Table(name = "cart")
public class Cart{
@EmbeddedId
private CartPrimaryKey id;
@OneToOne(fetch = FetchType.LAZY)
@MapsId("userId")
private User user;
@OneToOne(fetch = FetchType.LAZY)
@MapsId("productId")
private Product product;
@Column(name = "quantity")
@NotNull(message = "Please provide quantity")
private int quantity;
@Column(name = "expiration")
private Timestamp expiration;
public Cart() {}
//Getters - Setters ...
}
Δημιουργούμε το CartProduct στο springeshop.model
public class CartProduct{
private int userId;
private int productId;
private String name;
private String brand ;
private String imageUrl;
private double price;
private int quantity;
public CartProduct() {}
//Getters - Setters ...
}
Δημιουργούμε ένα repository CartRepository.
package springeshop.repositories;
@Repository
public interface CartRepository extends JpaRepository<Cart, Integer> {
@Query("select cartProduct from Cart cartProduct where cartProduct.user.id = :userid")
List<Cart> findUserCartProducts(@Param("userid") int userid);
@Query(value = "delete from Cart cartProduct where cartProduct.user.id = :userid")
@Modifying
void deleteUserCart(@Param("userid") int userid);
@Query(value = "select cartProduct from Cart cartProduct where cartProduct.user.id = :userid and cartProduct.product.id = :productid")
Cart findUserCartProductRow(@Param("userid") int userid, @Param("productid") int productid);
@Query(value = "delete from Cart cartProduct where cartProduct.user.id = :userid and cartProduct.product.id = :productid")
@Modifying
void deleteUserCartProductRow(@Param("userid") int userid, @Param("productid") int productid);
@Query(value = "insert into cart (user_id, product_id, quantity, expiration) values ( :userid, :productid, :quantity, :expiration )",nativeQuery = true))
void addProductToCart(@Param("userid") int userid, @Param("productid") int productid, @Param("quantity") int quantity, @Param("expiration") Timestamp expiration);
@Query("update Cart cartProduct set cartProduct.quantity = :quantity where cartProduct.user.id = :userid and cartProduct.product.id = :productid")
@Modifying
void updateCartProduct (@Param("userid") int userid, @Param("productid") int productid, @Param("quantity") int quantity);
}
Δημιουργούμε το CartService και CartServiceImpl στο springeshop.service .
package springeshop.service;
public interface CartService{
List<Cart> findUserCartProducts(int userid);
boolean deleteUserCartAndIsSuccess(int userid);
Cart findUserCartRow(int userid, int productid);
boolean deleteUserCartRowAndIsSuccess(int userid, int productid);
boolean addProductToCartAndIsSuccess(Cart cartProduct);
boolean updateCartProductAndIsSuccess(int userid, int productid, int quantity);
boolean doesUserCartRowExist(int userid, int productid);
}
package springeshop.service;
@Service("cartService")
@Transactional
public class CartServiceImpl implements CartService{
@Autowired
private CartRepository cartRepository;
@Override
public List<Cart> findUserCartProducts(int userid) {
return userRepository.findByUsername(userName);
}
@Override
public deleteUserCartAndIsSuccess(int userid) {
boolean isSuccess = false;
try {
cartRepository.deleteUserCart(userid);
isSuccess = true;
} catch (DataAccessException exception) {
System.out.println(exception);
isSuccess = false;
}
return isSuccess;
}
@Override
public Cart findUserCartRow(int userid, int productid) {
return cartRepository.findUserCartProductRow(userid, productid);
}
@Override boolean deleteUserCartRowAndIsSuccess(int userid, int productid) {
boolean isSuccess = false;
try {
cartRepository.deleteUserCartProductRow(userid, productid);
isSuccess = true;
} catch (DataAccessException exception) {
System.out.println(exception);
isSuccess = false;
}
return isSuccess;
}
@Override boolean addProductToCartAndIsSuccess(Cart cartProduct) {
boolean isSuccess = false;
try {
cartRepository.save(cartProduct);
isSuccess = true;
} catch (DataAccessException exception) {
System.out.println(exception);
isSuccess = false;
}
return isSuccess;
}
@Override boolean updateCartProductAndIsSuccess(int userid, int productid, int quantity) {
boolean isSuccess = false;
try {
cartRepository.updateCartProduct(userid, productid, quantity);
isSuccess = true;
} catch (DataAccessException exception) {
System.out.println(exception);
isSuccess = false;
}
return isSuccess;
}
@Override
public User findById(int id) {
return userRepository.findById(id);
}
}
Δημιουργούμε τoν CartApiController στο πακέτο springeshop.controller
package springeshop.controller;
@RestController
@RequestMapping("/api")
public class CartApiController{
@Autowired
private CartService cartService;
@Autowired
private UserService userService;
@Autowired
private ProductService productService;
@Autowired
private ProductImageService productImageService;
...
Προσθέτουμε τη μέθοδο createCartProduct() στον CartApiController, με την οποία προσθέτουμε προϊόντα στο πίνακα Carts. O client στέλνει το ένα CartProduct, που περιέχει το id του χρήστη και του προϊόντος και άλλα στοιχεία του και τα προσθέτουμε στον πίνακα.
@RequestMapping(value = "/carts", method = RequestMethod.POST)
public ResponseEntity<?> createCartProduct(@RequestBody() CartProduct cartProduct{
User user = userService.findById(cartProduct.getUserid());
Product product = productService.findById(cartProduct.getProductid());
if(user == null){
return new ResponseEntity<>(new ErrorMessage("Unable to create. User does not exist" , HttpStatus.BAD_REQUEST);
}
if(product == null){
return new ResponseEntity<>(new ErrorMessage("Unable to create. Product does not exist" , HttpStatus.BAD_REQUEST);
}
if(cartProduct.getQuantity() < 0){
return new ResponseEntity<>(new ErrorMessage("Unable to create. Quantity does not exist" , HttpStatus.BAD_REQUEST);
}
CartPrimaryKey cartProductCompositeId = new CartPrimaryKey(cartProduct.getUserid(), cartProduct.getProductid());
Cart cartRow = new Cart();
User user = userService.findById(cartProduct.getUserid());
Timestamp expiration = new Timestamp(System.currentTimeMillis());
cartRow.setId(cartProductCompositeId);
cartRow.setUser(user);
cartRow.setProduct(product);
cartRow.setQuantity(cartProduct.getQuantity());
cartRow.setExpiration(expiration);
if(cartProduct.getQuantity() < 0){
CartProduct cartProductCreated = new CartProduct();
cartProductCreated.setUserid(cartRow.getId().getUserId());
cartProductCreated.setProductid(cartRow.getId().getProductId());
cartProductCreated.setName(cartRow.getProduct().getName());
cartProductCreated.setBrand(cartRow.getProduct().getBrand().getName());
cartProductCreated.setQuantity(cartRow.getQuantity());
cartProductCreated.setPrice(cartRow.getProduct().getPrice());
return new ResponseEntity<>(cartProductCreated, HttpStatus.CREATED);
}
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
Προσθέτουμε τη μέθοδο getUserCartProducts(), η οποία δέχεται το id του χρήστη και επιστρέφει τα προϊόντα του καλαθιού του.
@RequestMapping(value = "/carts/{userid}", method = RequestMethod.GET)
public ResponseEntity<?> getUserCartProducts(@PathVariable(value = "userid", required = true)) int userid{
User user = userService.findById(cartProduct.getUserid());
if(user == null){
return new ResponseEntity<>(new ErrorMessage("User does not exist" , HttpStatus.BAD_REQUEST);
}
List<Cart> products = cartService.findUserCartProducts(userid);
List<CartProduct> cartProducts = new ArrayList<>();
if(products == null){
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
for(Cart cart : products){
CartProduct prod = new CartProduct();
prod.setUserid(cart.getId().getUserId());
prod.setProductid(cart.getId().getProductId());
prod.setName(cart.getProduct().getName());
prod.setBrand(cart.getProduct().getBrand().getName());
prod.setQuantity(cart.getQuantity());
prod.setPrice(cart.getProduct().getPrice());
ProductImage productImage = productImageService.findByProductId(prod.getProductid());
prod.setImageUrl(productImage.getVerySmallImageurl());
cartProducts.add(prod);
}
return new ResponseEntity<List<CartProduct>>(cartProducts, HttpStatus.OK);
}
Προσθέτουμε τη μέθοδο getUserCartProduct(), η οποία δέχεται το id του χρήστη και προϊόντος, επιστρέφει το προϊόν αυτό.
@RequestMapping(value = "/carts/{userid}/products/{productid}", method = RequestMethod.GET)
public ResponseEntity<?> getUserCartProduct(@PathVariable(value = "userid", required = true)) String userid,
@PathVariable(value = "productid", required = true)) String productid){
int usrId = Integer.parseInt(userid);
int prodId = Integer.parseInt(productid);
User user = userService.findById(usrId);
if(user == null){
return new ResponseEntity<>(new ErrorMessage("User does not exist" , HttpStatus.BAD_REQUEST);
}
if(!cartService.doesUserCartRowExist(usrId, prodId)){
return new ResponseEntity<>(new ErrorMessage("Product does not exist" , HttpStatus.NOT_FOUND);
}
Cart cartRow = cartService.findUserCartRow(usrId, prodId);
CartProduct cartProduct = new CartProduct();
cartProduct.setUserid(cart.getId().getUserId());
cartProduct.setProductid(cart.getId().getProductId());
cartProduct.setName(cart.getProduct().getName());
cartProduct.setBrand(cart.getProduct().getBrand().getName());
cartProduct.setQuantity(cart.getQuantity());
cartProduct.setPrice(cart.getProduct().getPrice());
return new ResponseEntity<CartProduct>(cartProduct, HttpStatus.OK);
}
Προσθέτουμε τη μέθοδο deleteUserCartProduct(), η οποία δέχεται το id του χρήστη και προϊόντος, διαγράφει το προϊόν από το καλάθι.
@RequestMapping(value = "/carts/{userid}/products/{productid}", method = RequestMethod.DELETE)
public ResponseEntity<?> deleteUserCartProduct(@PathVariable(value = "userid", required = true)) String userid,
@PathVariable(value = "productid", required = true)) String productid){
int usrId = Integer.parseInt(userid);
int prodId = Integer.parseInt(productid);
User user = userService.findById(usrId);
if(user == null){
return new ResponseEntity<>(new ErrorMessage("User does not exist" , HttpStatus.BAD_REQUEST);
}
if(!cartService.doesUserCartRowExist(usrId, prodId)){
return new ResponseEntity<>(new ErrorMessage("Product does not exist" , HttpStatus.NOT_FOUND);
}
if(cartService.deleteUserCartRowAndIsSuccess(usrId, prodId)){
return new ResponseEntity<>(HttpStatus.OK);
}
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
Προσθέτουμε τη μέθοδο updateCartProduct(), η οποία δέχεται το id του χρήστη και προϊόντος και ενημερώνουμε την ποσότητα του προϊόντος.
@RequestMapping(value = "/carts/{userid}/products/{productid}", method = RequestMethod.PATCH)
public ResponseEntity<?> updateCartProduct(@PathVariable(value = "userid", required = true)) String userid,
@PathVariable(value = "productid", required = true)) String productid){
int usrId = Integer.parseInt(userid);
int prodId = Integer.parseInt(productid);
User user = userService.findById(usrId);
Product product = productService.findById(prodId);
if(user == null){
return new ResponseEntity<>(new ErrorMessage("User does not exist" , HttpStatus.BAD_REQUEST);
}
if(product == null){
return new ResponseEntity<>(new ErrorMessage("Product does not exist" , HttpStatus.BAD_REQUEST);
}
if(cartProduct.getQuantity() <> 0){
return new ResponseEntity<>(new ErrorMessage("Quantity cannot be negative" , HttpStatus.BAD_REQUEST);
}
int oldQuantity = cartService.findUserCartRow(usrId, prodId).getQuantity();
if(oldQuantity != cartProduct.getQuantity()){
if(cartService.updateCartProductAndIsSuccess(usrId, prodId, cartProduct.getQuantity())){
return new ResponseEntity<>(HttpStatus.OK);
}else{
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
return new ResponseEntity<>(HttpStatus.INTERNAL_OK);
}
Προσθέτουμε τη μέθοδο deleteUserCart(), η οποία δέχεται το id του χρήστη και διαγράφει το καλάθι του.
@RequestMapping(value = "/carts/{userid}/products/{productid}", method = RequestMethod.DELETE)
public ResponseEntity<?> deleteUserCart(@PathVariable(value = "userid", required = true)) String userid){
int usrId = Integer.parseInt(userid);
User user = userService.findById(usrId);
if(user == null){
return new ResponseEntity<>(new ErrorMessage("User does not exist" , HttpStatus.BAD_REQUEST);
}
if(cartService.findUserCartProducts(usrId).isEmpty()){
return new ResponseEntity<>(new ErrorMessage("Cart is empty" , HttpStatus.BAD_REQUEST);
}
if(cartService.deleteUserCartAndIsSuccess(usrId)){
return new ResponseEntity<>(HttpStatus.OK);
}
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
Δημιουργούμε το component cart-page και το service cart.
ng generate component cart-page
ng generate service cart
Δημιουργούμε ένα μοντέλο CartProduct
cart.service.ts
Όταν ο χρήστης είναι συνδεδεμένος, το καλάθι αποθηκεύται στη βάση.
Όταν ο χρήστης δεν είναι συνδεδεμένος, το καλάθι αποθηκεύεται στο localStorage ως String
Προσθέτουμε τη μέθοδο addProductsToCart() στο ProductPageComponent, ώστε προσθέτει ο χρήστης προιόντα στο καλάθι
cart-page.component.ts
cart-page.component.html
cart-page.component.css
Εμφάνιση σελίδας