Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

write CourseController.java #84

Merged
merged 1 commit into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/main/java/com/backend/elearning/configuration/VNPayConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,25 @@ public Map<String, String> getVNPayConfig(PaymentRequestVM request) {
vnpParamsMap.put("vnp_ExpireDate", vnp_ExpireDate);
return vnpParamsMap;
}

public Map<String, String> getVNPayConfigForAndroid(PaymentRequestVM request) {
Map<String, String> vnpParamsMap = new HashMap<>();
vnpParamsMap.put("vnp_Version", this.vnp_Version);
vnpParamsMap.put("vnp_Command", this.vnp_Command);
vnpParamsMap.put("vnp_TmnCode", this.vnp_TmnCode);
vnpParamsMap.put("vnp_CurrCode", "VND");
vnpParamsMap.put("vnp_TxnRef", VNPayUtils.getRandomNumber(8));
vnpParamsMap.put("vnp_OrderInfo", request.orderId().toString());
vnpParamsMap.put("vnp_OrderType", this.orderType);
vnpParamsMap.put("vnp_Locale", "vn");
vnpParamsMap.put("scheme", "resultactivity");
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Etc/GMT+7"));
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
String vnpCreateDate = formatter.format(calendar.getTime());
vnpParamsMap.put("vnp_CreateDate", vnpCreateDate);
calendar.add(Calendar.MINUTE, 15);
String vnp_ExpireDate = formatter.format(calendar.getTime());
vnpParamsMap.put("vnp_ExpireDate", vnp_ExpireDate);
return vnpParamsMap;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ ResponseEntity<AuthenticationVm> outboundAuthenticate(
return ResponseEntity.ok().body(result);
}

@PostMapping("/outbound/authentication/mobile")
ResponseEntity<AuthenticationVm> outboundAuthenticateForMobile(
@RequestBody OutboundUserRequest request
){
AuthenticationVm result = authenticationService.outboundAuthenticateForMobile(request);
return ResponseEntity.ok().body(result);
}



@PostMapping("/login")
Expand All @@ -61,4 +69,16 @@ public ResponseEntity<AuthenticationVm> register (
.body(response);
}

@PostMapping("/verify")
public ResponseEntity<String> verfify (
@RequestParam String code
) {
if (authenticationService.verify(code)) {
return ResponseEntity.ok()
.body("Verify Success");
}
return ResponseEntity.badRequest()
.body("Verify Fail");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.backend.elearning.exception.NotFoundException;
import com.backend.elearning.security.JWTUtil;
import com.backend.elearning.utils.Constants;
import com.backend.elearning.utils.RandomString;
import jakarta.mail.MessagingException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
Expand Down Expand Up @@ -146,13 +147,25 @@ public AuthenticationVm register(RegistrationPostVm request) {
.lastName(request.lastName())
.email(request.email())
.photo("")
.active(false)
.build());
String randomCode = RandomString.make(64);
student.setVerificationCode(randomCode);
String token = jwtUtil.issueToken(student.getEmail(), ERole.ROLE_STUDENT.name());
UserVm userVm = UserVm.fromModelStudent(student);
AuthenticationVm authenticationVm = new AuthenticationVm(token, userVm);
return authenticationVm ;
}

public boolean verify(String verificationCode) {
Optional<Student> studentOptional = studentRepository.findByVerificationCode(verificationCode);
if (studentOptional.isPresent()) {
studentOptional.get().setActive(true);
return true;
}
return false ;
}

public void forgotPassword(String email) {
Optional<Student> studentOptional = studentRepository.findByEmail(email);
if (!studentOptional.isPresent()) {
Expand Down Expand Up @@ -187,4 +200,19 @@ public void updatePassword(AuthenticationPostVm request) {
throw e; // Rethrow the exception if needed
}
}

public AuthenticationVm outboundAuthenticateForMobile(OutboundUserRequest userInfo) {
Student student = studentRepository.findByEmail(userInfo.email()).orElseGet(
() -> studentRepository.saveAndFlush(Student.builder()
.active(true)
.firstName(userInfo.familyName())
.lastName(userInfo.givenName())
.email(userInfo.email())
.photo(userInfo.picture())
.build()));
String token = jwtUtil.issueToken(student.getEmail(), ERole.ROLE_STUDENT.name());
UserVm userVm = UserVm.fromModelStudent(student);
AuthenticationVm authenticationVm = new AuthenticationVm(token, userVm);
return authenticationVm ;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.backend.elearning.domain.auth;

public record OutboundUserRequest(String email, String givenName, String familyName, String picture) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,24 @@ public ResponseEntity<List<CourseListGetVM>> getPageableCourse (
}


// @GetMapping("/courses/search")
// public ResponseEntity<PageableData<CourseListGetVM>> getCoursesByMultiQueryWithPageable (
// @RequestParam(value = "pageNum", defaultValue = Constants.PageableConstant.DEFAULT_PAGE_NUMBER, required = false) int pageNum,
// @RequestParam(value = "pageSize", defaultValue = Constants.PageableConstant.DEFAULT_PAGE_SIZE, required = false) int pageSize,
// @RequestParam(value = "keyword", required = false) String keyword,
// @RequestParam(value = "ratingStar", required = false) Float rating,
// @RequestParam(value = "level", required = false) String[] level,
// @RequestParam(value = "free", required = false) Boolean[] free,
// @RequestParam(value = "categoryName", required = false) String categoryName,
// @RequestParam(value = "topicId", required = false) Integer topicId
// ) {
// PageableData<CourseListGetVM> pageableCourses = courseService.getCoursesByMultiQuery(pageNum, pageSize, keyword, rating, level, free, categoryName, topicId);
// return ResponseEntity.ok().body(pageableCourses);
// }


@GetMapping("/courses/search")
public ResponseEntity<PageableData<CourseListGetVM>> getCoursesByMultiQuery (
public ResponseEntity<List<CourseListGetVM>> getCoursesByMultiQuery (
@RequestParam(value = "pageNum", defaultValue = Constants.PageableConstant.DEFAULT_PAGE_NUMBER, required = false) int pageNum,
@RequestParam(value = "pageSize", defaultValue = Constants.PageableConstant.DEFAULT_PAGE_SIZE, required = false) int pageSize,
@RequestParam(value = "keyword", required = false) String keyword,
Expand All @@ -55,9 +71,9 @@ public ResponseEntity<PageableData<CourseListGetVM>> getCoursesByMultiQuery (
@RequestParam(value = "free", required = false) Boolean[] free,
@RequestParam(value = "categoryName", required = false) String categoryName,
@RequestParam(value = "topicId", required = false) Integer topicId
) {
PageableData<CourseListGetVM> pageableCourses = courseService.getCoursesByMultiQuery(pageNum, pageSize, keyword, rating, level, free, categoryName, topicId);
return ResponseEntity.ok().body(pageableCourses);
) {
List<CourseListGetVM> coursesByMultiQueryReturnList = courseService.getCoursesByMultiQueryReturnList(pageNum, pageSize, keyword, rating, level, free, categoryName, topicId);
return ResponseEntity.ok().body(coursesByMultiQueryReturnList);
}

@PostMapping("/admin/courses")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ PageableData<CourseListGetVM> getCoursesByMultiQuery(int pageNum,
Integer topicId
);


List<CourseListGetVM> getCoursesByMultiQueryReturnList(int pageNum,
int pageSize,
String title,
Float rating,
String[] level,
Boolean[] free,
String categoryName,
Integer topicId
);

List<CourseListGetVM> getCoursesByCategoryId(Integer categoryId);

void delete(Long id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,34 @@ public PageableData<CourseListGetVM> getCoursesByMultiQuery(int pageNum,
);
}

@Override
public List<CourseListGetVM> getCoursesByMultiQueryReturnList(int pageNum, int pageSize, String title, Float rating, String[] level, Boolean[] free, String categoryName, Integer topicId) {
List<Course> courses = title != null ? courseRepository.findByMultiQueryWithKeyword(title, rating, level, free, categoryName, topicId) :
courseRepository.findByMultiQuery(rating, level, free, categoryName, topicId);
List<CourseListGetVM> courseListGetVMS = courses.stream().map(course -> {
List<Review> reviews = course.getReviews();
int ratingCount = reviews.size();
Double averageRating = reviews.stream().map(review -> review.getRatingStar()).mapToDouble(Integer::doubleValue).average().orElse(0.0);
double roundedAverageRating = Math.round(averageRating * 10) / 10.0;
AtomicInteger totalCurriculumCourse = new AtomicInteger();
AtomicInteger totalDurationCourse = new AtomicInteger();
List<Section> sections = sectionService.findByCourseId(course.getId());
sections.forEach(section -> {
List<Lecture> lectures = section.getLectures();
List<Quiz> quizzes = section.getQuizzes();
totalCurriculumCourse.addAndGet(lectures.size());
totalCurriculumCourse.addAndGet(quizzes.size());
int totalSeconds = lectures.stream()
.mapToInt(lecture -> lecture.getDuration())
.sum();
totalDurationCourse.addAndGet(totalSeconds);
});
String formattedHours = convertSeconds(totalDurationCourse.get());
return CourseListGetVM.fromModel(course, formattedHours, totalCurriculumCourse.get(), roundedAverageRating, ratingCount);
}).toList();
return courseListGetVMS;
}

@Override
public List<CourseListGetVM> getCoursesByCategoryId(Integer categoryId) {
List<Course> courses = courseRepository.findByCategoryIdWithStatus(categoryId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public ResponseEntity<Media> save (@RequestParam("file") MultipartFile multipart
return ResponseEntity.ok().body(media);
}



@PutMapping("/{id}")
public ResponseEntity<Media> update (@RequestParam("file")MultipartFile multipartFile,
@PathVariable("id") String id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ public PaymentController(PaymentService paymentService) {
public ResponseEntity<PaymentVM.VNPayResponse> pay(@RequestBody PaymentRequestVM request, HttpServletRequest httpServletRequest) {
return ResponseEntity.ok().body(paymentService.createVNPayPayment(request, httpServletRequest));
}

@PostMapping("/vn-pay/mobile")
public ResponseEntity<PaymentVM.VNPayResponse> payForMobile(@RequestBody PaymentRequestVM request, HttpServletRequest httpServletRequest) {
return ResponseEntity.ok().body(paymentService.createVNPayPaymentMobile(request, httpServletRequest));
}
@GetMapping("/vn-pay-callback")
public ResponseEntity<PaymentVM.VNPayResponse> payCallbackHandler(@RequestParam String vnp_ResponseCode) {
if (vnp_ResponseCode.equals("00")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@
public interface PaymentService {
PaymentVM.VNPayResponse createVNPayPayment(PaymentRequestVM request, HttpServletRequest httpServletRequest);

PaymentVM.VNPayResponse createVNPayPaymentMobile(PaymentRequestVM request, HttpServletRequest httpServletRequest);


void savePayment(PaymentPostVM request);
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,27 @@ public PaymentVM.VNPayResponse createVNPayPayment(PaymentRequestVM request, Http
.paymentUrl(paymentUrl).build();
}

@Override
public PaymentVM.VNPayResponse createVNPayPaymentMobile(PaymentRequestVM request, HttpServletRequest httpServletRequest) {
long amount = request.amount() * 100L;
String bankCode = request.bankCode();
Map<String, String> vnpParamsMap = vnPayConfig.getVNPayConfigForAndroid(request);
vnpParamsMap.put("vnp_Amount", String.valueOf(amount));
if (bankCode != null && !bankCode.isEmpty()) {
vnpParamsMap.put("vnp_BankCode", bankCode);
}
vnpParamsMap.put("vnp_IpAddr", VNPayUtils.getIpAddress(httpServletRequest));
//build query url
String queryUrl = VNPayUtils.getPaymentURL(vnpParamsMap, true);
String hashData = VNPayUtils.getPaymentURL(vnpParamsMap, false);
queryUrl += "&vnp_SecureHash=" + VNPayUtils.hmacSHA512(vnPayConfig.getSecretKey(), hashData);
String paymentUrl = vnPayConfig.getVnp_PayUrl() + "?" + queryUrl;
return PaymentVM.VNPayResponse.builder()
.code("ok")
.message("success")
.paymentUrl(paymentUrl).build();
}

@Override
public void savePayment(PaymentPostVM request) {
Order order = orderRepository.findById(request.orderId()).orElseThrow(() -> new NotFoundException(Constants.ERROR_CODE.ORDER_NOT_FOUND, request.orderId()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public class Student extends AbstractAuditEntity implements UserDetails {

private LocalDate dateOfBirth;

private String verificationCode;

@OneToMany(mappedBy = "student", cascade = CascadeType.ALL, orphanRemoval = true)
@Builder.Default
private List<LearningCourse> learningCourses = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
@Repository
public interface StudentRepository extends JpaRepository<Student, Long> {
Optional<Student> findByEmail(String email);


Optional<Student> findByVerificationCode(String verificationCode);
@Query("""
select count(1)
from Student
Expand Down
107 changes: 107 additions & 0 deletions src/main/java/com/backend/elearning/utils/RandomString.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package com.backend.elearning.utils;

import java.util.Random;

public class RandomString {
public static final int DEFAULT_LENGTH = 8;

/**
* The symbols which are used to create a random {@link java.lang.String}.
*/
private static final char[] SYMBOL;

/**
* The amount of bits to extract out of an integer for each key generated.
*/
private static final int KEY_BITS;

/*
* Creates the symbol array.
*/
static {
StringBuilder symbol = new StringBuilder();
for (char character = '0'; character <= '9'; character++) {
symbol.append(character);
}
for (char character = 'a'; character <= 'z'; character++) {
symbol.append(character);
}
for (char character = 'A'; character <= 'Z'; character++) {
symbol.append(character);
}
SYMBOL = symbol.toString().toCharArray();
int bits = Integer.SIZE - Integer.numberOfLeadingZeros(SYMBOL.length);
KEY_BITS = bits - (Integer.bitCount(SYMBOL.length) == bits ? 0 : 1);
}

/**
* A provider of random values.
*/
private final Random random;

/**
* The length of the random strings that are created by this instance.
*/
private final int length;


public RandomString() {
this(DEFAULT_LENGTH);
}

/**
* Creates a random {@link java.lang.String} provider where each value is of the given length.
*
* @param length The length of the random {@link String}.
*/
public RandomString(int length) {
if (length <= 0) {
throw new IllegalArgumentException("A random string's length cannot be zero or negative");
}
this.length = length;
random = new Random();
}


public static String make() {
return make(DEFAULT_LENGTH);
}

/**
* Creates a random {@link java.lang.String} of the given {@code length}.
*
* @param length The length of the random {@link String}.
* @return A random {@link java.lang.String}.
*/
public static String make(int length) {
return new RandomString(length).nextString();
}

/**
* Represents an integer value as a string hash. This string is not technically random but generates a fixed character
* sequence based on the hash provided.
*
* @param value The value to represent as a string.
* @return A string representing the supplied value as a string.
*/
public static String hashOf(int value) {
char[] buffer = new char[(Integer.SIZE / KEY_BITS) + ((Integer.SIZE % KEY_BITS) == 0 ? 0 : 1)];
for (int index = 0; index < buffer.length; index++) {
buffer[index] = SYMBOL[(value >>> index * KEY_BITS) & (-1 >>> (Integer.SIZE - KEY_BITS))];
}
return new String(buffer);
}

/**
* Creates a new random {@link java.lang.String}.
*
* @return A random {@link java.lang.String} of the given length for this instance.
*/
public String nextString() {
char[] buffer = new char[length];
for (int index = 0; index < length; index++) {
buffer[index] = SYMBOL[random.nextInt(SYMBOL.length)];
}
return new String(buffer);
}
}
Loading