Skip to content

Commit

Permalink
Merge pull request #79 from keke125/development
Browse files Browse the repository at this point in the history
feat: Introduce Email Notification functionality and fix: Strengthen security by replacing JWT Key and email configuration with environment variables.
  • Loading branch information
keke125 authored Dec 22, 2023
2 parents 0ead1ab + 09f391d commit 34f2707
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 85 deletions.
129 changes: 126 additions & 3 deletions src/main/java/ntou/auction/spring/mail/EmailService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

import jakarta.mail.Message;
import jakarta.mail.internet.InternetAddress;
import ntou.auction.spring.util.AppConfig;
import ntou.auction.spring.product.entity.Product;
import ntou.auction.spring.account.entity.User;
import ntou.auction.spring.account.service.UserService;
import ntou.auction.spring.order.entity.Order;
import ntou.auction.spring.product.entity.Product;
import ntou.auction.spring.util.AppConfig;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessagePreparator;
Expand All @@ -25,7 +26,7 @@ public EmailService(JavaMailSender mailSender, UserService userService, AppConfi
this.appConfig = appConfig;
}

public void sendMailBid(Long userId, Product product) {
public void sendMailBidSuccess(Long userId, Product product) {

if (userService.get(userId).isEmpty()) {
System.err.println("找不到ID為 " + userId + " 的使用者,無法寄出得標成功通知");
Expand Down Expand Up @@ -56,4 +57,126 @@ public void sendMailBid(Long userId, Product product) {
}
}

/*
public void sendMailBidFailed(Long userId, Product product) {
if (userService.get(userId).isEmpty()) {
System.err.println("找不到ID為 " + userId + " 的使用者,無法寄出商品下架通知");
return;
}
User customer = userService.get(userId).get();
MimeMessagePreparator preparator = mimeMessage -> {
mimeMessage.setSubject("[NTOU Auction] 商品下架通知", "UTF-8");
mimeMessage.setRecipient(Message.RecipientType.TO,
new InternetAddress(customer.getEmail()));
mimeMessage.setFrom(new InternetAddress(appConfig.getMailUsername()));
mimeMessage.setText("親愛的 " + customer.getName()
+ " (@" + customer.getUsername() + ") 您好:" + "\n"
+ "您之前參加競標的 " + product.getProductName() + " 商品"
+ "目前已由賣家下架,造成您的不便還請見諒。" + "\n\n"
+ "感謝您使用 NTOU Auction,歡迎選購其他商品!" + "\n\n"
+ "此為系統自動發送之郵件,請勿回覆!", "UTF-8"
);
mimeMessage.setSentDate(new Date());
};
try {
this.mailSender.send(preparator);
} catch (MailException ex) {
System.err.println(ex.getMessage());
}
}
*/
public void sendMailOrderEstablished(Long userId, Order order) {

if (userService.get(userId).isEmpty() || userService.get(order.getSellerid()).isEmpty()) {
System.err.println("找不到ID為 " + userId + " 的使用者,或查無賣家,無法寄出訂單成立通知");
return;
}
User customer = userService.get(userId).get();
User seller = userService.get(order.getSellerid()).get();

MimeMessagePreparator buyerPreparator = mimeMessage -> {
mimeMessage.setSubject("[NTOU Auction] 訂單成立通知", "UTF-8");
mimeMessage.setRecipient(Message.RecipientType.TO,
new InternetAddress(customer.getEmail()));
mimeMessage.setFrom(new InternetAddress(appConfig.getMailUsername()));
mimeMessage.setText("親愛的 " + customer.getName()
+ " (@" + customer.getUsername() + ") 您好:" + "\n"
+ "您已成功購買賣家為 @" + seller.getUsername() + " 的商品,"
+ "您這次購買了 " + order.getProductAddAmountList().size() + " 個品項的商品" + "\n"
+ "目前訂單狀態為等待賣家確認,訂單詳細資訊請上NTOU Auction確認。" + "\n\n"
+ "感謝您使用 NTOU Auction,祝您購物愉快!" + "\n\n"
+ "此為系統自動發送之郵件,請勿回覆!", "UTF-8"

);
mimeMessage.setSentDate(new Date());
};

MimeMessagePreparator sellerPreparator = mimeMessage -> {
mimeMessage.setSubject("[NTOU Auction] 訂單成立通知", "UTF-8");
mimeMessage.setRecipient(Message.RecipientType.TO,
new InternetAddress(seller.getEmail()));
mimeMessage.setFrom(new InternetAddress(appConfig.getMailUsername()));
mimeMessage.setText("親愛的 " + seller.getName()
+ " (@" + seller.getUsername() + ") 您好:" + "\n"
+ "買家 @" + customer.getUsername() + " 已下訂您的商品,"
+ "目前訂單狀態為等待確認,請您盡快上NTOU Auction更新訂單狀態。" + "\n\n"
+ "感謝您使用 NTOU Auction,祝您交易愉快!" + "\n\n"
+ "此為系統自動發送之郵件,請勿回覆!", "UTF-8"

);
mimeMessage.setSentDate(new Date());
};

try {
this.mailSender.send(buyerPreparator);
this.mailSender.send(sellerPreparator);
} catch (MailException ex) {
System.err.println(ex.getMessage());
}
}

public void sendMailOrderUpdate(Long userId, Order order) {

if (userService.get(userId).isEmpty() || userService.get(order.getSellerid()).isEmpty()) {
System.err.println("找不到ID為 " + userId + " 的使用者,或查無賣家,無法寄出訂單狀態更新通知");
return;
}
User customer = userService.get(userId).get();
User seller = userService.get(order.getSellerid()).get();
String status;
if (order.getStatus() == 0L) {
status = "賣家拒絕您的訂單";
} else if (order.getStatus() == 2L) {
status = "賣家同意您的訂單";
} else {
status = "未知";
}

MimeMessagePreparator buyerPreparator = mimeMessage -> {
mimeMessage.setSubject("[NTOU Auction] 訂單狀態更新通知", "UTF-8");
mimeMessage.setRecipient(Message.RecipientType.TO,
new InternetAddress(customer.getEmail()));
mimeMessage.setFrom(new InternetAddress(appConfig.getMailUsername()));
mimeMessage.setText("親愛的 " + customer.getName()
+ " (@" + customer.getUsername() + ") 您好:" + "\n"
+ "您之前購買賣家為 @" + seller.getUsername() + " 的商品,"
+ "目前訂單狀態為 " + status + " ,訂單詳細資訊請上NTOU Auction確認。" + "\n\n"
+ "感謝您使用 NTOU Auction,祝您購物愉快!" + "\n\n"
+ "此為系統自動發送之郵件,請勿回覆!", "UTF-8"

);
mimeMessage.setSentDate(new Date());
};

try {
this.mailSender.send(buyerPreparator);
} catch (MailException ex) {
System.err.println(ex.getMessage());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import jakarta.validation.Valid;
import ntou.auction.spring.account.response.UserIdentity;
import ntou.auction.spring.account.service.UserService;
import ntou.auction.spring.mail.EmailService;
import ntou.auction.spring.order.entity.Order;
import ntou.auction.spring.order.request.AddOrderRequest;
import ntou.auction.spring.order.request.OperateOrderRequest;
Expand All @@ -28,7 +29,7 @@ public class OrderController {

private final ShoppingcartService shoppingcartService;
private final UserService userService;

private final EmailService emailService;
private final UserIdentity userIdentity;

private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
Expand All @@ -49,11 +50,12 @@ public class OrderController {

private static final Map<String, String> selfBuyingError = Collections.singletonMap("message", "不可以購買自己的商品");

public OrderController(OrderService orderService, ProductService productService, ShoppingcartService shoppingcartService, UserService userService, UserIdentity userIdentity) {
public OrderController(OrderService orderService, ProductService productService, ShoppingcartService shoppingcartService, UserService userService, EmailService emailService, UserIdentity userIdentity) {
this.orderService = orderService;
this.productService = productService;
this.shoppingcartService = shoppingcartService;
this.userService = userService;
this.emailService = emailService;
this.userIdentity = userIdentity;
}

Expand Down Expand Up @@ -137,8 +139,8 @@ ResponseEntity<Map<String, String>> addOrder(@Valid @RequestBody AddOrderRequest

// checkInShoppingCart -> -1: format error, 0: false, 1: true
Long checkInShoppingCart = shoppingcartService.checkIsProductAllInShoppingCart(getrequest, userId);
if(checkInShoppingCart.equals(-1L)) return ResponseEntity.badRequest().body(formatError);
if(checkInShoppingCart.equals(0L)) return ResponseEntity.badRequest().body(notFoundInShoppingCartError);
if (checkInShoppingCart.equals(-1L)) return ResponseEntity.badRequest().body(formatError);
if (checkInShoppingCart.equals(0L)) return ResponseEntity.badRequest().body(notFoundInShoppingCartError);

for (List<Long> eachProductAddAmount : getrequest) {
Long productId = eachProductAddAmount.get(0);
Expand All @@ -153,11 +155,11 @@ ResponseEntity<Map<String, String>> addOrder(@Valid @RequestBody AddOrderRequest

// Same seller
boolean checkSameSeller = orderService.checkIsSameSeller(getrequest);
if(!checkSameSeller) return ResponseEntity.badRequest().body(tooManySellerMessage);
if (!checkSameSeller) return ResponseEntity.badRequest().body(tooManySellerMessage);

// Self buying
boolean checkSelfBuying = shoppingcartService.checkIsViolateSelfBuying(getrequest, userId);
if(checkSelfBuying) return ResponseEntity.badRequest().body(selfBuyingError);
if (checkSelfBuying) return ResponseEntity.badRequest().body(selfBuyingError);

// order status -> 0: reject, 1: waiting for submit, 2: submitted but not paid, 3: order done
Order order = new Order();
Expand Down Expand Up @@ -186,6 +188,7 @@ ResponseEntity<Map<String, String>> addOrder(@Valid @RequestBody AddOrderRequest
shoppingcartService.decreaseProductByUserId(userId, productId, amount);
}
orderService.addOrder(order);
emailService.sendMailOrderEstablished(order.getBuyerid(),order);
return ResponseEntity.ok(successMessage);
}

Expand Down Expand Up @@ -244,7 +247,7 @@ ResponseEntity<Map<String, String>> makeCancel(@Valid @RequestBody OperateOrderR
if (result.equals(-1L)) return ResponseEntity.badRequest().body(expiredError);
Order thisOrder = orderService.findOrderById(orderId);
boolean check = orderService.addAmountToProduct(thisOrder);
if(!check) return ResponseEntity.badRequest().body(orderNotFound); // this may not be happened
if (!check) return ResponseEntity.badRequest().body(orderNotFound); // this may not be happened
return ResponseEntity.ok(successMessage);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ntou.auction.spring.order.service;

import ntou.auction.spring.mail.EmailService;
import ntou.auction.spring.order.entity.Order;
import ntou.auction.spring.order.response.OrderWithProductDetail;
import ntou.auction.spring.order.repository.OrderRepository;
Expand All @@ -20,13 +21,15 @@ public class OrderService {
private final ProductService productService;

private final ShoppingcartService shoppingcartService;
private final EmailService emailService;

private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

public OrderService(OrderRepository repository, ProductService productService, ShoppingcartService shoppingcartService) {
public OrderService(OrderRepository repository, ProductService productService, ShoppingcartService shoppingcartService, EmailService emailService) {
this.repository = repository;
this.productService = productService;
this.shoppingcartService = shoppingcartService;
this.emailService = emailService;
}
public Order findOrderById(Long Id) {
return repository.findById(Id).orElse(null);
Expand Down Expand Up @@ -68,6 +71,7 @@ public Long submitOrder(Long orderId, Long userId) {
if(!Objects.equals(findOrderById(orderId).getSellerid(), userId)) return 2L;
getorder.setStatus(2L);
repository.save(getorder);
emailService.sendMailOrderUpdate(getorder.getBuyerid(),getorder);
return 3L;
}

Expand All @@ -80,6 +84,7 @@ public Long rejectOrder(Long orderId, Long userId) {
if(!Objects.equals(findOrderById(orderId).getSellerid(), userId)) return 2L;
getorder.setStatus(0L);
repository.save(getorder);
emailService.sendMailOrderUpdate(getorder.getBuyerid(),getorder);
return 3L;
}

Expand Down
Loading

0 comments on commit 34f2707

Please sign in to comment.