Skip to content

Commit

Permalink
update :: resolve conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
JuuuuHong committed Sep 1, 2024
2 parents 9074f6b + 90e19ca commit 74eea67
Show file tree
Hide file tree
Showing 7 changed files with 226 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,10 @@ class AdminController(
adminService.downloadClubStatusExcel(response)
return ResponseEntity.ok().build()
}

@PostMapping("/lecture/excel")
fun uploadLectureListExcel(@RequestPart file: MultipartFile): ResponseEntity<Unit> {
adminService.uploadLectureListExcel(file)
return ResponseEntity.status(HttpStatus.CREATED).build()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ interface AdminService {
fun uploadStudentListExcel(file: MultipartFile)
fun uploadClubListExcel(file: MultipartFile)
fun downloadClubStatusExcel(response: HttpServletResponse)
fun uploadLectureListExcel(file: MultipartFile)
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
package team.msg.domain.admin.service

import javax.servlet.http.HttpServletResponse
import org.apache.poi.common.usermodel.HyperlinkType
import org.apache.poi.hssf.usermodel.HSSFFont
import org.apache.poi.ss.usermodel.FillPatternType
import org.apache.poi.ss.usermodel.HorizontalAlignment
import org.apache.poi.ss.usermodel.IndexedColors
import org.apache.poi.ss.usermodel.VerticalAlignment
import org.apache.poi.ss.usermodel.WorkbookFactory
import org.apache.poi.xssf.usermodel.XSSFCellStyle
import org.apache.poi.xssf.usermodel.XSSFFont
import org.apache.poi.xssf.usermodel.XSSFHyperlink
import org.apache.poi.xssf.usermodel.XSSFRow
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import org.springframework.beans.factory.annotation.Value
import org.apache.poi.ss.usermodel.*
import org.apache.poi.xssf.usermodel.*
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import org.springframework.web.multipart.MultipartFile
import team.msg.common.enums.ApproveStatus
import team.msg.common.enums.Field
import team.msg.common.util.KakaoUtil
import team.msg.common.util.StudentUtil
import team.msg.common.util.UserUtil
import team.msg.domain.admin.exception.InvalidCellTypeException
Expand All @@ -28,21 +18,30 @@ import team.msg.domain.club.exception.ClubNotFoundException
import team.msg.domain.club.exception.InvalidFieldException
import team.msg.domain.club.model.Club
import team.msg.domain.club.repository.ClubRepository
import team.msg.domain.lecture.enums.Semester
import team.msg.domain.lecture.model.Lecture
import team.msg.domain.lecture.model.LectureDate
import team.msg.domain.lecture.model.LectureLocation
import team.msg.domain.lecture.repository.LectureDateRepository
import team.msg.domain.lecture.repository.LectureLocationRepository
import team.msg.domain.lecture.repository.LectureRepository
import team.msg.domain.school.exception.SchoolNotFoundException
import team.msg.domain.school.repository.SchoolRepository
import team.msg.domain.student.repository.StudentRepository
import team.msg.domain.user.enums.Authority
import team.msg.domain.user.exception.InvalidEmailException
import team.msg.domain.user.exception.InvalidPasswordException
import team.msg.domain.user.exception.InvalidPhoneNumberException
import team.msg.domain.user.exception.UserAlreadyApprovedException
import team.msg.domain.user.exception.*
import team.msg.domain.user.model.User
import team.msg.domain.user.presentation.data.response.UserResponse
import team.msg.domain.user.presentation.data.response.UsersResponse
import team.msg.domain.user.repository.UserRepository
import team.msg.global.config.properties.DomainProperties
import team.msg.global.exception.InternalServerException
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.format.DateTimeFormatter
import java.util.*
import javax.servlet.http.HttpServletResponse

@Service
class AdminServiceImpl(
Expand All @@ -52,7 +51,11 @@ class AdminServiceImpl(
private val clubRepository: ClubRepository,
private val studentRepository: StudentRepository,
private val schoolRepository: SchoolRepository,
private val domainProperties: DomainProperties
private val domainProperties: DomainProperties,
private val lectureRepository: LectureRepository,
private val lectureDateRepository: LectureDateRepository,
private val kakaoUtil: KakaoUtil,
private val lectureLocationRepository: LectureLocationRepository
) : AdminService {

/**
Expand Down Expand Up @@ -137,43 +140,43 @@ class AdminServiceImpl(
*/
@Transactional(rollbackFor = [Exception::class])
override fun uploadStudentListExcel(file: MultipartFile) {
file.inputStream.use {
val workbook = try {
WorkbookFactory.create(file.inputStream)
val workbook = file.inputStream.use {
try {
WorkbookFactory.create(it)
} catch (e: IndexOutOfBoundsException) {
throw InvalidCellTypeException("전화번호 셀 서식을 텍스트로 바꿔주세요.")
} catch (e: Exception) {
throw InternalServerException("엑셀 파일 처리 중 문제가 발생했습니다. info : [ errorMessage = ${e.message} ]")
}
}

val sheet = workbook.getSheetAt(0)
val sheet = workbook.getSheetAt(0)

sheet.forEachIndexed { index, row ->
if (index == 0)
return@forEachIndexed
sheet.forEachIndexed { index, row ->
if (index == 0)
return@forEachIndexed

if (row.getCell(0).stringCellValue == "")
return
if (row.getCell(0).stringCellValue == "")
return

val email = row.getCell(0).stringCellValue
val name = row.getCell(1).stringCellValue
val phoneNumber = row.getCell(2).stringCellValue
val password = row.getCell(3).stringCellValue
val clubName = row.getCell(4).stringCellValue
val grade = row.getCell(5).numericCellValue.toInt()
val classRoom = row.getCell(6).numericCellValue.toInt()
val number = row.getCell(7).numericCellValue.toInt()
val admissionNumber = row.getCell(8).numericCellValue.toInt()
val subscriptionGrade = row.getCell(9).numericCellValue.toInt()
val email = row.getCell(0).stringCellValue
val name = row.getCell(1).stringCellValue
val phoneNumber = row.getCell(2).stringCellValue
val password = row.getCell(3).stringCellValue
val clubName = row.getCell(4).stringCellValue
val grade = row.getCell(5).numericCellValue.toInt()
val classRoom = row.getCell(6).numericCellValue.toInt()
val number = row.getCell(7).numericCellValue.toInt()
val admissionNumber = row.getCell(8).numericCellValue.toInt()
val subscriptionGrade = row.getCell(9).numericCellValue.toInt()

validateExcelStudentData(email, phoneNumber, password)
validateExcelStudentData(email, phoneNumber, password)

val user = userUtil.createUser(email, name, phoneNumber, password, Authority.ROLE_STUDENT)
val user = userUtil.createUser(email, name, phoneNumber, password, Authority.ROLE_STUDENT)

val club = clubRepository findByName clubName
val club = clubRepository findByName clubName

studentUtil.createStudent(user, club, grade, classRoom, number, admissionNumber, subscriptionGrade)
}
studentUtil.createStudent(user, club, grade, classRoom, number, admissionNumber, subscriptionGrade)
}
}

Expand All @@ -183,49 +186,156 @@ class AdminServiceImpl(
*/
@Transactional(rollbackFor = [Exception::class])
override fun uploadClubListExcel(file: MultipartFile) {
file.inputStream.use {
val workbook = try {
WorkbookFactory.create(file.inputStream)
val workbook = file.inputStream.use {
try {
WorkbookFactory.create(it)
} catch (e: Exception) {
throw InternalServerException("엑셀 파일 처리 중 문제가 발생했습니다. info : [ errorMessage = ${e.message} ]")
}
}

val sheet = workbook.getSheetAt(0)
val sheet = workbook.getSheetAt(0)

sheet.forEachIndexed { index, row ->
if (index == 0)
return@forEachIndexed
sheet.forEachIndexed { index, row ->
if (index == 0)
return@forEachIndexed

if (row.getCell(0).stringCellValue == "")
return
if (row.getCell(0).stringCellValue == "")
return

val schoolName = row.getCell(0).stringCellValue
val clubName = row.getCell(1).stringCellValue
val field = row.getCell(2).stringCellValue
val schoolName = row.getCell(0).stringCellValue
val clubName = row.getCell(1).stringCellValue
val field = row.getCell(2).stringCellValue

val school = schoolRepository.findByName(schoolName)
?: throw SchoolNotFoundException("존재하지 않는 학교입니다. info : [ schoolName = $schoolName ]")
val school = schoolRepository.findByName(schoolName)
?: throw SchoolNotFoundException("존재하지 않는 학교입니다. info : [ schoolName = $schoolName ]")

if (clubRepository.existsByName(clubName)) {
throw AlreadyExistClubException("이미 존재하는 동아리입니다. info : [ clubName = $clubName ]")
}
if (clubRepository.existsByName(clubName)) {
throw AlreadyExistClubException("이미 존재하는 동아리입니다. info : [ clubName = $clubName ]")
}

val clubField = when (field) {
FUTURISTIC_TRANSPORTATION_EQUIPMENT -> Field.FUTURISTIC_TRANSPORTATION_EQUIPMENT
ENERGY -> Field.ENERGY
MEDICAL_HEALTHCARE -> Field.MEDICAL_HEALTHCARE
AI_CONVERGENCE -> Field.AI_CONVERGENCE
CULTURE -> Field.CULTURE
else -> throw InvalidFieldException("유효하지 않은 동아리 분야입니다. info : [ clubField = $field ]")
}
val clubField = when (field) {
FUTURISTIC_TRANSPORTATION_EQUIPMENT -> Field.FUTURISTIC_TRANSPORTATION_EQUIPMENT
ENERGY -> Field.ENERGY
MEDICAL_HEALTHCARE -> Field.MEDICAL_HEALTHCARE
AI_CONVERGENCE -> Field.AI_CONVERGENCE
CULTURE -> Field.CULTURE
else -> throw InvalidFieldException("유효하지 않은 동아리 분야입니다. info : [ clubField = $field ]")
}

val club = Club(
school = school,
name = clubName,
field = clubField
)
clubRepository.save(club)
}
}

/**
* 강의 리스트 엑셀을 업로드 하는 비지니스 로직입니다
* @param file 강의 리스트 엑셀 업로드를 위한 MultipartFile
*/
@Transactional(rollbackFor = [Exception::class])
override fun uploadLectureListExcel(file: MultipartFile) {
val workbook = file.inputStream.use {
try {
WorkbookFactory.create(it)
} catch (e: IndexOutOfBoundsException) {
throw InvalidCellTypeException("셀 서식을 텍스트로 변경해주세요.")
} catch (e: Exception) {
throw InternalServerException("엑셀 파일 처리 중 문제가 발생했습니다. info : [ errorMessage = ${e.message} ]")
}
}

val sheet = workbook.getSheetAt(0)

sheet.forEachIndexed { index, row ->
if (index == 0 || index == 1)
return@forEachIndexed

if (row.getCell(0) == null || row.getCell(0).stringCellValue == "")
return

val name = row.getCell(0).stringCellValue
val content = row.getCell(1).stringCellValue

val instructorName = row.getCell(2).stringCellValue
val instructorEmail = row.getCell(3).stringCellValue

val club = Club(
school = school,
name = clubName,
field = clubField
)
clubRepository.save(club)
val instructor = userRepository.findByEmail(instructorEmail)
?: throw UserNotFoundException("존재하지 않는 강사입니다. info : [ email = $instructorEmail ]")

val type = row.getCell(4).stringCellValue
val credit = row.getCell(5).numericCellValue.toInt()
val semester = row.getCell(6).stringCellValue

val lectureSemester = when(semester) {
FIRST_YEAR_FALL_SEMESTER -> Semester.FIRST_YEAR_FALL_SEMESTER
SECOND_YEAR_SPRING_SEMESTER -> Semester.SECOND_YEAR_SPRING_SEMESTER
SECOND_YEAR_FALL_SEMESTER -> Semester.SECOND_YEAR_FALL_SEMESTER
THIRD_YEAR_SPRING_SEMESTER -> Semester.THIRD_YEAR_SPRING_SEMESTER
else -> Semester.NOT_APPLICABLE
}

val division = row.getCell(7).stringCellValue
val line = row.getCell(8).stringCellValue
val department = row.getCell(9).stringCellValue
val maxRegisteredUser = row.getCell(10).numericCellValue.toInt()

val startDate = row.getCell(11).stringCellValue.toLocalDateTime()
val endDate = row.getCell(12).stringCellValue.toLocalDateTime()
val essentialComplete = row.getCell(16).stringCellValue

val lectureEssentialComplete = essentialComplete.uppercase() == "O"

val lecture = Lecture(
id = UUID(0, 0),
name = name,
content = content,
instructor = instructorName,
user = instructor,
lectureType = type,
credit = credit,
semester = lectureSemester,
division = division,
line = line,
department = department,
maxRegisteredUser = maxRegisteredUser,
startDate = startDate,
endDate = endDate,
essentialComplete = lectureEssentialComplete
)

lectureRepository.save(lecture)

val lectureDates = row.getCell(13).stringCellValue
.split(",").map {
val timeZone = it.split(" ", "~")
LectureDate(
id = UUID(0, 0),
lecture = lecture,
completeDate = timeZone[0].toLocalDate(),
startTime = timeZone[1].toLocalTime(),
endTime = timeZone[2].toLocalTime()
)
}

lectureDateRepository.saveAll(lectureDates)

val address = row.getCell(14).stringCellValue
val addressDetails = row.getCell(15).stringCellValue

val coordinate = kakaoUtil.getCoordinate(address)
val lectureLocation = LectureLocation(
lectureId = lecture.id,
x = coordinate.first,
y = coordinate.second,
address = address,
details = addressDetails
)

lectureLocationRepository.save(lectureLocation)
}
}

Expand Down Expand Up @@ -378,5 +488,19 @@ class AdminServiceImpl(
const val MEDICAL_HEALTHCARE = "의료 헬스케어"
const val AI_CONVERGENCE = "AI 융복합"
const val CULTURE = "문화산업"

const val FIRST_YEAR_FALL_SEMESTER = "1학년 2학기"
const val SECOND_YEAR_SPRING_SEMESTER = "2학년 1학기"
const val SECOND_YEAR_FALL_SEMESTER = "2학년 2학기"
const val THIRD_YEAR_SPRING_SEMESTER = "3학년 1학기"
}

private fun String.toLocalDateTime(): LocalDateTime =
LocalDateTime.parse(this, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))

private fun String.toLocalDate(): LocalDate =
LocalDate.parse(this, DateTimeFormatter.ofPattern("yyyy-MM-dd"))

private fun String.toLocalTime(): LocalTime =
LocalTime.parse(this, DateTimeFormatter.ofPattern("HH:mm"))
}
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ class SecurityConfig(
.mvcMatchers(HttpMethod.POST, "/admin/student/excel").hasRole(ADMIN)
.mvcMatchers(HttpMethod.POST, "/admin/club/excel").hasRole(ADMIN)
.mvcMatchers(HttpMethod.GET, "/admin/club/excel").hasRole(ADMIN)
.mvcMatchers(HttpMethod.POST, "/admin/lecture/excel").hasRole(ADMIN)

// inquiry
.mvcMatchers(HttpMethod.POST, "/inquiry").authenticated()
Expand Down
Loading

0 comments on commit 74eea67

Please sign in to comment.