Skip to content

Commit dc669c6

Browse files
authored
Merge pull request #440 from DSM-PICK/develop
merge to main
2 parents d6ef69f + 1794936 commit dc669c6

File tree

11 files changed

+124
-8
lines changed

11 files changed

+124
-8
lines changed

src/main/kotlin/dsm/pick2024/domain/attendance/domain/Attendance.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,10 @@ data class Attendance(
2020
val period8: AttendanceStatus,
2121
val period9: AttendanceStatus,
2222
val period10: AttendanceStatus
23-
)
23+
24+
) {
25+
26+
fun updateClub(clubName: String, floor: Int, place: String): Attendance {
27+
return this.copy(club = clubName, floor = floor, place = place)
28+
}
29+
}

src/main/kotlin/dsm/pick2024/domain/attendance/persistence/AttendancePersistenceAdapter.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,7 @@ class AttendancePersistenceAdapter(
6060
)
6161
.fetch()
6262
.map { attendanceMapper.toDomain(it) }
63+
64+
override fun findByStudentNum(grade: Int, classNum: Int, num: Int): Attendance? =
65+
attendanceJpaRepository.findByGradeAndClassNumAndNum(grade, classNum, num).let { attendanceMapper.toDomain(it) }
6366
}

src/main/kotlin/dsm/pick2024/domain/attendance/persistence/repository/AttendanceRepository.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,6 @@ interface AttendanceRepository : Repository<AttendanceJpaEntity, UUID> {
1414
fun findAll(): List<AttendanceJpaEntity>
1515

1616
fun findByFloor(floor: Int): List<AttendanceJpaEntity>
17+
18+
fun findByGradeAndClassNumAndNum(grade: Int, classNum: Int, number: Int): AttendanceJpaEntity
1719
}

src/main/kotlin/dsm/pick2024/domain/attendance/port/out/QueryAttendancePort.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ interface QueryAttendancePort {
1212
classNum: Int
1313
): List<Attendance>
1414

15+
fun findByStudentNum(
16+
grade: Int,
17+
classNum: Int,
18+
num: Int
19+
): Attendance?
20+
1521
fun findByClub(club: String): List<Attendance>?
1622

1723
fun findByUserId(userId: UUID): Attendance?
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package dsm.pick2024.domain.user.exception
2+
3+
import dsm.pick2024.global.error.exception.ErrorCode
4+
import dsm.pick2024.global.error.exception.PickException
5+
6+
object NotExtensionXslException : PickException(
7+
ErrorCode.NOT_EXTENSION_XSL
8+
)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package dsm.pick2024.domain.user.port.`in`
2+
3+
import org.springframework.web.multipart.MultipartFile
4+
5+
interface UpdateUserClubFromExcelUseCase {
6+
fun updateUserClubFromExcel(file: MultipartFile)
7+
}

src/main/kotlin/dsm/pick2024/domain/user/presentation/UserController.kt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
package dsm.pick2024.domain.user.presentation
22

3-
import dsm.pick2024.domain.user.port.`in`.LoginUseCase
4-
import dsm.pick2024.domain.user.port.`in`.QueryUserAllUseCase
5-
import dsm.pick2024.domain.user.port.`in`.QueryUserDetailsInfoUseCase
6-
import dsm.pick2024.domain.user.port.`in`.QueryUserSimpleInfoUseCase
7-
import dsm.pick2024.domain.user.port.`in`.UploadUserProfileUseCase
8-
import dsm.pick2024.domain.user.port.`in`.UserTokenRefreshUseCase
3+
import dsm.pick2024.domain.user.port.`in`.*
94
import dsm.pick2024.domain.user.presentation.dto.request.UserLoginRequest
105
import dsm.pick2024.global.security.jwt.dto.TokenResponse
116
import io.swagger.v3.oas.annotations.Operation
@@ -30,7 +25,8 @@ class UserController(
3025
private val queryUserSimpleInfoUseCase: QueryUserSimpleInfoUseCase,
3126
private val queryUserDetailsInfoUseCase: QueryUserDetailsInfoUseCase,
3227
private val queryUserAllUseCase: QueryUserAllUseCase,
33-
private val uploadUserProfileUseCase: UploadUserProfileUseCase
28+
private val uploadUserProfileUseCase: UploadUserProfileUseCase,
29+
private val updateUserClubFromExcelUseCase: UpdateUserClubFromExcelUseCase
3430
) {
3531
@Operation(summary = "유저 로그인 API")
3632
@PostMapping("/login")
@@ -59,4 +55,10 @@ class UserController(
5955
@Operation(summary = "유저 프로필 업로드 API")
6056
@PatchMapping("/profile")
6157
fun upload(@RequestParam("file")file: MultipartFile) = uploadUserProfileUseCase.uploadUserProfile(file)
58+
59+
@Operation(summary = "엑셀 파일 동아리 정보 업데이트 API")
60+
@PostMapping("/club")
61+
fun updateClub(@RequestParam("file")file: MultipartFile) = updateUserClubFromExcelUseCase.updateUserClubFromExcel(
62+
file
63+
)
6264
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package dsm.pick2024.domain.user.presentation.dto.request
2+
3+
import org.springframework.web.multipart.MultipartFile
4+
5+
data class UpdateUserClubFromExcelRequest(
6+
val excel: MultipartFile
7+
)
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package dsm.pick2024.domain.user.service
2+
3+
import dsm.pick2024.domain.attendance.port.out.QueryAttendancePort
4+
import dsm.pick2024.domain.attendance.port.out.SaveAttendancePort
5+
import dsm.pick2024.domain.user.exception.NotExtensionXslException
6+
import dsm.pick2024.domain.user.port.`in`.UpdateUserClubFromExcelUseCase
7+
import org.apache.commons.compress.utils.FileNameUtils
8+
import org.apache.poi.hssf.usermodel.HSSFWorkbook
9+
import org.apache.poi.ss.usermodel.Row
10+
import org.apache.poi.ss.usermodel.Sheet
11+
import org.apache.poi.ss.usermodel.Workbook
12+
import org.apache.poi.xssf.usermodel.XSSFWorkbook
13+
import org.springframework.stereotype.Service
14+
import org.springframework.web.multipart.MultipartFile
15+
import javax.transaction.Transactional
16+
17+
@Service
18+
class UpdateUserClubFromExcelService(
19+
private val queryAttendancePort: QueryAttendancePort,
20+
private val saveAttendancePort: SaveAttendancePort
21+
) : UpdateUserClubFromExcelUseCase {
22+
val STUDENT_NUM_INDEX = 1
23+
val STUDENT_CULB_INDEX = 3
24+
val STUDENT_PLACE_INDEX = 6
25+
val STUDENT_FLOOR_INDEX = 7
26+
val START_DATA_INDEX = 2
27+
28+
@Transactional
29+
override fun updateUserClubFromExcel(file: MultipartFile) {
30+
val extension = FileNameUtils.getExtension(file.originalFilename!!).lowercase()
31+
32+
if (extension != "xls" && extension != "xlsx") {
33+
throw NotExtensionXslException
34+
}
35+
36+
var excel: Workbook? = null
37+
try {
38+
if (extension == "xlsx") {
39+
excel = XSSFWorkbook(file.inputStream)
40+
} else {
41+
excel = HSSFWorkbook(file.inputStream)
42+
}
43+
44+
val worksheet: Sheet = excel.getSheetAt(0)
45+
46+
for (i in START_DATA_INDEX until worksheet.physicalNumberOfRows) {
47+
val row: Row = worksheet.getRow(i)
48+
val studentNum = row.getCell(STUDENT_NUM_INDEX).toString().trim()
49+
val clubName = row.getCell(STUDENT_CULB_INDEX).toString().trim()
50+
val floor = row.getCell(STUDENT_FLOOR_INDEX).toString().trim()
51+
val place = row.getCell(STUDENT_PLACE_INDEX).toString().trim()
52+
if (studentNum != "" && clubName != "" && floor != "") {
53+
updateClub(
54+
studentNum.substring(0, 1).toInt(),
55+
studentNum.substring(1, 2).toInt(),
56+
studentNum.substring(2, 4).toInt(),
57+
clubName,
58+
floor.substring(0, 1).toInt(),
59+
place
60+
)
61+
}
62+
}
63+
} finally {
64+
excel?.close()
65+
}
66+
}
67+
68+
private fun updateClub(grade: Int, classNum: Int, num: Int, clubName: String, floor: Int, place: String) {
69+
val attendance = queryAttendancePort.findByStudentNum(grade, classNum, num)
70+
attendance?.updateClub(clubName, floor, place)?.let { saveAttendancePort.save(it) }
71+
}
72+
}

src/main/kotlin/dsm/pick2024/global/config/security/SecurityConfig.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class SecurityConfig(
4646
).permitAll()
4747
.antMatchers(
4848
HttpMethod.POST,
49+
"/user/club",
4950
"/after/**",
5051
"/meal",
5152
"/notice",

0 commit comments

Comments
 (0)