Merge branch 'backend' of https://github.com/TeamBNBN/edufocus into be/Quiz
This commit is contained in:
commit
10ef02eaf4
@ -2,7 +2,9 @@ package com.edufocus.edufocus;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
|
||||
|
||||
@EnableJpaAuditing
|
||||
@SpringBootApplication
|
||||
public class EdufocusApplication {
|
||||
|
||||
|
@ -5,7 +5,7 @@ import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.LocalTime;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
@ -17,6 +17,6 @@ public class ResponseBoardDetailDto {
|
||||
private String title;
|
||||
private String content;
|
||||
private int viewCount;
|
||||
private LocalTime createdAt;
|
||||
private LocalTime modifiedAt;
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime modifiedAt;
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
@Setter
|
||||
@ -12,4 +14,5 @@ public class ResponseBoardSummaryDto {
|
||||
private long id;
|
||||
private String name;
|
||||
private String title;
|
||||
private LocalDateTime createdAt;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
|
||||
@Builder
|
||||
@ -13,6 +14,6 @@ public class ResponseCommentDto {
|
||||
private long id;
|
||||
private String name;
|
||||
private String content;
|
||||
private LocalTime createAt;
|
||||
private LocalTime modifiedAt;
|
||||
private LocalDateTime createAt;
|
||||
private LocalDateTime modifiedAt;
|
||||
}
|
||||
|
@ -8,8 +8,11 @@ import com.edufocus.edufocus.user.model.entity.User;
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.annotation.LastModifiedDate;
|
||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.List;
|
||||
|
||||
@ -18,6 +21,7 @@ import java.util.List;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Setter
|
||||
@EntityListeners(AuditingEntityListener.class)
|
||||
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
|
||||
public class Board {
|
||||
|
||||
@ -37,11 +41,11 @@ public class Board {
|
||||
@Column(nullable = true)
|
||||
private int viewCount;
|
||||
|
||||
@CreationTimestamp
|
||||
LocalTime createdAt;
|
||||
@CreatedDate
|
||||
LocalDateTime createdAt;
|
||||
|
||||
@CreationTimestamp
|
||||
LocalTime modifiedAt;
|
||||
@LastModifiedDate
|
||||
LocalDateTime modifiedAt;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "user_id")
|
||||
@ -60,6 +64,7 @@ public class Board {
|
||||
.id(id)
|
||||
.title(title)
|
||||
.name(user.getUserId())
|
||||
.createdAt(createdAt)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ import lombok.Builder;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.LocalTime;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Entity
|
||||
@Builder
|
||||
@ -26,10 +26,10 @@ public class Comment {
|
||||
private String content;
|
||||
|
||||
@Column
|
||||
private LocalTime createdAt;
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@Column
|
||||
private LocalTime modifiedAt;
|
||||
private LocalDateTime modifiedAt;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "user_id")
|
||||
|
@ -47,7 +47,7 @@ public class Lecture {
|
||||
@Column
|
||||
private String time;
|
||||
|
||||
@Column
|
||||
@Column(columnDefinition = "boolean default false")
|
||||
private boolean online;
|
||||
|
||||
}
|
||||
|
@ -26,4 +26,6 @@ public interface LectureService {
|
||||
List<LectureSearchResponse> findMyLecture(long userId);
|
||||
|
||||
Lecture findLectureByTitle(String title);
|
||||
|
||||
void changeState(Long lectureId);
|
||||
}
|
||||
|
@ -216,4 +216,28 @@ public class LectureServiceImpl implements LectureService {
|
||||
public Lecture findLectureByTitle(String title) {
|
||||
return lectureRepository.findByTitle(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeState(Long id) {
|
||||
|
||||
Optional<Lecture> lecture = lectureRepository.findById(id);
|
||||
|
||||
Lecture l;
|
||||
if(lecture.isPresent())
|
||||
{
|
||||
l = lecture.get();
|
||||
|
||||
System.out.println(l.isOnline());
|
||||
l.setOnline(true);
|
||||
System.out.println(l.isOnline());
|
||||
|
||||
|
||||
}else {
|
||||
|
||||
throw new RuntimeException("Lecture not found with id: " + id);
|
||||
}
|
||||
lectureRepository.save(l);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -106,9 +106,9 @@ public class QnaController {
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public ResponseEntity<Qna> getQna(@PathVariable Long id) {
|
||||
public ResponseEntity<QnaResponseDto> getQna(@PathVariable Long id) {
|
||||
try{
|
||||
Qna findQna= qnaService.getQna(id);
|
||||
QnaResponseDto findQna= qnaService.getQna(id);
|
||||
return new ResponseEntity<>(findQna, HttpStatus.ACCEPTED);
|
||||
|
||||
} catch (SQLException e) {
|
||||
|
@ -13,7 +13,6 @@ import java.util.List;
|
||||
@Repository
|
||||
public interface QnaRepository extends JpaRepository<Qna, Long> {
|
||||
|
||||
|
||||
List<Qna> findByLectureId(Long lecturerId);
|
||||
Page<Qna> findByLectureId(Long lectureId, Pageable pageable);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public interface QnaService {
|
||||
QnaResponseDto createQna(Long id, QnaRequestDto qnaRequestDto, Long lecture_id) throws SQLException;
|
||||
QnaResponseDto updateQna(Long id,QnaRequestDto qnaRequestDto) throws SQLException;
|
||||
void deleteQna(Long id) throws SQLException;
|
||||
Qna getQna(Long id) throws SQLException;
|
||||
QnaResponseDto getQna(Long id) throws SQLException;
|
||||
|
||||
List<QnaResponseDto> getAllQnasByLecture(Long lectureId,int pageNumber) throws SQLException;
|
||||
QnaResponseDto createAnswer(Long id,QnaRequestDto qnaRequestDto) throws SQLException;
|
||||
|
@ -80,8 +80,22 @@ qnaRepository.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Qna getQna(Long id) {
|
||||
return null;
|
||||
public QnaResponseDto getQna(Long id) {
|
||||
Optional<Qna> qna;
|
||||
try {
|
||||
|
||||
qna= qnaRepository.findById(id);
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
throw new RuntimeException("Qna 없음 " + id, e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return QnaResponseDto.toEntity(qna.get());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.edufocus.edufocus.registration.service;
|
||||
|
||||
import com.edufocus.edufocus.registration.entity.Registration;
|
||||
import com.edufocus.edufocus.registration.entity.RegistrationStatus;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@ -12,4 +13,5 @@ public interface RegistrationService {
|
||||
|
||||
boolean deleteRegistration(long userId, long registrationId);
|
||||
|
||||
RegistrationStatus isOnline(Long userId , Long lectureId);
|
||||
}
|
||||
|
@ -62,4 +62,11 @@ public class RegistrationServiceImpl implements RegistrationService {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegistrationStatus isOnline(Long userId, Long lectureId) {
|
||||
|
||||
Registration registration = registrationRepository.findByUserIdAndLectureId(userId,lectureId);
|
||||
return registration.getStatus();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ public class WebConfiguration implements WebMvcConfigurer {
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry
|
||||
.addMapping("/**")
|
||||
.allowedOrigins("http://i11a701.p.ssafy.io/", "http://localhost:5173", "http://localhost:4173")
|
||||
.allowedOrigins("http://i11a701.p.ssafy.io/", "http://localhost:5173", "http://localhost:4173","http://localhost:5080")
|
||||
.allowedMethods(HttpMethod.GET.name(), HttpMethod.POST.name(), HttpMethod.PUT.name(),
|
||||
HttpMethod.DELETE.name(), HttpMethod.HEAD.name(), HttpMethod.OPTIONS.name(),
|
||||
HttpMethod.PATCH.name())
|
||||
@ -45,7 +45,7 @@ public class WebConfiguration implements WebMvcConfigurer {
|
||||
registry.addInterceptor(jwtInterceptor)
|
||||
|
||||
.addPathPatterns("/**") // 모든 경로에 대해 인터셉터 적용
|
||||
.excludePathPatterns("/v3/api-docs/**","/swagger-resources/**","/webjars/**","/swagger-ui/**","/auth/**", "/board/**", "/user/**","/lecture/**","/qna/**", "/quiz/**"); // 인증 없이 접근 가능한 경로 설정
|
||||
.excludePathPatterns("/v3/api-docs/**","/swagger-resources/**","/webjars/**","/swagger-ui/**","/auth/**", "/board/**", "/user/**","/lecture/**","/qna/**", "/quiz/**","/video/**","/registration/**"); // 인증 없이 접근 가능한 경로 설정
|
||||
|
||||
///v3/api-docs/**, /swagger-resources/**, /webjars/**
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
package com.edufocus.edufocus.user.model.entity;
|
||||
|
||||
public class InfoDto {
|
||||
|
||||
String name;
|
||||
String email;
|
||||
|
||||
}
|
@ -12,4 +12,7 @@ public interface UserService {
|
||||
void sendEamail(User user) throws Exception;
|
||||
void userCheck(Long id) throws Exception;
|
||||
String getUserName(Long id) throws Exception;
|
||||
void changeuInfo(Long id) throws Exception;
|
||||
void changePassword(Long id) throws Exception;
|
||||
|
||||
}
|
||||
|
@ -143,6 +143,16 @@ public class UserServiceImpl implements UserService{
|
||||
return userRepository.findById(id).get().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeuInfo(Long id) throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changePassword(Long id) throws Exception {
|
||||
|
||||
}
|
||||
|
||||
public String getTempPassword() {
|
||||
char[] charSet = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
|
||||
'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
|
||||
|
@ -1,20 +1,38 @@
|
||||
package com.edufocus.edufocus.video.controller;
|
||||
|
||||
import io.livekit.server.AccessToken;
|
||||
import io.livekit.server.RoomJoin;
|
||||
import io.livekit.server.RoomName;
|
||||
import io.livekit.server.WebhookReceiver;
|
||||
import livekit.LivekitWebhook.WebhookEvent;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@CrossOrigin(origins = "*")
|
||||
@RestController
|
||||
public class Controller {
|
||||
import com.edufocus.edufocus.lecture.entity.Lecture;
|
||||
import com.edufocus.edufocus.lecture.entity.LectureDetailResponse;
|
||||
import com.edufocus.edufocus.lecture.service.LectureService;
|
||||
import com.edufocus.edufocus.registration.entity.RegistrationStatus;
|
||||
import com.edufocus.edufocus.registration.service.RegistrationService;
|
||||
import com.edufocus.edufocus.user.model.service.UserService;
|
||||
import com.edufocus.edufocus.user.util.JWTUtil;
|
||||
import com.edufocus.edufocus.video.service.VideoSertvice;
|
||||
import io.livekit.server.*;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import livekit.LivekitWebhook.WebhookEvent;
|
||||
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/video")
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
|
||||
public class Controller {
|
||||
private final JWTUtil jwtUtil;
|
||||
private final UserService userService;
|
||||
private final LectureService lectureService;
|
||||
private final VideoSertvice videoSertvice;
|
||||
private final RegistrationService registrationService;
|
||||
@Value("${livekit.api.key}")
|
||||
private String LIVEKIT_API_KEY;
|
||||
|
||||
@ -25,47 +43,102 @@ public class Controller {
|
||||
* @param params JSON object with roomName and participantName
|
||||
* @return JSON object with the JWT token
|
||||
*/
|
||||
@PostMapping(value = "/token")
|
||||
public ResponseEntity<Map<String, String>> createToken(@RequestBody Map<String, String> params) {
|
||||
String roomName = params.get("roomName");
|
||||
String participantName = params.get("participantName");
|
||||
// @PostMapping(value = "/token")
|
||||
// public ResponseEntity<Map<String, String>> createToken(@RequestBody Map<String, String> params) {
|
||||
// String roomName = params.get("roomName");
|
||||
// String participantName = params.get("participantName");
|
||||
//
|
||||
// if (roomName == null || participantName == null) {
|
||||
// return ResponseEntity.badRequest().body(Map.of("errorMessage", "roomName and participantName are required"));
|
||||
// }
|
||||
//
|
||||
// AccessToken token = new AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET);
|
||||
// token.setName(participantName);
|
||||
// token.setIdentity(participantName);
|
||||
// token.addGrants(new RoomJoin(true), new RoomName(roomName));
|
||||
//
|
||||
//
|
||||
//
|
||||
// return ResponseEntity.ok(Map.of("token", token.toJwt()));
|
||||
// }
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
@PostMapping(value = "/makeroom/{lecture_id}")
|
||||
public ResponseEntity<Map<String, String>> startLecture(@PathVariable("lecture_id") Long id, HttpServletRequest request) throws Exception {
|
||||
|
||||
String userToken = request.getHeader("Authorization");
|
||||
log.info("userToekn : ", userToken);
|
||||
|
||||
|
||||
Long userId = Long.parseLong(jwtUtil.getUserId(userToken));
|
||||
LectureDetailResponse lecture= lectureService.findLectureById(userId,id);
|
||||
|
||||
String roomName = lecture.getTitle();
|
||||
String participantName = userService.getUserName(userId);
|
||||
|
||||
if (roomName == null || participantName == null) {
|
||||
return ResponseEntity.badRequest().body(Map.of("errorMessage", "roomName and participantName are required"));
|
||||
}
|
||||
|
||||
AccessToken token = new AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET);
|
||||
|
||||
|
||||
token.setName(participantName);
|
||||
token.setIdentity(participantName);
|
||||
token.addGrants(new RoomJoin(true), new RoomName(roomName));
|
||||
token.addGrants(new RoomJoin(true), new RoomName(roomName),new RoomCreate(true));
|
||||
|
||||
videoSertvice.startOnline(userId,id);
|
||||
|
||||
|
||||
// 방이름으로 입장하는건데
|
||||
// 만약 수강생에 DB에 신청한 강의명이 없다면 들어갈수 없음
|
||||
// 검증 로직만 추가하면 될듯?
|
||||
|
||||
|
||||
return ResponseEntity.ok(Map.of("token", token.toJwt()));
|
||||
}
|
||||
|
||||
@PostMapping(value = "/webhook", consumes = "application/webhook+json")
|
||||
public ResponseEntity<String> receiveWebhook(@RequestHeader("Authorization") String authHeader, @RequestBody String body) {
|
||||
WebhookReceiver webhookReceiver = new WebhookReceiver(LIVEKIT_API_KEY, LIVEKIT_API_SECRET);
|
||||
try {
|
||||
WebhookEvent event = webhookReceiver.receive(body, authHeader);
|
||||
System.out.println("LiveKit Webhook: " + event.toString());
|
||||
} catch (Exception e) {
|
||||
System.err.println("Error validating webhook event: " + e.getMessage());
|
||||
}
|
||||
return ResponseEntity.ok("ok");
|
||||
|
||||
@PostMapping(value = "/joinroom/{lecture_id}")
|
||||
public ResponseEntity<Map<String, String>> joinRoom(@PathVariable("lecture_id") Long id, HttpServletRequest request) throws Exception {
|
||||
|
||||
String userToken = request.getHeader("Authorization");
|
||||
|
||||
Long userId = Long.parseLong(jwtUtil.getUserId(userToken));
|
||||
LectureDetailResponse lecture= lectureService.findLectureById(userId,id);
|
||||
|
||||
|
||||
//RegistrationStatus registrationStatus = registrationService.isOnline(userId,id);
|
||||
|
||||
// if(registrationStatus==RegistrationStatus.ACCEPTED)
|
||||
// {
|
||||
String roomName = lecture.getTitle();
|
||||
String participantName = userService.getUserName(userId);
|
||||
|
||||
|
||||
AccessToken token = new AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET);
|
||||
token.setName(participantName);
|
||||
token.setIdentity(participantName);
|
||||
token.addGrants(new RoomJoin(true), new RoomName(roomName));
|
||||
|
||||
//videoSertvice.startOnline(userId,id);
|
||||
|
||||
|
||||
|
||||
return ResponseEntity.ok(Map.of("token", token.toJwt()));
|
||||
// }
|
||||
// else{
|
||||
// return ResponseEntity.status(HttpStatus.FORBIDDEN).body(Map.of("errorMessage", "Not accepted"));
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@PostMapping(value = "/livekit/webhook", consumes = "application/webhook+json")
|
||||
public ResponseEntity<String> receiveWebhook(@RequestHeader("Authorization") String authHeader, @RequestBody String body) {
|
||||
WebhookReceiver webhookReceiver = new WebhookReceiver(LIVEKIT_API_KEY, LIVEKIT_API_SECRET);
|
||||
try {
|
||||
WebhookEvent event = webhookReceiver.receive(body, authHeader);
|
||||
System.out.println("LiveKit Webhook: " + event.toString());
|
||||
} catch (Exception e) {
|
||||
System.err.println("Error validating webhook event: " + e.getMessage());
|
||||
}
|
||||
return ResponseEntity.ok("ok");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
package com.edufocus.edufocus.video.service;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
public interface VideoSertvice {
|
||||
|
||||
void startOnline(Long userId,Long lectureId) throws SQLException;
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.edufocus.edufocus.video.service;
|
||||
|
||||
import com.edufocus.edufocus.lecture.entity.Lecture;
|
||||
import com.edufocus.edufocus.lecture.service.LectureService;
|
||||
import jakarta.transaction.Transactional;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.sql.SQLException;
|
||||
@Service
|
||||
@Transactional
|
||||
@RequiredArgsConstructor
|
||||
public class VideoServiceImpl implements VideoSertvice{
|
||||
|
||||
private final LectureService lectureService;
|
||||
@Override
|
||||
public void startOnline(Long userId,Long lectureId) throws SQLException {
|
||||
|
||||
lectureService.changeState(lectureId);
|
||||
}
|
||||
}
|
@ -4,6 +4,9 @@ server.port=8080
|
||||
server.ssl.enabled=false
|
||||
server.servlet.context-path=${CONTEXT_PATH}
|
||||
|
||||
# openvidu
|
||||
#server.port=${SERVER_PORT:6080}
|
||||
|
||||
|
||||
# LiveKit configuration
|
||||
livekit.api.key=${LIVEKIT_API_KEY:devkey}
|
||||
|
Loading…
Reference in New Issue
Block a user