Project(SEMOGONG) ๊ฐ๋ฐ ์ผ์ง
- Issue ๋ฅผ ๋ฐํ์ผ๋ก ๊ฐ๋ฐ ์งํ.
- Issue Labels
Bug
: ๊ตฌํํ ๊ธฐ๋ฅ๋ค ์ค์์ ์๋ฒ์ ์ฌ๋ ธ๋๋ฐ ์๋ํ์ง ์๊ฑฐ๋ ์ค๋ฅ๊ฐ ์๊นBack
: Back-End Engineer ๋ง์ ์ํ ์ด์Front
: Front-End Engineer ๋ง์ ์ํ ์ด์Enhancement
: ์๋ก์ด ๊ธฐ๋ฅ์ด ํ์ํ ๊ฒฝ์ฐ, front back ๋ชจ๋๊ฐ ์๋ด์ผํ ์ด์
<220818>
#99
Bug
: 0-4 ์ ์์ ์ ์์์๊ฐ ์ค๋ฅ
- #99
- ๊ธฐ์กด์ ๋ฌธ์ ์
- 0-4์ ๊ณต๋ถ ์์ ์, ๋ก์ง์ ๋ฐ๋ผ ๋ ์ง๋ ์ ๋ ๋ก ์ค์ ๋๋๋ฐ, ๊ทธ๋ ๊ณต๋ถ ์์ ์๊ฐ ๋ง์ createTime์ผ๋ก ์ค์ ๋๋ ์ค๋ฅ
- Post Entity ์์ฑ ๋ฉ์๋ createPost ์ ์๊ฐ List์ ์๊ฐ์ ์ถ๊ฐํ๋ times.add ๊ฐ createTime ์ผ๋ก ์ค์ ๋์ด ์์ด ๋ฐ์ํ๋ ์ค๋ฅ
- ํด๊ฒฐ
-
createPost์ times.add ๋ฅผ ํ์ฌ ์๊ฐ(LocalDateTime.now())์ผ๋ก ์ค์
public static Post createPost(Member member, LocalDateTime createTime){ Post post = new Post(); post.setMember(member); post.createTime = createTime; DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm"); post.times.add(LocalDateTime.now().format(timeFormatter)); post.state = StudyState.STUDYING; return post; }
-
- ๊ธฐ์กด์ ๋ฌธ์ ์
<220815>
#96
Back
: ๊ณต๋ถ ์์ ์๊ฐ์ด 0~4์ ์ฌ์ด์ผ ๊ฒฝ์ฐ์ ๋ํ ์ฒ๋ฆฌ [์๊ฐ ์ฒ๋ฆฌ]
- #96
- ๊ธฐ์กด์ ๋ฌธ์ ์
- ๋ง์ฝ ์ฌ์ฉ์๊ฐ 0~4์ ์ฌ์ด์ ๊ณต๋ถ๋ฅผ ์์ํ ๊ฒฝ์ฐ, ํด๋น post๋ ๋น์ง๋์ค ๋ก์ง ํน์ฑ ์ ํด๋น ๋ ์ง๋ฅผ ๊ฐ์ง๊ฒ ๋จ. (
LocalDateTime.now()
์ด์ฉ) - ํ์ง๋ง, ์๋น์ค ํน์ฑ ์ 0~4์ ์ฌ์ด์ ์๊ฐ์ ์ด์ ๋ ์ง๋ก ์ธ์๋๊ฒ ํด์ผ๋จ. (๊ทธ๋ ์ง ์์ผ๋ฉด ํด๋น ๋ ์ง์ Post๊ฐ 2๊ฐ๊ฐ ๋๋ ์์ธ ๋ฐ์)
- ex) 13์ผ์ด ๋์ด๊ฐ๋ 1์์ ๊ณต๋ถ๋ฅผ ์์ํ๋ค๋ฉด 14์ผ๋ก ์ธ์ โ 13์ผ๋ก ์ธ์๋๊ฒ ์ค์ ํ์
- ๋ง์ฝ ์ฌ์ฉ์๊ฐ 0~4์ ์ฌ์ด์ ๊ณต๋ถ๋ฅผ ์์ํ ๊ฒฝ์ฐ, ํด๋น post๋ ๋น์ง๋์ค ๋ก์ง ํน์ฑ ์ ํด๋น ๋ ์ง๋ฅผ ๊ฐ์ง๊ฒ ๋จ. (
- ๊ตฌํ
- 0 - 4 ์ ์ฌ์ด์ ๊ธ์ ์์ฑํ ๊ฒฝ์ฐ, ์ ๋ ์ 23:59 ์ ๊ธ์ ์์ฑํ ๊ฒ๊ณผ ๋์ผํ๊ฒ ์ทจ๊ธํ์ฌ ๊ตฌํ โ ๊ธฐ์กด์ ๋ก์ง์ ๋ฐฉํด๋์ง ์์ผ๋ฉด์ ํ์ฌ ํ์ํ ์๊ตฌ์ฌํญ ์ถฉ์กฑ ๊ฐ๋ฅ
-
์ฆ, post์ times์๋ ํ์ฌ์๊ฐ์ ๋ฃ์ด์ฃผ๊ณ , post์ createTime์ ๊ทธ์ ๋ ์ 23:59 ๋ก ์ค์
if (createDate.getHour() < 4) { // 0 - 4 ์ ์ฌ์ด์ ๊ธ์ ์์ฑํ ๊ฒฝ์ฐ, ์ ๋ ์ 23:59 ์ ๊ธ์ ์์ฑํ ๊ฒ๊ณผ ๋์ผํ๊ฒ ์ทจ๊ธ. LocalDateTime toChange = createDate.minusDays(1); // ์ ๋ ๋ก ์ค์ createDate = LocalDateTime.of(toChange.getYear(), toChange.getMonthValue(), toChange.getDayOfMonth(), 23, 59, 59); // ์ ๋ 23์59๋ถ์ผ๋ก ์ค์ } Long postId = postService.save(loginMember.getId(), createDate); // ์ ์ฅํ ๋๋ ํด๋น ๊ธ์ ์์ฑ์ Member ์ฐ๊ฒฐ, creatTime๋ง ์ค์ ํด์ค
- ๊ธฐ์กด์ ๋ฌธ์ ์
<220814>
#95
Back
: ๋ญํฌ ์ธก์ ๊ธฐ๋ฒ ๋ณ๊ฒฝ
- #95
- ๊ธฐ๋ฅ ํ์์ฑ
- ํ์ฌ ๋ญํฌ ์ธก์ ๊ธฐ์ค์ [์ด์ ๊ณต๋ถ ์๊ฐ์ ๊ธฐ์ค์ผ๋ก ํ๋ฃจ ๋ชฉํ ๋ฌ์ฑ๋ + ์ผ์ฃผ์ผ ์ด ๊ณต๋ถ์๊ฐ์ ๊ธฐ์ค์ผ๋ก ์ผ์ฃผ์ผ ๋ชฉํ ๋ฌ์ฑ๋ + ํ๋ฌ ์ถ์๋ฅ ]
- ํ์ง๋ง, โ์ด์ ๊ณต๋ถ ์๊ฐ์ ๊ธฐ์ค์ผ๋ก ํ๋ฃจ ๋ชฉํ ๋ฌ์ฑ๋โ ์ ๋ณ๋๋์ด ๋๋ฌด ํฌ๊ธฐ ๋๋ฌธ์ ์ด์ ํ๋ฃจ์ ๊ณต๋ถ๋์ด ๋ญํฌ์ ํฐ ์ํฅ์ ๋ฏธ์นจ. โ ๋ญํฌ ๋ณ๋๋ฅ ์ด ์ปค์ง
- ๊ณ ๋ก ๋ณ๋๋ฅ ์ ์ค์ผ ํ์๊ฐ ์กด์ฌ
- ๊ตฌํ
-
โ์ด์ ๊ณต๋ถ ์๊ฐ์ ๊ธฐ์ค์ผ๋ก ํ๋ฃจ ๋ชฉํ ๋ฌ์ฑ๋โ โ โ์ผ์ฃผ์ผ ๊ธฐ์ค ํ๋ฃจ ํ๊ท ๊ณต๋ถ์๊ฐ์ผ๋ก ํ๋ฃจ ๋ชฉํ ๋ฌ์ฑ๋โ ์ผ๋ก ๋ณ๊ฒฝ (ํด๋น ์ฌํญ์ ์ถํ ๋ณ๋ ๊ฐ๋ฅ)
Times weekAvgTimes = new Times(); int weekAvgTime = weekAllTimes / 7; int dayGoalTimes = member.getGoal().getDayGoalTimes(); allStatic.setGoalAttainmentToday(Math.round(((float) weekAvgTime / (float) dayGoalTimes) * 100));
-
- ๊ธฐ๋ฅ ํ์์ฑ
<220812>
#93
Bug
: ๋ญํน ํ์ด์ง ๋ฐ My Page Times ๊ณ์ฐ ์ค๋ฅ
- #93
- ๋ฐ์ ์ค๋ฅ
- Ranking Page ์ด๋ My Page ์ด๋ ๊ณต๋ถ ์๊ฐ ๊ณ์ฐ ์ ์๊ฐ์ด ๋ง๋ฌด๋ฆฌ๋์ง ์์ Post์ ๋ํด์ Times๊ฐ Null ๋ฐํ โ
NullPointerException
๋ฐ์ - Post์ times size ๊ฐ ํ์ ์ผ๊ฒฝ์ฐ ๊ทธ๋ฅ null์ด ๋ฐํ๋๋๋ก ์ค์ ๋์ด ์์์ โ ์ฒ๋ฆฌ ํ์
- Ranking Page ์ด๋ My Page ์ด๋ ๊ณต๋ถ ์๊ฐ ๊ณ์ฐ ์ ์๊ฐ์ด ๋ง๋ฌด๋ฆฌ๋์ง ์์ Post์ ๋ํด์ Times๊ฐ Null ๋ฐํ โ
- ํด๊ฒฐ
- times size ๊ฐ ์ง์๋ผ๋ฉด ๊ณ์ฐ์ ๋๋ฆฌ๊ณ
-
ํ์ (๋ง๋ฌด๋ฆฌ๋์ง ์์ ์๊ฐ) ์ ๋ํด์๋ null ์ด ์๋ 0์ ๋ฐํํ์ฌ
NullPointerException
์ ํผํ ์ ์๋๋ก ์ค์ private Times getTimes(List<String> times) { Times resultTime; if (times.size() % 2 == 0) { // ์ง์ int total1 = 0; ... } resultTime = new Times(total1); } else { // ํ์ -> ๋ง๋ฌด๋ฆฌ๋์ง ์์ post resultTime = new Times(0); } return resultTime; }
- ๋ฐ์ ์ค๋ฅ
<220811>
#88
Bug
: My Page ์์์ post edit ์ค๋ฅ
#89Bug
: My Page, Member Detail ์์์ ์ถ์๋ฅ ๊ณ์ฐ ์ค๋ฅ
- #88
- ๋ฐ์ ์ค๋ฅ
- My Page ์์ ๊ธ ์์ submit์ด ์๋๋ ์ค๋ฅ
- focusedPostId ๋ฅผ ์ฐพ์ ์ ์์ด์ ๋ฐ์ํ ์ค๋ฅ
- ๋ฟ๋ง ์๋๋ผ ์ด์ ์ home์์์ post edit ์ ๋ฐ์ํ๋ ์ค๋ฅ์ ๋์ผํ ์ค๋ฅ ๋ฐ์
- ์์ธ : focusedPostId ๋ณ์์ด๋ฆ ๋ณ๊ฒฝ์ผ๋ก ๋ฐ์ํ ์ค๋ฅ + ์ค๋ณต๋๋ id๋ก ์ธํ ์ค๋ฅ โ ์ ์ฒด์ ์ธ post edit์ ๋ณ๊ฒฝ์ฌํญ์ ๋ฐ์ํ์ง ์์
- ํด๊ฒฐ
- Home์์์ ์ค๋ฅํด๊ฒฐ๊ณผ ๋์ผํ๊ฒ My Page์ ๋ ๋๋ง๋๋ html์ ๊ฐ ๋ชจ๋ post์ ์ฐ๊ฒฐ๋๋ simplemde + {post.id} ๋ณ์ ์์ฑ ํ ํด๋น ๋ณ์์ ์๋ก ์์ฑ๋๋ Simple MDE ํ ๋น
- focusedPostId ๋ณ์ ์ด๋ฆ ์์
- ์ถํ ํ์ ์์ ์ฌํญ
- [์ค์] focusedPostId๋ ํด๋น ๋น์ง๋์ค ๋ก์ง์์ ์ฌ์ฉ๋์ง ์์ โ main.js ๊ฐ ์๋ ์๋ก์ด javascript๋ฅผ ์์ฑํ์ฌ ๋ถ๋ฆฌํ ํ์๊ฐ ์์.
- ๋ฐ์ ์ค๋ฅ
- #89
- ๋ฐ์ ์ค๋ฅ
- ํ๋ฌ ๊ณต๋ถ ํต๊ณ์์ ์ถ์๋ฅ , ์ ์ฒด ๊ณต๋ถ์๊ฐ, ํ๊ท ๊ณต๋ถ์๊ฐ ๋ฑ์ด ์์ ํ ๋ถ๋ถ๊ณผ ๋ค๋ฅด๊ฒ โ์ค๋โ๊น์ง ๊ณ ๋ ค๊ฐ ๋จ. ( โ ์๋๋ โ์ด์ โ ๊น์ง๋ง ๊ณ ๋ ค๊ฐ ๋์ด ๊ณ์ฐ๋์ด์ผ ํจ)
- ๊ณ์ฐ ๋ถ๋ถ์ ์์ด์ ์ค๋ฅ ๋ฐ์ โ ๊ณ์ฐ ํด๋๊ณ ๋ค๋ฅธ ๋ณ์๋ก ์ ์ฉํ๊ณ ์์์
- ํด๊ฒฐ
- ๊ณต๋ถ ๋ญํน์ ์ํด์ ํ์ฌ ๋ฌ์ ์ถ์๋ฅ ์ ๊ตฌํด์ฃผ๊ธฐ ์ํด์ focusedDay, nowMonthDayLen ์ ์ฌ์ฉํ์ง๋ง, ํ์ฌ ๋ณด๊ณ ์๋ ๋ฌ๋ ฅ์ ํต๊ณ๋ฅผ ๋ณด์ฌ์ฃผ๊ธฐ ์ํด monthDate, mothPosts ๋ฅผ ์ฌ์ฉํ์. ์ฌ๊ธฐ์ ๋ง์ฝ ํ์ฌ ๋ณด๋ ๋ฌ๋ ฅ์ด ์ค๋ ๋ ์ง์ ๋ฌ๊ณผ ๋์ผํ๋ค๋ฉด monthDate์ focusedDay ๋ฅผ ๋์ ํ๊ณ monthPosts์ ์ด์ ๋ ์ง๊น์ง์ post๋ฅผ ๋ฃ์ด์ฃผ์ด ํด๊ฒฐ
- ์ฆ, ๋ณด๊ณ ์๋ ๋ฌ๋ ฅ์ ํต๊ณ๋ฅผ ์ํฉ์ ๋ฐ๋ผ ํ์ฌ ๋ฌ์ ๋ง๊ฒ ์ค์ ํด์ฃผ๋ฉฐ ํด๊ฒฐ
List<Post> nowMonthPosts = postService.getMonthPosts(memberId, LocalDateTime.now().getMonthValue()); int focusedDay; if (LocalDateTime.now().getHour() < 4) { focusedDay = LocalDateTime.now().getDayOfMonth() - 2; } else { focusedDay = LocalDateTime.now().getDayOfMonth() - 1; } List<Post> calculatedNowMonthPosts = new ArrayList<>(); for (Post post : nowMonthPosts) { if (post.getCreateTime().getDayOfMonth() > focusedDay) { break; } calculatedNowMonthPosts.add(post); } ForCalender CalenderInfo = getCalenderInfo(weekDay, focusedDate); int monthDate = dayData[month - 1]; if (month == LocalDateTime.now().getMonthValue()) { monthDate = focusedDay; monthPosts = new ArrayList<>(calculatedNowMonthPosts); } AllStatic allStatic = getAllStatus(oriMember, staticsData, days.get(days.size() - 1), monthPosts, monthDate, focusedDay, calculatedNowMonthPosts.size());
- ๋จผ์ focosedDay๋ฅผ ๊ตฌํด๊ณ ํด๋น ๋ณ์์ ๋ง๋ ํ์ฌ ๋ฌ์ posts๋ฅผ ๊ฐ์ ธ์ด
- ๊ทธ ํ ๋ง์ฝ ์ฌ์ฉ์๊ฐ ํ์ธํ๊ณ ์๋ ๋ฌ๋ ฅ์ด ํ์ฌ ๋ฌ๊ณผ ๋์ผํ๋ค๋ฉด ํด๋น ๋ณ์๋ค์ ํ์ฌ ๋ฌ์ ์ฌ์ฉ๋๋ ๋ณ์๋ก ๋ณ๊ฒฝ. (์๋๋ผ๋ฉด ๊ธฐ์กด์ ๋ณ์ ์ฌ์ฉ)
- ๋ฐ์ ์ค๋ฅ
<220809>
#90
Bug
: ์ ๊ธ ์์ฑ ์ค๋ฅ
- #90
- ๋ฐ์ ์ค๋ฅ
- ์ ๊ธ ์์ฑ ์ simpleMDE ๊ฐ content์ ์์ฑ๋์ง ์์
- submit ์ ์ ์ถ๋์ง ์์
- ์์ธ : post edit ๊ณผ fragment๋ฅผ ๊ณต์ ํ๊ณ ์๊ธฐ ๋๋ฌธ์, ์ด์ ์ post edit ์ค๋ฅ ์์ ์ id ๊ฐ์ ๋ณ๊ฒฝํ๋ ๋ถ๋ถ์ด ์์๋๋ฐ, ๊ทธ ๋ถ๋ถ์ post new(์ ๊ธ ์์ฑ)์ javascript ์ฝ๋์ ๋ฐ์ํ์ง ์์๊ธฐ ๋๋ฌธ์ ๋ฐ์
- ํด๊ฒฐ
- ๊ธฐ์กด์ content ๋ผ๋ id๋ฅผ ๊ฐ์ก๋ ์์์
content + ${post.id}
์ id๋ฅผ ์๋ก ๋ถ์ฌ โ ์ด์ ํด๋น id๋ก Simple MDE ๋ฅผ ์ฌ์ด์ค ์ ์์ simplemde + ${post.id}
์ ๋ณ์๋ฅผ ์์ฑํด์ฃผ๊ณ ํด๋น ๋ณ์์ ์๋ก ์์ฑ๋ Simple MDE ๋ฅผ ํ ๋น โ ํด๋น MDE์ value(content) ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๊ฒ ๋จ
- ๊ธฐ์กด์ content ๋ผ๋ id๋ฅผ ๊ฐ์ก๋ ์์์
- ๋ฐ์ ์ค๋ฅ
<220808>
#87
Bug
: ๋ค์ค post edit ์ ์ฌ๋ฌ ์ค๋ฅ ๋ฐ์
- #87
- ๊ธฐ์กด ๋ฌธ์ ์
- ๊ฐ์ฅ ๋ง์ง๋ง์ edit๋ฒํผ์ ๋๋ฅธ post์ content๋ก ๋ชจ๋ post์ ๋ด์ฉ์ด ๋ณ๊ฒฝ๋จ (simpleMDE๋ฅผ ์ ์ญ๋ณ์๋ก ๊ณต์ ํ๋ฉฐ ์ฌ์ฉํด์ ๋ฐ์ํ ๋ฌธ์ )
- simpleMDE๊ฐ ๋ค๋ฅธ post์ content์ ์์ฑ๋จ (postEditForm์ content๊ฐ unique id๊ฐ ์๋๋ฉด์ ์๊ธฐ๋ ๋ฌธ์ . โ editํ๋ฉด ์ฌ๋ฌ๊ฐ์ content๊ฐ ์์ฑ๋๊ณ , ์ค๋ณต๋ ID๋ก ์ธํด์ ๊ฐ์ฅ ์ฒ์ ์์ฑ๋ content์ simpleMDE๊ฐ ๋ฐ์)
- submit ํ๋ฉด ์ด์ ์ ์ด์๋ post์ fragment๊ฐ replacement๋๊ณ ํ์ฌ post๋ replacement๋์ง ์์ (postEditForm์ postEdit_container์ id๊ฐ uniqueํ์ง ์์ ๋ฐ์ํ๋ ๋ฌธ์ , 2๋ฒ๊ณผ ๋์ผํ ์ด์ ๋ก ๋ฐ์ํ๋ ๋ฌธ์ )
- ํด๊ฒฐ
- simpleMDE ๋ณ์ ํ๋๋ฅผ ์ ์ญ๋ณ์๋ก ๊ณต์ ํ๋ฉฐ ์ฌ์ฉํด์ ๋ฐ์ํ ๋ฌธ์
- simpleMDE๋ฅผ ๊ฐ post์ ID๋ก ์์ฑํ ํ (์ ์ญ๋ณ์๋ก ์ ์ธ โ ๋ค๋ฅธ ํจ์์์๋ ์ฌ์ฉํด์ผ ๋๊ธฐ ๋๋ฌธ)
- edit ์ ํด๋น post์ ID ๊ฐ์ ๊ฐ์ง๋ simpleMDE๋ฅผ ๊ฐ์ ธ์ ํด๋น ๋ณ์์ ์๋ก์ด simpleMDE๋ฅผ ์์ฑํด์ค. โ unique ID๋ฅผ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์, ๊ฐ post์ simpleMDE์ ๊ฐ์ ๊ตฌ๋ถํ์ฌ ์ ์ฅํ ์ ์๊ฒ ๋จ
-
๊ตฌํ ์ฝ๋
// home.html์ script ๋ถ๋ถ (๋ณ๊ฒฝ ์ : var simplemde;) [# th:each="post, stat : ${postDtos}"] var simplemde[[${post.id}]]; [/]
- home.html์ simplemde๋ฅผ ๊ฐ post์ mapping ๋ ์ ์๋๋ก id์ ๋ง๊ฒ simplemde๋ฅผ ์์ฑ
- thymeleaf์ javascirpt์์์ ์ ์ฉํ ๊ธฐ๋ฅ์ ์ด์ฉํ์ฌ ๋์ ๋ณ์ ์์ฑ
function edit_post(id) { $.ajax({ url: '/posts/edit/' + id, type: "GET", }) .done(function (fragment) { $('#postModal_content' + id).replaceWith(fragment); /* (๋ณ๊ฒฝ ์ ) => simplemde = new SimpleMDE({element: document.getElementById("content"+id.toString()),spellChecker: false});*/ eval("simplemde" + id + "= new SimpleMDE({element: document.getElementById("content"+id.toString()),spellChecker: false})"); ... }); }
- edit ์์ฒญ์ด ๋ค์ด์ฌ ๋ ๋์ ์ผ๋ก ํด๋น post์ mapping ๋๋ simplemde๋ฅผ ์ฌ์ ์ โ ํด๋น post์ simpleMDE๋ฅผ content์ ์ฌ์ด์ฃผ๋ ๊ฒ
- ์ด๋ id์ ๋ง๋ ๋์ ๋ณ์๋ฅผ ํตํด ์ ์ญ ๋ณ์์ธ simpleMDE๋ฅผ ๊ฐ์ ธ์์ผ ํ๊ธฐ ๋๋ฌธ์
eval()
ํจ์ ์ฌ์ฉ
- postEditForm์ content๊ฐ unique id๊ฐ ์๋๋ฉด์ ์๊ธฐ๋ ๋ฌธ์ . โ editํ๋ฉด ์ฌ๋ฌ๊ฐ์ content๊ฐ ์์ฑ๋๊ณ , ์ค๋ณต๋ ID๋ก ์ธํด์ ๊ฐ์ฅ ์ฒ์ ์์ฑ๋ content์ simpleMDE๊ฐ ๋ฐ์
-
postEditForm์ content id์์ฑ์ post์ ID๋ฅผ ์ฐ๊ฒฐํด์ฃผ์ด uniqueํ id๊ฐ ๋ ์ ์๋๋ก ์ค์ .
<textarea type="text" rows="4" th:field="*{content}" th:id="'content'+${postForm.id}" placeholder="Content" class="form-control" autocomplete="off"></textarea>
-
์ถ๊ฐ๋ก ๊ทธ์ ๋ง๊ฒ simpleMDE๋ฅผ ์ฌ์ด์ค ๋๋
content+post.id
๋ก ์ฐพ์์ค๊ณ ์ฌ์ ์ ์๋๋ก ์ค์ โ unique id์ด๊ธฐ ๋๋ฌธ์ ๊ฒน์น ์ผ๋ ์์ผ๋ฉฐ, ์ ๋๋ก๋ ์์น์ ์์ฑ ๊ฐ๋ฅnew SimpleMDE({element: document.getElementById(\"content\"+id.toString()),spellChecker: false})
-
- submit ํ๋ฉด ์ด์ ์ ์ด์๋ post์ fragment๊ฐ replacement๋๊ณ ํ์ฌ post๋ replacement๋์ง ์์ (postEditForm์ postEdit_container์ id๊ฐ uniqueํ์ง ์์ ๋ฐ์ํ๋ ๋ฌธ์ , 2๋ฒ๊ณผ ๋์ผํ ์ด์ ๋ก ๋ฐ์ํ๋ ๋ฌธ์ )
- eidt ์์ฒญ ์ postEditForm์ postEdit_container๋ฅผ ์ฐพ์์ ๊ต์ฒดํด ์ค ํ
- ํด๋น postEdit_container id๊ฐ์
postEdit_container + post.id
๋ก ๊ฐ์ง ์ ์๋๋ก ์ค์ โ ๋ฏธ๋ฆฌ id๊ฐ์ผ๋ก ๋ ๋๋ง ํ ์ฐพ์ผ๋ฉด ์ฐพ์์์ง์ง ์๊ธฐ ๋๋ฌธ์ ๊ฐ์ ธ์จ ํ id ๊ฐ์ ๋ณ๊ฒฝ -
์ฝ๋
function edit_post(id) { $.ajax({ url: '/posts/edit/' + id, type: "GET", }) .done(function (fragment) { $('#postModal_content' + id).replaceWith(fragment); ... document.getElementById("postEdit_container").setAttribute("id", "postEdit_container" + id.toString()); document.getElementById("postEdit_container"+id.toString()).scrollIntoView(); }); }
- ๋ง์ง๋ง์ผ๋ก post ์
postEdit_container + post.id
๋ก ๊ฒฐ๊ณผ fragment๋ก replace. โ unique ID๋ฅผ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ ์ ๋๋ก๋ ์์น๋ก replace ๋จ
- simpleMDE ๋ณ์ ํ๋๋ฅผ ์ ์ญ๋ณ์๋ก ๊ณต์ ํ๋ฉฐ ์ฌ์ฉํด์ ๋ฐ์ํ ๋ฌธ์
- ๊ธฐ์กด ๋ฌธ์ ์
<220807>
#83
Bug
: ์๊ฐ ๋ณ๊ฒฝ ์ค๋ฅ
- #83
- ๊ธฐ์กด ๋ฌธ์ ์
- ์ค๋์ด ์๋ ์ด์ post์์ ์๊ฐ ์์ ์ ์ค๋ฅ ๋ฐ์
- ์ค๋ ์์ฑ ์ค์ธ Post๊ฐ ์๋๋ฐ, โํ์ฌ์๊ฐ์ ๋๋ ์๊ฐ์ด ๋ฐ์ํ๋คโ ๋ validation ์๋
- ๋ํ 00์, 01์ ๋ฑ 0~4์์ ๋ํ ์๊ฐ๊ณ์ฐ ์ค๋ฅ โ 23์๋ณด๋ค 00์, 01์๊ฐ ๋ ํฐ ๊ฐ์ธ๋ฐ, ๋จ์ํ๊ฒ 23>0 ์ด๋ฏ๋ก 0~4์๊ฐ ๋ ์์ ์๊ฐ์ผ๋ก ํ๋ณ๋๋ ์ค๋ฅ
- ํด๊ฒฐ
- 0~4 ์์ ๋ํ ์ถ๊ฐ์ ์ธ ์ฒ๋ฆฌ
- ํ๋ฃจ ์๊ฐ์ ๊ธฐ์ค์ 4์๋ก ์ก์๊ธฐ ๋๋ฌธ์ 0~4์์ ๋ํด์ 24๋ฅผ ๋ ์ถ๊ฐํด์ฃผ์ด์ผ ํจ
if (hour < 4) {hour+=24}
์ถ๊ฐํ์ฌ ์ ์ฒด์ ์ธ ์๊ฐ ๊ณ์ฐ์ด ์ ์์ ์ผ๋ก ์ด๋ฃจ์ด์ง ์ ์๋๋ก ์์
- ์ค๋ post์ ๋ํด์๋ง ์๊ฐํ์ธ(1) ๊ฒ์ฆ ์คํ
- ์ด์ post๋ค์ ๋ํด์ ์๊ฐํ์ธ(1-ํ์ฌ์๊ฐ๊ณผ ๋น๊ต)์ ์งํํด์ ์๋จ
if (id == focusedPostId) {...}
๋ฅผ ํตํด ์ค๋ post์ ๋ํด์๋ง ํด๋น ๊ฒ์ฆ ์งํ
- 0~4 ์์ ๋ํ ์ถ๊ฐ์ ์ธ ์ฒ๋ฆฌ
- ๊ธฐ์กด ๋ฌธ์ ์
<220806>
#82
Enhancement
: ์๊ฐ์์ check
- #82
- ๊ธฐ๋ฅ์ ํ์์ฑ
- ํ์ฌ ์๊ฐ์ ์ ์ถํ ๋, ์๊ฐ์ ๊ฐ์, ๋น ์๊ฐ์ธ์ง ์๋์ง ๋ฑ์ Validation๋ง ๊ฑฐ์น๊ณ ์์
- ํ์ง๋ง, ์๊ฐ ๊ณ์ฐ์ ์ํ ์๊ฐ์์์์ ๋ฒ์ด๋ ์ ๋ ฅ๊ฐ์ ๋ํด์ ์ฒ๋ฆฌ๊ฐ ๋์ง ์๊ณ ์์
- ์๊ฐ ๊ณ์ฐ์ ์ํด์ ์ฌ๋ฐ๋ฅธ ์๊ฐ์์์ผ๋ก ์ ๋ ฅํ ์ ์๋๋ก ์ ๋ ํ์
- ๊ตฌํ
- ํ์ ์ฒดํฌ
- ์ง์ ํ์ : (์๊ฐํ์: ex_ โ
17:20
โ)var reg = /^\d{1,2}:\d{1,2}$/;
- ์ ๊ทํํ์์ ์ด์ฉํ์ฌ ํ์ ํ์ธ, ํ์์์ ๋ฒ์ด๋ ๊ฒฝ์ฐ alert ๋ฐ class ๋ณ๊ฒฝ
if (!reg.test(times[idx].value)) { alert('์๋ชป๋ ํ์์ ์๊ฐ์ด ์ ๋ ฅ๋์์ต๋๋ค.\n์ฌ๋ฐ๋ฅธ ํ์: "์๊ฐ:๋ถ" ex) 17:20'); var temp_times_id = "times" + idx; var timeHtml = document.getElementById(temp_times_id); timeHtml.setAttribute('class', 'form-control is-invalid'); timeHtml.setAttribute('style', 'background-image: none; padding: 6px;'); document.getElementById("postEdit_container").scrollIntoView(); return; }
- ์ง์ ํ์ : (์๊ฐํ์: ex_ โ
- ์๊ฐ ํ์ธ - 1
- ์ ๋ ฅ๋ ์๊ฐ ๊ฐ์ด ํ์ฌ ์๊ฐ๋ณด๋ค ํฐ์ง ํ์ธ
- ํฌ๋ฉด ์ค๋ฅ, alert์ ํตํด ์์ ํ ์ ์๋๋ก ์ค์
var curr = times[idx].value.split(':') var currTime = parseInt(curr[0])*60 + parseInt(curr[1]) if (currTime > totalTimeToday) { alert("ํ์ฌ์๊ฐ์ ์ด๊ณผํ ์๊ฐ๊ฐ์ด ์์ต๋๋ค."); var curr_times_id = "times" + idx; var timeHtmlCurr = document.getElementById(curr_times_id); timeHtmlCurr.setAttribute('class', 'form-control is-invalid'); timeHtmlCurr.setAttribute('style', 'background-image: none; padding: 6px;'); document.getElementById("postEdit_container").scrollIntoView(); return; }
- ์๊ฐ ํ์ธ -2
- ์ด์ ์๊ฐ๊ฐ์ด ์ดํ ์๊ฐ๊ฐ๋ณด๋ค ํฐ์ง ํ์ธ
- ํฌ๋ฉด ์ค๋ฅ, alert์ ํตํด ์์ ํ ์ ์๋๋ก ์ค์
if (idx !== 0){ var before = times[idx-1].value.split(':'); var beforeTime = parseInt(before[0])*60 + parseInt(before[1]); if (beforeTime > currTime) { alert("์ดํ ์๊ฐ์ด ์ด์ ์๊ฐ๋ณด๋ค ์์ต๋๋ค. ์์ ํด์ฃผ์ธ์!"); var timeAfter = "times" + idx; var timeBefore = "times" + (idx-1); var timeHtmlAfter = document.getElementById(timeAfter); var timeHtmlBefore = document.getElementById(timeBefore); timeHtmlAfter.setAttribute('class', 'form-control is-invalid'); timeHtmlAfter.setAttribute('style', 'background-image: none; padding: 6px;'); timeHtmlBefore.setAttribute('class', 'form-control is-invalid'); timeHtmlBefore.setAttribute('style', 'background-image: none; padding: 6px;'); document.getElementById("postEdit_container").scrollIntoView(); return; } }
- ํ์ ์ฒดํฌ
- ๊ธฐ๋ฅ์ ํ์์ฑ
<220804>
#80
Back
: ๋ญํฌ ์ธก์ ๊ธฐ์ค ๋ณ๊ฒฝ
#81Bug
: post edit ์ค๋ฅ
#79Bug
: paging ์ค๋ฅ
- #80
- ๊ธฐ์กด์ ๋ฌธ์ ์
- ๋ญํฌ ์ธก์ ๊ธฐ์ค ํญ๋ชฉ๋ค์ ๊ธฐ์ค์ด ์ผ์นํ์ง ์์์ โ ์ด๋ฒ๋ฌ ์ถ์๋ฅ (์ค๋๊น์ง ํฌํจ), ํ๋ฃจ ๋ชฉํ ๋ฌ์ฑ๋ฅ (์ด์ ), ์ฃผ๊ฐ ๋ชฉํ ๋ฌ์ฑ๋ฅ (์ด์ ๊น์ง)
- ๋ณ๊ฒฝ ํ์ : ๋ชจ๋ ์ด์ ๊น์ง๋ฅผ ๊ธฐ์ค์ผ๋ก ์ธก์ . -> ์ด๋ฒ๋ฌ ์ถ์๋ฅ ์ ์ค๋์ด ์๋ ์ด์ ๊น์ง๋ง ํฌํจํ๋๋ก
- ํด๊ฒฐ
- ์ด๋ฒ๋ฌ ์ถ์๋ฅ ์ ํฌํจ๋๋ ๋ฒ์๋ฅผ ์ค๋์์ ์ด์ ๊น์ง๋ง ํฌํจ
-
DB ์์ฒด์ ์กฐํ๋ฅผ ํตํด์๋ ํ ์ ์์ง๋ง, ์ด๋ฏธ ์ค๋๊น์ง์ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๊ธฐ์, ๋ถ๋ฌ์จ ๋ฐ์ดํฐ๋ฅผ ์๋ฒ ์์ฒด์์ ํ๋จํ๋๋ก ์คํ
int focusedDay; int nowMonthPostsLen = 0; if (LocalDateTime.now().getHour() < 4) { focusedDay = LocalDateTime.now().getDayOfMonth() - 2; } else { focusedDay = LocalDateTime.now().getDayOfMonth() - 1; } for (Post post : nowMonthPosts) { if (post.getCreateTime().getDayOfMonth() > focusedDay) { break; } nowMonthPostsLen = nowMonthPostsLen + 1; }
- ์์ฒญ์๊ฐ์ ๋ฐ๋ผ ๋ฒ์๋ฅผ 1์์2๋ก ์ค์ (์ด์ ๊น์ง์ ๋ ์ง)
- ๋ํ ๋ฒ์์ ๋์ด ๋๋ focusedDay ์ดํ์ post๋ ํฌํจํ์ง ์์
- ์ด๋ ๊ฒ ํด์ ๋ฒ์๋ฅผ ํด๋น ๋ ์ง(์ด์ )๊น์ง๋ก ์ค์
- ๊ธฐ์กด์ ๋ฌธ์ ์
- #81
- ๊ธฐ์กด์ ๋ฌธ์ ์
- edit ์ javascript(ajax)์์ post ํ ๋ฐ์์ค๋ fragment๋ก replace๋ฅผ ํ์ง ๋ชปํ๋ ์ค๋ฅ ๋ฐ์
- fragment ์ค postModal id part๋ฅผ ์ฐพ์์ค์ง ๋ชปํจ (id๋ฅผ
th:id=โโpostModalโ+${post.id}โ
๋ก ์ค์ ํ์ฌ ๋ฐ์ํ ์ค๋ฅ)
- ํด๊ฒฐ
th:id=โโpostModalโ+${post.id}โ
โ id=โpostModalโ ๋ก๋ณ๊ฒฝ- [์ค์] ๊ทธ ํ replace๋ฅผ ํตํด ์์๋ฅผ ๋ฐ๊ฟ์ฃผ๊ณ ํด๋น ๋ถ๋ถ์ id๋ฅผ ์๋ก
โpostModal+post.id"
๋ก ๋ถ์ฌํจ
- ๊ธฐ์กด์ ๋ฌธ์ ์
- #79
- ๊ธฐ์กด์ ๋ฌธ์ ์
- page ๋ฒํผ์ด ์ ๋๋ก ๋์ํ์ง ์์ (๋๋ฅด๋ฉด ์๋ฌด post๋ ๋จ์ง ์๋ ์ค๋ฅ ๋ฐ์)
- page ๋ฒํผ์ด ๊ฐ์ง๋ a ์์์ href์ requestParam ์ด๋ฆ์ด ์๋ชป ์ค์ ๋จ (content๊ฐ)
- ํด๊ฒฐ
- page์ queryParameter ์์ (queryParam : content -> inputContent)
th:href="@{/ (page=${i}, focus=${nav2}, selected=${searchForm.selected}, **content**=${searchForm.inputContent})}"
โth:href="@{/ (page=${i}, focus=${nav2}, selected=${searchForm.selected}, **inputContent**=${searchForm.inputContent})}"
- ๊ธฐ์กด์ ๋ฌธ์ ์
<220803>
#29
Back
: comment ์์ ๊ธฐ๋ฅ
- #29
- ๊ธฐ๋ฅ ํ์์ฑ
- member ์ ๋ณด๋ฅผ ์์ , post๋ฅผ ์์ ํ๋ ๋ฑ ๊ธฐ์กด์ ๋ชจ๋ Entity๋ ์์ ๊ธฐ๋ฅ์ด ์์์ง๋ง, comment๋ ์์ฑ ๋ฐ ์ญ์ ๊ธฐ๋ฅ๋ฐ์ ์์์
- comment๋ ์๋ชป์์ฑํ ๊ฒฝ์ฐ ์์ ๊ธฐ๋ฅ์ ํตํด ๋ณ๊ฒฝ์ด ๊ฐ๋ฅํด์ผ ๋จ. (์ด์ ์๋ ์์ ์ ์ํ๋ค๋ฉด ์ญ์ ํ ๋ค์ ์์ฑ)
- ๊ตฌํ
- Controller
-
๋๊ธ ์์ Form ์์ฒญ
// ๋๊ธ ์์ get @GetMapping("/comment/api/edit/{id}/{commentId}") public String editForm(@PathVariable("id") Long postId, @PathVariable("commentId") Long commentId, @SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) Long loginMemberId,Model model) { Post post = postService.findOne(postId); PostViewDto postViewDto = new PostViewDto(post); Comment comment = commentService.findOne(commentId); CommentViewDto commentDto = new CommentViewDto(comment); model.addAttribute("post", postViewDto); model.addAttribute("check", true); model.addAttribute("comment", commentDto); return "components/commentList :: #comment"; }
- ๊ธฐ์กด์ ๋ด์ฉ์ ๋ณด์ฌ์ฃผ๊ธฐ ์ํด ํด๋น id๋ฅผ ๊ฐ์ง comment๋ฅผ ๊ฐ์ ธ์ model์ ๋ฃ์ด์ค
- post์์ comment๋ฅผ ๋ณด์ฌ์ฃผ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ํด๋น comment๋ฅผ ๊ฐ์ง๊ณ ์๋ post๋ model์ ๋ด์์ค
-
๋๊ธ ์์
@PostMapping("/comment/api/edit/{id}/{commentId}") public String edit(@PathVariable("id") Long postId, @PathVariable("commentId") Long commentId, @SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) Long loginMemberId, Model model, @RequestParam Map<String, Object> paramMap) { Member member = memberService.findOne(loginMemberId); Post post = postService.findOne(postId); commentService.edit(commentId, paramMap.get("comment").toString()); PostViewDto postViewDto = new PostViewDto(post); MemberDto memberDto = new MemberDto(member); model.addAttribute("post", postViewDto); model.addAttribute("check", true); model.addAttribute("member", memberDto); return "components/commentList :: #commentPart"; }
- ๊ธฐ์กด์ ์๋ก์ด ๋๊ธ ์์ฑ๊ณผ ๋น์ทํ ์๋ฆฌ๋ก ์งํ (ํด๋น post์ comment๋ค์ ์๋ก ๋ถ๋ฌ์ redering ํ ํด๋น commentPart๋ฅผ replaceํ๋ ๊ฒ)
- ํ์ง๋ง ๋ค๋ฅธ ์ ์ save๊ฐ ์๋ edit
-
commentService.edit()
public void edit(Long id, String content) { Comment comment = em.find(Comment.class, id); comment.editContent(content); }
- ํด๋น comment๋ฅผ ๊ฐ์ ธ์ content์ ๋ด์ฉ์ ์์ ํด์ค (์๋ก ์ ์ฅ) โ
editContent
:this.content = content;
- ์ค์ํ ์ ์ ์ด๋ ๊ฒ ์์ ํ ์๋ก post์ ์ฐ๊ฒฐํ ํ์๊ฐ ์์. ์ด๋ฏธ ์ฐ๊ฒฐ๋์ด ์๊ธฐ์.
- ํด๋น comment๋ฅผ ๊ฐ์ ธ์ content์ ๋ด์ฉ์ ์์ ํด์ค (์๋ก ์ ์ฅ) โ
-
- Controller
- ๊ธฐ๋ฅ ํ์์ฑ
<220802>
#3
Back
: post ๊ฒ์ (ํํฐ๋ฅผ ํตํด -> ์กฐ๊ฑด[์ ๋ชฉ,์ด๋ฆ,ํฌ๋ง์ง๋ฌด,๋ด์ฉ])
#76Back
: member ๊ฒ์ (ํํฐ๋ฅผ ํตํด -> ์กฐ๊ฑด[์ด๋ฆ, ํฌ๋ง์ง๋ฌด])
#8Enhancement
: error page ์์ฑ (error.html, error/4xx.html, error/5xx.html)
#77Bug
: edit ์ search bar์ simpleMDE๊ฐ ์๊ธฐ๋ ์ค๋ฅ
- #3, #76
- ๊ธฐ๋ฅ ํ์์ฑ
- ํ์ฌ๊น์ง๋ ๊ทธ๋ฅ ํด๋น ๋ฉ๋ด(์ ์ฒด๊ธ, ๋์๊ธ, ์ค๋์๊ธ ๋ฑ)์ ๋ง๋ ๋ชจ๋ ๊ธ๋ค์ ๋ณด์ฌ์ค
- ํ์ง๋ง, ๊ฒ์์ ํตํด ์ํ๋ ๊ธ์ ํํฐ๋งํ์ฌ ๋ณด๋ ๊ธฐ๋ฅ์ ๋น์ฐํ ํ์
- ์ฌ๊ธฐ์ ๊ฒ์ ์, ์กฐ๊ฑด์ ๋ฌ์ ์ธ๋ถ์ ์ผ๋ก ๊ฒ์ํ ์ ์๋๋ก ํ๋ ๊ฒ์ด ํ์
- ์ถ๊ฐ๋ก ๋ฉค๋ฒ ๊ฒ์๋ ํ์
- ํด๊ฒฐ ๋ฐ ๊ตฌํ
- search bar๋ฅผ ๋ง๋ค๊ณ ํด๋น search bar ์ข์ธก์ ์กฐ๊ฑด[์ ๋ชฉ,์ด๋ฆ,ํฌ๋ง์ง๋ฌด,๋ด์ฉ]์ ์ ํํ์ฌ ๊ฒ์ํ ์ ์๋๋ก ์ค์
- ํด๋น form์์ ์ฌ์ฉ๋ Object(
SearchForm
)๋ฅผ HomeController์์ ๋ณด๋ด์ค ํ ํด๋น SearchForm์selected
(์กฐ๊ฑด),inputContent
(๊ฒ์๋ด์ฉ) ์ ๋ฐ์์ ๊ฒ์ ์งํ @ModelAttribute(name = "searchForm") SearchForm searchForm
- ReqeustMapping์ผ๋ก ์งํ, GetMapping์์๋ ModelAttribute์ ๊ธฐ๋ฅ์ ํตํด serachForm์ ์๋ก ๋ง๋ค์ด model์ ํฌํจ์์ผ์ฃผ์ด ๋๊ธฐ๋ฉฐ, PostMapping ๋๋ ModelAttribute๋ฅผ ํตํด selected์ inputContent์ ์
๋ ฅ๋ ๊ฐ์ ๋ฐ์์ด โ GET๊ณผ POST๋ฅผ ๋ถ๋ฆฌํ์ง ์์๊ธฐ์ ์ถ๊ฐ์ ์ธ ์ฝ๋ฉ์ด ํ์ํ์ (searchForm์ด ์ด๊ธฐํ๊ฐ ๋์ง ์์ ์ํ ํ๋จ (
if (searchForm.getSelected() == null)
) โ GET, searchForm์ด ์ด๊ธฐํ โ POST) -
์ด๋ฅผ ์ด์ฉํ์ฌ form html ์์ฑ
<form id="search-form" class="d-flex px-1" th:object="${searchForm}"> <input hidden id="focus" name="focus" th:value="${nav2}"/> <select th:field="*{selected}" class="form-select form-select-sm" aria-label=".form-select-lg example" style="width: 35%"> <option th:if="${nav2 != 'all-members'}" selected value="title">์ ๋ชฉ</option> <option th:if="${nav2 != 'my-posts'}" value="writer">์ด๋ฆ</option> <option th:if="${nav2 != 'my-posts'}" value="desiredJob">ํฌ๋ง์ง๋ฌด</option> <option th:if="${nav2 != 'all-members'}" value="content">๋ด์ฉ</option> </select> <input type="search" th:field="*{inputContent}" class="form-control" th:placeholder="'['+ ${nav2} + ']' + ' ์์ ๊ฒ์'"/> <button type="submit" class="btn btn-secondary"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-search" viewBox="0 0 16 16"> <path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z"/> </svg> </button> </form>
- selected ์ inputContent๋ฅผ th:field๋ฅผ ํตํด ์ฐ๊ฒฐ
- [์ค์] ์ถ๊ฐ๋ก Mapping๋ Controller๋ focus request param๊ฐ์ ์๊ตฌํ๊ธฐ ๋๋ฌธ์ ํ์ฌ focus๋ฅผ ๋ด์ ๊ฐ์ด form์ผ๋ก ์ ํด์ค
- ์ค์ํ ์ ์ ๊ฐ ๋ฉ๋ด์ ๋ง๊ฒ ๊ฒ์์ด ์งํ๋๋ฉฐ, ํ์ด์ง๊น์ง ์ ์ฉ์ด ๋์ด์ผ ํ๋ค๋ ์
- all, today, my-posts, members ์ ๋ฉ๋ด์ ๋ง๊ฒ ๊ฒ์์ด ์งํ๋์ด์ผ ํจ
- all,today ์์๋ ๋ชจ๋ ์กฐ๊ฑด(ํํฐ) ์ฌ์ฉ ๊ฐ๋ฅ
- my-posts ์์๋ ์ด๋ฏธ ์ด๋ฆ๊ณผ ํฌ๋ง์ง๋ฌด๋ ์ ํด์ ธ์๊ธฐ ๋๋ฌธ์ [์ ๋ชฉ, ๋ด์ฉ] ํํฐ๋ง ์ ์ฉ ๊ฐ๋ฅ
- members ์์๋ ๊ธ์ด ์๋๋ฏ๋ก [์ด๋ฆ, ํฌ๋ง์ง๋ฌด]๋ก๋ง ๊ฒ์ ๊ฐ๋ฅ. (ํ์ด์ง๋ ์ ์ฉX)
- ์ด์ Controller, Service์์๋ ํ์ฌ ๋ฉ๋ด์ ๋ค์ด์ค๋ ํํฐ ์กฐ๊ฑด, ๊ฒ์๋ด์ฉ์ ๋ฐ๋ผ ๋ค๋ฅธ ์ฟผ๋ฆฌ ์ ์ฉ [๋ถ๊ธฐ ์์ : menu โ selectedโ searchContent]
- ๋ํ query ์ ์ฉ ์ like์ ์ฌ์ฉํ๊ณ ํด๋น ๊ฒ์๋ด์ฉ์ ํฌํจํ๋ ๋ชจ๋ post๋ฅผ ๊ฐ์ ธ์์ผ ํ๊ธฐ ๋๋ฌธ์ โ%โ+๊ฒ์๋ด์ฉ+โ%โ ํ์ ์ ์ฉ โ
String searchKeyword = '%' + content + '%';
- today :
posts = postService.findByTodaySearch(...)
-
selected[title,writer,desriedJob,content] โ searchContent
if (selected.equals("title")) { return postNativeRepository.findByTitleToday(searchKeyword, date, offset); } else if (selected.equals("writer")) { return postNativeRepository.findByWriterToday(searchKeyword, date, offset); } else if (selected.equals("desiredJob")) { return postNativeRepository.findByJobToday(searchKeyword, date, offset); } else { return postNativeRepository.findByContentToday(searchKeyword, date, offset); }
-
today๊ฐ์ ๊ฒฝ์ฐ ๋ ์ง๊ฐ ๋ค์ด๊ฐ๊ธฐ์ native query๋ก DB ์กฐํ
-
- my-posts :
posts = postService.findBySearchMy(...)
-
selected[title,content] โ searchContent
if (selected.equals("title")) { return postRepository.findByTitleMy(memberId, searchKeyword, offset); } else { return postRepository.findByContentMy(memberId, searchKeyword, offset); }
-
my-posts๋ ๋ ์ง๊ฐ ๋ค์ด๊ฐ์ง ์๊ธฐ ๋๋ฌธ์ ์ผ๋ฐ์ ์ธ JPQL ์ฌ์ฉ
-
- all :
posts = postService.findBySearch(...)
-
selected[title,writer,desriedJob,content] โ searchContent
if (selected.equals("title")) { return postRepository.findByTitle(searchKeyword, offset); } else if (selected.equals("writer")) { return postRepository.findSearchByMember(searchKeyword, offset); } else if (selected.equals("desiredJob")) { return postRepository.findByJob(searchKeyword, offset); } else { return postRepository.findByContent(searchKeyword, offset); }
-
- members:
bySearchMembers = memberService.findBySearch(...)
-
selected[writer,desriedJob] โ searchContent
if (selected.equals("writer")) { return memberRepository.findSearchByName(searchKeyword); } else { return memberRepository.findSearchByJob(searchKeyword); }
-
- ๋ํ query ์ ์ฉ ์ like์ ์ฌ์ฉํ๊ณ ํด๋น ๊ฒ์๋ด์ฉ์ ํฌํจํ๋ ๋ชจ๋ post๋ฅผ ๊ฐ์ ธ์์ผ ํ๊ธฐ ๋๋ฌธ์ โ%โ+๊ฒ์๋ด์ฉ+โ%โ ํ์ ์ ์ฉ โ
- [์ค์] ๋ํ ์ด๋ฐ ๊ฒ์ ๊ธฐ๋ฅ์์ ํ์ด์ง ๋๊ธฐ๋ ๊ธฐ๋ฅ์ ์ ์ฉํ๊ธฐ ์ํด page index ๋ฒํผ์ request param([ํ์ฌ๋ฉ๋ด, ์ ํ๋ ํํฐ, ๊ฒ์ ๋ด์ฉ])์ ํฌํจ โ
th:href="@{/ (page=${i}, focus=${nav2}, selected=${searchForm.selected}, inputContent=${searchForm.inputContent})}"
- ๊ธฐ๋ฅ ํ์์ฑ
- #8
- ๊ธฐ๋ฅ ํ์์ฑ
- error๊ฐ ๋ฐ์ํ์ ๋, Spring ๊ธฐ๋ณธ error page๊ฐ ๋์์ ์ด์ง๊ฐ์ ์คฌ์
- ์ง์ ๊ฐ๋ฐํ error page๋ฅผ ๋ณด์ฌ์ค์ผ๋ก์จ ์ด๋ค ์ค๋ฅ์ธ์ง ์๋ดํ๊ณ ๋ค๋ฅธ ํ์ด์ง๋ก ์ฝ๊ฒ ์ด๋ ๊ฐ๋ฅ ํ์
- ํด๊ฒฐ
- Spring์์๋ ์๋์ผ๋ก ์๋ฌํ์ด์ง๋ฅผ ์ฐ๊ฒฐํ๋ ๊ธฐ๋ฅ์ด ์์ผ๋ฉฐ, ๊ทธ ๊ธฐ๋ฅ์ ์ด์ฉ
- templates/error/4xx.html โ 400, 404 ๋ฑ Error Code๊ฐ 4๋ก ์์ํ๋ ์๋ฌ๋ค์ ๋ํด ํด๋น html๋ก ์ฐ๊ฒฐ
- templates/error/5xx.html โ 500, 505 ๋ฑ Error Code๊ฐ 5๋ก ์์ํ๋ ์๋ฌ๋ค์ ๋ํด ํด๋น html๋ก ์ฐ๊ฒฐ
- templates/error.html โ ๊ธฐ๋ณธ ์๋ฌํ์ด์ง. ์์ ํด๋น๋์ง ์๋ Error Code๋ค์ ๋ํด ์ฐ๊ฒฐ
- ๊ณ ๋ก ํด๋น html ํ์ผ์ ์ฌ์ฉ์์นํ์ ์ผ๋ก ๋ง๋ค์ด ํด๋น ๊ท์น์ ๋ง๊ฒ ์ค์ .
- ๊ธฐ๋ฅ ํ์์ฑ
- #77
- ์ค๋ฅ ํญ๋ชฉ
- post edit์ ๋๋ฅผ ์ ๋์ ์ผ๋ก ํ์ด์ง๋ฅผ ๋ฐ์์ค๋ ๋ฐ, ์ด๋ post modal์์ ์งํ๋๋ ๊ฒ์ด ์๋ search bar์ input ์ editor๊ฐ ๋ค์ด๊ฐ๊ฒ ๋จ.
- ๋ฌธ์ ์์ธ : input ํ๊ทธ์ searchForm์ field์ ์ด๋ฆ์ content๋ก ์ค์ ํ๊ณ ์ด๋ฅผ th:field๋ก ๋ฐ์์ค๋ฉด์ ํด๋น ํ๊ทธ๊ฐ content์ id๋ฅผ ๊ฐ์ง๊ฒ ๋๊ณ , MDE๊ฐ content์ mapping๋์ด ์์๊ธฐ์ ํด๋น inputํ๊ทธ์ mde๊ฐ ๋ฌ๋ฆฌ๊ฒ ๋จ
- ํด๊ฒฐ
- searchForm์ field๋ฅผ inputContent๋ก ๋ณ๊ฒฝ (
searchForm.content โ searchForm.inputContent
)
- searchForm์ field๋ฅผ inputContent๋ก ๋ณ๊ฒฝ (
- ์ค๋ฅ ํญ๋ชฉ
<220801>
#46
Enhancement
: post edit์์ ์๊ฐ ์์ (์๊ฐ ์ถ๊ฐ ๋ฐ ์ญ์ )
#52Enhancement
: older page ๊ธฐ๋ฅ ์ถ๊ฐ
- #46
- ๊ธฐ๋ฅ ํ์์ฑ
- ์๊ฐ์ ๋ณ๊ฒฝํ ์๋ ์์์ง๋ง, ์๊ฐ์ ์ถ๊ฐํ๊ฑฐ๋ ์ญ์ ํ๋ ๊ธฐ๋ฅ์ด ์์์
- Breaking์ ์๋ชป๋๋ฌ, ์ธ๋ฐ์์ด ์๊ฐ์ด ๊ธฐ๋ก๋๊ฑฐ๋ ์๊ฐ์ ์๋ชป ์ถ๊ฐํ ๊ฒฝ์ฐ๋ค์ด ์์
- ๋ํ ์ฐ ๊ฒ์ ๊ธฐ๋กํ์ง ์์ ๋๋ ์๊ฐ๋ณ๊ฒฝ์ ์ํด breaking์ ๋๋ ๋ค๊ฐ ์๊ฐ์ ์์ ํด์ผ ๋๋ ๋ถํธํจ ์กด์ฌ
- ํด๊ฒฐ
- edit์ ํตํด ์๊ฐ์ ์ถ๊ฐํ๊ฑฐ๋ ์ญ์ ํ ์ ์๋๋ก ์ค์
-
์ด๋, ํ์ฌ ์ํ์ ๋ง์ง ์๋ ์๊ฐ์ ๊ฐ์๋ก ์ค์ ๋ ๋ ์๋ฆผ์ ํตํด ์ ๋๋ก ์์ ํ ์ ์๋๋ก ์ ๋ (ex_ STUDYING ์ํ์ธ๋ฐ [12:00] ~ [13:00] ์ฒ๋ผ ๊ณต๋ถ๊ฐ ๋ง๋ฌด๋ฆฌ๋์ด ์๊ฒ ์๊ฐ์ด ์ค์ ๋์ด ์๋ค๋ฉด, ๋ค์ ์์ ํ ์ ์๋๋ก alert ์๋ฆผ)
if (state == 'STUDYING' & times_len % 2 == 0) { alert("[STUDYING] ์ํ์ ๋๋ค. ์๊ฐ ๊ฐ์๋ฅผ ํ์ธํด์ฃผ์ธ์!"); var times_id = "times" + (times_len-1); var timeInput = document.getElementById(times_id); timeInput.setAttribute('class','form-control is-invalid'); document.getElementById("postEdit_container").scrollIntoView(); } else if ((state == 'BREAKING' || state == 'END') & times_len % 2 != 0) { alert("[BREAKING] ํน์ [END] ์ํ์ ๋๋ค. ์๊ฐ ๊ฐ์๋ฅผ ํ์ธํด์ฃผ์ธ์!"); var times_id = "times" + (times_len-1); var titleHtml = document.getElementById(times_id); titleHtml.setAttribute('class', 'form-control is-invalid'); document.getElementById("postEdit_container").scrollIntoView(); } else { $.ajax({ url: '/posts/edit/' + id, type: "POST", data: formData }).done(...) }
-
์ถ๊ฐ๋ก ๋น์ด์๋ ์ํ๋ก ์๊ฐ์ ์์ ํ๋ฉด ๋น ์๊ฐ์ ์๋์ผ๋ก ์ญ์ ๋๋๋ก ์ค์
List<String> times = postEditForm.getTimes(); while (times.remove("")) {}
- ๊ธฐ๋ฅ ํ์์ฑ
- #52
- ์ถ๊ฐ ์์ ํ์ ๋ถ๋ถ
- ํ์ฌ๊น์ง๋ ๊ทธ๋ฅ older page๋ก ๋ค์ ํ์ด์ง๋ก ๋์ด๊ฐ๋ ๊ฒ๋ง ์ ์ฉ.
- ์ฆ, 1~5page ๊น์ง๋ ์ ํํ์ฌ ๋ณผ ์ ์์์ง๋ง, 6page ๋ถํฐ๋ older page๋ฒํผ์ ๋๋ฌ์ ํ๋ํ๋์ฉ ๋ค์ํ์ด์ง๋ก ๋๊ฒจ์ผ์ง ํ์ธํ ์ ์์์
- ํด๊ฒฐ (์์ )
- 1~5p ์์ 6p ๋ก ๋์ด๊ฐ๋ฉด page index ๊ฐ 6~10๋ก ์ค์ ๋ ์ ์๋๋ก ์ค์
- ๋ํ 7p๋ 6~11 ๋ฒ์์ ์๊ธฐ์ 7p์์๋ 6~11p ์ ์ธ๋ฑ์ค๋ก ๋ณด์ฌ์ง ์ ์๋๋ก ์ค์
- page ๊ฐ์ ์ด์ฉํ์ฌ ์ธ๋ฑ์ค ๊ณ์ฐ ์คํ
th:each="i: ${#numbers.sequence(5*((page -1)/5)+1, 5*((page -1)/5)+5)}"
- 1~5, 6~10, 12~16 ๋ฑ ๋ฒ์๋ณ๋ก 5๋ก ๋๋๋์ ๋ชซ์ด ๊ฐ๋ค๋ ์ ์ ์ด์ฉํ์ฌ ์์ ์ค์ โ page ๊ฐ์์ 1์ ๋บ ๊ฐ์ 5๋ก ๋๋ ๋ชซ์ 5๋ฅผ ๊ณฑํ๊ณ 1~5์ ๋ํด ์ค์ .
- ์ถ๊ฐ ์์ ํ์ ๋ถ๋ถ
<220728>
#69
Bug
: post_times DB ์ ์ฅ ์ค๋ฅ
#71Bug
: ์ธ์ฆ์ ๋ฐ๋ฅธ html ์ค๋ฅ ๋ณ๊ฒฝ
#59Enhancement
: ํ๋ฃจ ๋ชฉํ ์๊ฐ์ ๋ฐ๋ฅธ ์๋ฆผ
- #69
- ๊ธฐ์กด์ ๋ฌธ์ ์
- 4์,5์์ ๋ํ post๋ค์ ์ ์ฅ๋ post_times๊ฐ ์ค๋ณต๋์ด ์ ์ฅ๋์ด ์์ด์ ์๊ฐ๊ณ์ฐ๋ฑ์์ ๊ธฐ์กด์ 2๋ฐฐ์ ์๊ฐ์ผ๋ก ๊ธฐ๋ก๋จ โ ex) [12:00~15:00] [16:00~17:30] [12:00~15:00][16:00~17:30] ๊ณผ ๊ฐ์ด ์ค๋ณต๋์ด ์ ์ฅ.
- ์ด๋ ๊ฒ ๋๋ฉด ์ ์ฒด ๊ณต๋ถ ์๊ฐ, ์๋ณ ๊ณต๋ถ์๊ฐ ๋ฑ ํต๊ณ์๋ฃ์ ์ํฅ์ ๋ฏธ์นจ
- ํด๊ฒฐ
- DBM ์์ ์์ ํ๋ ค ํ์ง๋ง, post_times๊ฐ Embedded Type์ผ๋ก ์ ์ฅ๋์ด ์๊ธฐ ๋๋ฌธ์, unique key๊ฐ ์์ด์ ์ญ์ ์ ๋ชจ๋ post_times๊ฐ ์ญ์ ๋๋ ํ์ ๋ฐ์
-
Spring ๋ด์์ ์ฝ๋๋ก ์ง์ ์์ ํ๋ ๋ฐฉ์ ์ ํ
@Component @RequiredArgsConstructor public class DbChange { private final InitService initService; @PostConstruct public void dbInit() { initService.dbInit1(); } @Component @Transactional @RequiredArgsConstructor static class InitService { private final MemberService memberService; private final PostNativeRepository postNativeRepository; private final PostService postService; public void dbInit1() { // 4/1 ~ 5/31 List<Member> all = memberService.findAll(); for (Member member : all) { List<Post> posts = postNativeRepository.getBetween(member.getId(), "2022-04-17", "2022-06-01"); for (Post post : posts) { Post one = postService.findOne(post.getId()); List<String> times = one.getTimes(); List<String> newTimes = new ArrayList<>(); for (String time : times) { if (newTimes.contains(time)) { break; } newTimes.add(time); } one.setTimes(newTimes); } } } } }
- ํด๋น ๋ก์ง์ด ์ด๋ฃจ์ด์ง Class๋ฅผ Component๋ก ๋ฑ๋กํ๊ณ PostCostruct๋ฅผ ํตํด ํ๋ก๊ทธ๋จ์ด ์์๋์ ๋ง์ ํด๋น ๋ก์ง์ด ์งํ๋ ์ ์๋๋ก ์ค์
- ๋ก์ง
- ๋ชจ๋ ๋ฉค๋ฒ๋ค์ ๋ํด ์งํ
- ํด๋น ๋ฉค๋ฒ์ 4/1 ~ 5/31 ์ post๋ฅผ ๊ฐ์ ธ์จ ํ
- ํด๋น post๋ค ์ค ์ค๋ณต๋๋ ๊ฐ์ด ๋์ฌ๋๊น์ง ๋ฐ๋ณต์ ์งํํ๋ฉฐ ์๊ฐ์ renew ํ ํ ์ ์ฅ
- ๊ธฐ์กด์ ๋ฌธ์ ์
- #71
- ๊ธฐ์กด์ ๋ฌธ์ ์
- my post์ ๋์ผํ html์ ์ฌ์ฉํ๋ค๋ณด๋ member detail ํ๋ฉด ์์๋ ์ธ์ฆ์์ด post edit, ๋๊ธ ์ธ์ฆ ๋ฑ์์ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๊ฒ๋จ
- ํด๊ฒฐ
- ๊ฐ ์ํฉ์ ๋ฐ๋ผ ์ธ์ฆ์ ์งํํ ํ post, comment ์์ ๋ฐ ์ญ์ ๋ฑ์ ์ ์ฉ
- ๊ธฐ์กด์ ๋ฌธ์ ์
- #59
- ๊ธฐ๋ฅ ํ์์ฑ
- ๋ชฉํ์๊ฐ์ ๋๊ธฐ์ง ๋ชปํ์ ๋ ๋๊ธฐ๋ถ์ฌ๋ฅผ ์ฃผ๊ธฐ ์ํจ
-
๊ตฌํ
function check_end(memberId) { $.ajax({ url: '/members/times/' + memberId, type: "GET" }) .done(function (response) { var currTotal = response.hour * 60 + response.min; if (currTotal < memberTodayGoalTotal) { var timeDiff = memberTodayGoalTotal - currTotal; var check = confirm("์์ง ๋ชฉํ ์๊ฐ์ ๋๋ฌํ์ง ๋ชปํ์ จ์ต๋๋ค. (" + Math.floor(timeDiff / 60) + "์๊ฐ " + timeDiff % 60 + "๋ถ ๋ถ์กฑ)\n์ฌ์ฉ์ ์ข ๋ฃํ์๊ฒ ์ต๋๊น?"); if (check) { window.location.href = "/end"; } } else { window.location.href = "/end"; } }) }
- javascript, ajax ํต์ ์ ์ด์ฉํ์ฌ ๋ชฉํ์๊ฐ๋ณด๋ค ์์ ๊ฒฝ์ฐ alert์ ํตํด ์๋ฆผ์ ์ค
- ๊ทธ๊ฒ ์๋๋ผ๋ฉด ๊ทธ๋ฅ ๋ฐ๋ก โ/endโ ๋ฅผ ํตํด ๊ณต๋ถ ์ข ๋ฃ ์งํ
- ๊ธฐ๋ฅ ํ์์ฑ
<220727>
#58
Enhancement
: ์๋จ๋ฐ ๋ฉ๋ด(all-members) ๋ฐ ๋ฉค๋ฒ ์์ธํ๋ฉด ์ค์
- #58
- ๊ธฐ๋ฅ ํ์์ฑ
- ๋ฉค๋ฒ๋ค์ ๋ํ ํ๋กํ์ ๋ณผ ์ ์๋ ํ๋ฉด์ด ์์์
- all-members ๊ธฐ๋ฅ์ ํตํด ๊ธฐ๋ณธ์ ์ธ ๊ฐ๋จํ ๋ชจ๋ ๋ฉค๋ฒ์ ํ๋กํ ํ์ธํ ์ ์๋๋ก ์ค์
- ๋ ํด๋น ํ๋กํ์ ํด๋ฆญํ๋ฉด ํ์์ ์์ธ ์ ๋ณด (ํต๊ณ์๋ฃ, ๋ชฉํ, ๊ณต๋ถ ์บ๋ฆฐ๋) ๋ฑ์ ํ์ธํ ์ ์๊ฒ ์ค์
- ๊ตฌํ
- ๊ธฐ๋ณธ โ/โ ์ mapping ๋ controller์์ ๋ชจ๋ ๋ฉค๋ฒ๋ฅผ ์ด๋ฏธ ๋๊ธฐ๊ณ ์์๊ธฐ์ ํด๋น ์ ๋ณด๋ฅผ ์ด์ฉํด์ view Template์์ ์ผ๋ถ๋ง์ ์์ ํ์ฌ ์งํ
-
focus request parameter๊ฐ all-members๋ฉด post๋ฅผ renderingํ์ง์๊ณ ํด๋น ์์น์ ๋ชจ๋ ๋ฉค๋ฒ์ ํ๋กํ์ ๋ณด์ผ ์ ์๋๋ก ์ค์ . (all-members๊ฐ ์๋๋ฉด post(all, today, my-posts) rendering)
<div class="col-lg-5 mb-4" th:if="${nav2 == 'all-members'}" th:each="mem:${allMembers}"> <!-- All Members --> <div id="profile" class="card shadow"> <div class="card-header d-sm-flex justify-content-between"> <div style="margin-top: 5px" class="input-group"> <h6 class="m-0 font-weight-bold"> <span class="ml-1 h5 fw-bold">ํ๋กํ</span></h6> ... </div> </div> </div>
- ๊ธฐ๋ฅ ํ์์ฑ
<220726>
Article Nav๋ฐ(All Members) ์๋น์ค
#58Enhancement
: ์๋จ๋ฐ ๋ฉ๋ด (my-posts ์ธํฐ์ ํฐ, all-members)
#70Bug
: Interceptor ์ค๋ฅ
- #58
- ๊ธฐ์กด์ ๋ฌธ์ ์
- ์๋จ๋ฐ ๋ฉ๋ด์์ my-posts ๊ฐ์ ๊ฒฝ์ฐ, ๋ก๊ทธ์ธ๋ ํ์์ ์ ์ฒด posts๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์, my-posts์ ๋ค์ด๊ฐ ๊ฒฝ์ฐ ์ธํฐ์ ํฐ๋ฅผ ์ ์ฉํด์ค์ผ ๋จ
- ๋ํ, redirect๋ฅผ ํตํด ๋ก๊ทธ์ธ ํ ๋ค์ my-posts๋ก ๋์ด๊ฐ ์ ์๋๋ก redirectURL ํฌํจ ํ์
- ํด๊ฒฐ
- WebConfig ์ ์ธํฐ์
ํฐ ์ ์ฉ URL์ โ/โ๋ฅผ ์ถ๊ฐํ๊ณ focus @RequestParam ์ด โmy-postsโ์ธ ๊ฒฝ์ฐ๋ง ๋ก๊ทธ์ธ์ธ์ฆ์ด ์งํ๋ ์ ์๋๋ก ์ค์ โ
.addPathPatterns("/members/my-page", "/members/edit/**", "/");
-
Spring Interceptor ์ ์ฉ ์ ํฌํจ Url๊ณผ ์ ์ธ Url์ ์ค์ ์ด ๊ฐ๋ฅํ์ง๋ง, request param๊ณผ ๊ฐ์ parameter ํํฐ๋ง์ ์ง์ํ์ง ์์ Interceptor ๋ด์ request๋ฅผ ํตํด parameter๋ฅผ ์ง์ ๋ฐ์์ ๋ก์ง์ ๊ตฌ์ฑํด์ค์ผ๋จ
String requestURI = request.getRequestURI(); String focus = request.getParameter("focus"); if (requestURI.equals("/")) { if (focus == null || !focus.equals("my-posts")) { // basic home -> / or parameters -> focus=all, today, all-members return true; } } // my-posts ๋ง ๋ก๊ทธ์ธ ์ธ์ฆ ์งํ
- โ/โ url์ ๋ํด์ focus paramter๊ฐ my-posts๊ฐ ์๋ ๋ชจ๋ url์ true๋ฅผ ํตํด ๋ก๊ทธ์ธ์ธ์ฆ์ ์งํํ์ง ์์
- WebConfig ์ ์ธํฐ์
ํฐ ์ ์ฉ URL์ โ/โ๋ฅผ ์ถ๊ฐํ๊ณ focus @RequestParam ์ด โmy-postsโ์ธ ๊ฒฝ์ฐ๋ง ๋ก๊ทธ์ธ์ธ์ฆ์ด ์งํ๋ ์ ์๋๋ก ์ค์ โ
- ๊ธฐ์กด์ ๋ฌธ์ ์
- #70
- Bug : ์ถ๊ฐ์ ์ธ ๋ก์ง์ ๋ฐ๋ผ My Page๊ฐ ๋ค์ด๊ฐ์ง์ง ์์์ง
- ํด๋น ๋ก์ง์ ์ง๋ ๊ณผ์ ์์ ๊ธฐ์กด์ My Page์ ๋ํ Interceptor ์ค๋ฅ๊ฐ ๋ฐ์ โ url๊ณผ request param ํ์ ๊ณผ์ ์์์ ์ค์ ํด๊ฒฐ (์กฐ๊ฑด๋ฌธ ์ค์)
<220725>
Article Nav๋ฐ(All, Today, My Posts) ์๋น์ค
#58Enhancement
: ์๋จ๋ฐ ๋ฉ๋ด ๊ฐ๋ฐ
#44Enhancement
: Today ํ์ฑํ
- #58, #44
- ๊ฐ๋ฐ ํ์์ฑ
- ํ์ฌ ๋ชจ๋ Post๋ค์์ ํ์ธํ ์ ์์ง๋ง, ์ค๋ ์์ฑ๋ Post, ๋์ Post๋ฑ ์กฐ๊ฑด์ ๋ฐ๋ฅธ post๋ฅผ ๋ณด์ฌ์ค ํ์๊ฐ ์์
- ์ฆ, ํํฐ๋ง๋ Post๋ค์ ๋ํด์ ๋ณด์ฌ์ค ํ์ ์กด์ฌ
- ๊ตฌํ
- ์ด๋ค์ Nav๋ฐ๋ฅผ ํตํด All(๋ชจ๋ Posts), Today(์ค๋์ Posts), My Posts(๋์ ๋ชจ๋ Posts) ๋ฅผ ์ ํํ์ฌ Post๋ค์ ๋ณผ ์ ์์
-
์ด๋ค์ @RequestParam์ผ๋ก ๊ตฌ๋ถ โ
@RequestParam(name = "focus", defaultValue = "all") String focus
(all, today, my-posts)if (focus.equals("today")) { DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); LocalDateTime now = LocalDateTime.now(); String date = now.format(dateTimeFormatter); if (now.getHour() < 4) { date = now.minusDays(1).format(dateTimeFormatter); } posts = postService.getTodayPosts(date, (page - 1) * 12); } else if (focus.equals("my-posts")) { posts = postService.getMemberPosts(loginMemberId, (page - 1) * 12); } else { posts = postService.findByPage((page - 1) * 12); }
- ์ฌ๊ธฐ์ all,today,my-posts ์ ๋ฐ๋ผ repository์์ ๊ฐ์ ธ์ค๋ post๊ฐ ๋ค๋ฆ
- ๋ํ ์ฌ๊ธฐ์ paging๊ธฐ๋ฅ๋ ์๊ธฐ ๋๋ฌธ์, ๊ฐ ์กฐ๊ฑด์ ๋ฐ๋ฅธ post์ ๋๋ถ์ด paging๊ธฐ๋ฅ๊น์ง ์ ์ฉํ์ฌ repository์์ ๊ฐ์ ธ์ฌ ์ ์๋๋ก ์ค์
- ๊ฐ์ ธ์จ ํ ๋๊ฐ์ด home.html์ rendering โ ๋ชจ๋ posts๋ก viewTemplate์ ๋ณด๋ด์ง
- ์ถ๊ฐ๋ก today๋ ์์ฒญ ์๊ฐ์ ๋ฐ๋ผ ์ค์ ๋๋ ๋ ์ง๋ฅผ ์ง์
- 0~4 ์์ฒญ : ์ ๋ ๊ธ
- 4~24 ์์ฒญ : ๋น์ผ ๊ธ
- ๊ฐ๋ฐ ํ์์ฑ
<220723>
#55
Back
: ๋ชฉํ ์ค์
#52Back
: older page
- #55
- ๊ธฐ๋ฅ ํ์์ฑ
- ๋ชฉํ๋ฅผ ์ค์ ํด์ ํด๋น ๋ชฉํ์ ๋ค๋ฅธ ๋ฌ์ฑ๋ฅ ๋ฑ์ ์๋ ค์ฃผ๋ฉฐ ๊ณต๋ถ ๋๊ธฐ ๋ถ์ฌ๋ฅผ ์ค ํ์๊ฐ ์์
- ๊ตฌํ
- ๋ชฉํ๋ Member์ ๋ฐ๋ผ ์ค์ ๋์ด์ผ ํ๋ฏ๋ก Member ๊ฐ์ฒด์ ๋ชฉํ๊ฐ์ ์ ํ ์ ์๋ Goal ๊ฐ์ฒด field ์ถ๊ฐ (Embedded Type)
-
Goal
@Embeddable @Getter public class Goal { private int dayGoalTimes; private int weekGoalTimes; public Goal(int day, int week) { this.dayGoalTimes = day; this.weekGoalTimes = week; } public Goal() { } }
int dayGoalTimes
: ํ๋ฃจ ๋ชฉํ ๊ณต๋ถ์๊ฐint weekGoalTimes
: ์ผ์ฃผ์ผ ๋ชฉํ ๊ณต๋ถ์๊ฐ- Entity์ Embedded Type์ผ๋ก ์ ์ฅ๋๊ธฐ ๋๋ฌธ์ Custom ๊ฐ์ฒด์ธ Times๋ก ์ ์ฅ์ด ์๋จ โ ํด๋น ๊ฐ์ ๋ถ(int)์ผ๋ก ๋ฐ๊ฟ์ ์ ์ฅ
-
- ์๋ก์ด Member๊ฐ ์์ฑ๋ ๋, ๊ธฐ๋ณธ์ ์ธ ๋ชฉํ์๊ฐ์ด ์ ํด์ง ์ํ๋ก ์ ์ฅ๋ ์ ์๋๋ก ์ค์ โ
member.setGoal(new Goal(300, 1500));
- ์ถ๊ฐ๋ก ๋ชฉํ ์ค์ ์ My Page์์ ๊ฐ๋ฅํ๋๋ก ์ค์
-
goal ์ค์ ์ ํธ์์ ์๊ฐ๊ณผ ๋ถ์ ๋ฐ๋ก ์ ๋ ฅ ๋ฐ์์ผ ํ๊ธฐ ๋๋ฌธ์ ๊ธฐ์กด์ Goal ๊ฐ์ฒด๊ฐ ์๋ ์ ๋ ฅ Form์ ์ํ GoalDto ์์ฑ
@Data static class GoalDto { private int dayHour; private int dayMin; private int weekHour; private int weekMin; public GoalDto(Goal goal) { int day = goal.getDayGoalTimes(); this.dayHour = Math.floorDiv(day, 60); this.dayMin = day % 60; int week = goal.getWeekGoalTimes(); this.weekHour = Math.floorDiv(week, 60); this.weekMin = week % 60; } public GoalDto() { } }
- Times๋ก ํ๋ฉด ๋๋จ๊ณ๋ก modelAttribute๊ฐ ๋์ํด์ผ๋จ โ ์ด ๋ถ๋ถ์ด ๋์ง ์์ ๋ชจ๋ ํ๋จ๊ณ์ modelAttribute๊ฐ ๋์ํ๋๋ก ๋ชจ๋ field๋ฅผ int๋ก ์ค์
-
- ๋ํ, ์ด ๋ชฉํ์ ๋ฐ๋ฅธ ๋ฌ์ฑ๋ฅ (ํ๋ฃจ ๋ชฉํ ๋ฌ์ฑ๋ฅ , ์ผ์ฃผ์ผ ๋ชฉํ ๋ฌ์ฑ๋ฅ ) ๋ณด์ฌ์ค
- ์ด์ ๋ฐ๋ฅธ ๋ญํฌ๋ ์ถ๊ฐ (๋ธ๋ก ์ฆ, ์ค๋ฒ, ๊ณจ๋, โฆ)
- ๋ชฉํ๋ Member์ ๋ฐ๋ผ ์ค์ ๋์ด์ผ ํ๋ฏ๋ก Member ๊ฐ์ฒด์ ๋ชฉํ๊ฐ์ ์ ํ ์ ์๋ Goal ๊ฐ์ฒด field ์ถ๊ฐ (Embedded Type)
- ๊ธฐ๋ฅ ํ์์ฑ
- #52
- ๊ธฐ์กด์ ๋ฌธ์ ์
- paging์ ๋ฐ๋ฅธ post๋ค์ ๋ณด์ฌ์ฃผ๊ธดํ์ง๋ง, 5ํ์ด์ง ๋๊ฒจ์์ post๋ค์ ๋ณด์ฌ์ฃผ์ง ๋ชปํ์
- older ๋ฒํผ์ด ์์์ง๋ง ํ์ฑํ๋๊ณ ์์ง ์์์
- ํด๊ฒฐ
-
older ๋ฒํผ์ ๋๋ฅด๋ฉด ์ด์ page๋ก ๊ณ์ํด์ ๋์ด๊ฐ ์ ์๋๋ก ์ค์
<ul class="pagination justify-content-center my-4"> <li class="page-item"> <a class="page-link" href="/" tabindex="-1" aria-disabled="true">Newer</a> </li> <li th:each="i: ${#numbers.sequence(5*((page -1)/5)+1, 5*((page -1)/5)+5)}" aria-current="page" th:class="${page == i}? 'page-item active' : 'page-item'"> <a class="page-link" th:href="@{/ (page=${i}, focus=${nav2})}" th:text="${i}">#</a> </li> <li class="page-item"> <a class="page-link" th:href="@{/ (page=${page+1}, focus=${nav2})}">Older</a> </li> </ul>
- ํ์ฌ focus ๋์ด ์๋ page์ 1์ ๋ํ์ฌ ๋ค์ page๋ก ๋์ด๊ฐ๋๋ก ์ค์
th:each="i: ${#numbers.sequence(5*((page -1)/5)+1, 5*((page -1)/5)+5)}"
๋ฅผ ํตํด ํ์ฌ ํ์ด์ง์ ๋ฐ๋ผ 1~5, 6~10, 11~15 ๋ฑ์ผ๋ก page index๊ฐ ๋ณด์ผ ์ ์๋๋ก ์ค์
-
- ๊ธฐ์กด์ ๋ฌธ์ ์
<220722>
My Page (๋ด ํ๋กํ) ์๋น์ค
#54Enhancement
: ๊ณต๋ถ ๋ฌ๋ ฅ ๋ฐ ํด๋น ์๋ณ ํต๊ณ
- #54
- ๊ธฐ๋ฅ ํ์์ฑ
- ์ง๊ธ๊น์ง๋ ์์ ์ด ์ผ๋ ๊ธ์ ํ์ธํ ์ ์์ผ๋ฉฐ
- ๊ทธ์ ๋ฐ๋ผ ์ผ๋ง๋ ๊ณต๋ถ๋ฅผ ํ๋์ง๋ ์ ์ ์๊ณ , ์ด๋ค ๊ณต๋ถ๋ฅผ ํ๋์ง๋ ์ ์ ์์์
- ์ด๋ฅผ ์๋ณ๋ก ์ด๋ค ๊ณต๋ถ๋ฅผ ํ๊ณ ๊ณต๋ถ๋ฅผ ์ผ๋ง๋ ํ๋์ง ํ์ธํ ์ ์๋ ์๋จ์ด ํ์
- ๊ตฌํ
- ์๋ณ๋ก ์ด๋ค ๊ณต๋ถ๋ฅผ ํ๊ณ , ํด๋น ์ผ์์ ๊ธ์ ํ์ธํ๊ณ ์์ ํ ์ ์๊ฒ๋ ๊ณต๋ถ ๋ฌ๋ ฅ ๋ฐ ํด๋น ์๋ณ ํต๊ณ ์๋น์ค ์ ๊ณต
- ๊ณต๋ถ ๋ฌ๋ ฅ
- ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ฌ์ ๋ฌ์ ๊ธฐ์ค์ผ๋ก ๋ฌ๋ ฅ์ ๋ณด์ฌ์ฃผ๊ณ , < > ๋ฒํผ์ ํตํด ๋ค๋ฅธ ๋ฌ๋ก ๋์ด๊ฐ ์ ์๊ฒ ์ค์
- ๊ฐ ๋ ์ง์ ํด๋นํ๋ post๊ฐ ์๋์ง ํ์ธ ํ ์์ผ๋ฉด ํด๋น post์ ์ ๋ชฉ์ ๋ฌ๋ ฅ์ ๋ณด์ฌ์ค
- ๋ํ, ๊ทธ ์ ๋ชฉ์ ํด๋ฆญํ๋ฉด ๋ชจ๋ฌํ์์ผ๋ก ํด๋น post๊ฐ ๋ฐ ์ ์๋๋ก ์ค์
if (month == null) { month = LocalDateTime.now().getMonthValue(); } focusedDate = LocalDateTime.of(year, month, 1, 0, 0); List<Post> monthPosts = postService.getMonthPosts(member.getId(), month); List<PostViewDto> monthPostDtos = monthPosts.stream().map(PostViewDto::new).collect(Collectors.toList()); int[] dayData = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; List<String> weekDay = Arrays.asList("sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"); List<Integer> calenderDays = new ArrayList<>(); Map<Integer, PostViewDto> calenderData = new HashMap<>(); for (int i = 1; i <= dayData[month - 1]; i++) { calenderDays.add(i); calenderData.put(i, null); } for (PostViewDto monthPostDto : monthPostDtos) { int dayOfMonth = monthPostDto.getCreateTime().getDayOfMonth(); calenderData.put(dayOfMonth, monthPostDto); } ForCalender CalenderInfo = getCalenderInfo(weekDay, focusedDate);
- @RequestParam ์ผ๋ก month๋ฅผ ๋ฐ์ ์ค๋๋ฐ, ์ด๋ month๊ฐ ์๋ค๋ฉด ํ์ฌ ์์ focus
- ํด๋น month์ 1์ผ์ ์์ ๋ ์ง๋ก ์ค์
-
ํด๋น member์ ํด๋น month์ post๋ฅผ ๊ฐ์ ธ์ด (navtive query ์ฌ์ฉ) โ
postService.getMonthPosts(member.getId(), month);
@Query(value = "SELECT * " + "FROM post p " + "where p.member_id = :m_id " + "and MONTH(p.create_time) = :request_month ;", nativeQuery = true) List<Post> getMonthPost(@Param(value = "m_id") Long id, @Param(value="request_month") int month);
- ํด๋น ์์ ๋ง๋ calender ์์ฑ (List๋ก ๋ฌ๋ ฅ์ ๋ง๋ค๊ณ , Map์ผ๋ก ํด๋น ๋ ์ง์ ๋ง๋ post๋ฅผ ๋ฃ์ด์ค)
- ๋ง์ง๋ง์ผ๋ก ํด๋น calender์ ์ ๋ณด(๋ ๋, ์, ์์์์ผ ๋ฑ)๋ฅผ ๋ด์ View Template์ ๋๊ฒจ์ค
- ๊ณต๋ถ ํต๊ณ
- ํ์ฌ focus ๋์ด ์๋ ๋ฌ์ ๋ชจ๋ post๋ฅผ ๊ฐ์ ธ์์ โ์ถ์๋ฅ , ์ด ๊ณต๋ถ์๊ฐ, ํ๊ท ๊ณต๋ถ์๊ฐโ ์ ๋ํ ํต๊ณ ์๋ฃ๋ฅผ ์ ๊ณต
int monthDate = dayData[month - 1]; int nowMonthPostsLen = 0; if (month == LocalDateTime.now().getMonthValue()) { monthDate = LocalDateTime.now().getDayOfMonth(); nowMonthPostsLen = monthPosts.size(); } else { nowMonthPostsLen = postService.getMonthPosts(loginMemberId, LocalDateTime.now().getMonthValue()).size(); } AllStatic allStatic = getAllStatus(oriMember, staticsData, days.get(days.size() - 1), monthPosts, monthDate, nowMonthPostsLen);
- ์ถ์๋ฅ : ํด๋น ๋ฌ์ ๋ชจ๋ post์ ๊ฐ์ / ํด๋น ๋ฌ์ ๋ชจ๋ ๋ ์ง (ํด๋น ๋ฌ์ด ํ์ฌ ๋ฌ์ด๋ฉด ํ์ฌ๊น์ง์ ์ถ์๋ฅ ๋ก ๊ณ์ฐ)
- ์ด ๊ณต๋ถ์๊ฐ : ํด๋น ๋ฌ์ ๋ชจ๋ post๋ฅผ ๊ฐ์ ธ์์ ์๊ฐ๊ณ์ฐ
- ํ๊ท ๊ณต๋ถ์๊ฐ : ์ด ๊ณต๋ถ์๊ฐ / ํด๋น ๋ฌ์ ๋ชจ๋ ๋ ์ง (ํด๋น ๋ฌ์ด ํ์ฌ ๋ฌ์ด๋ฉด ํ์ฌ๊น์ง์ ์ถ์๋ฅ ๋ก ๊ณ์ฐ)
- ๊ธฐ๋ฅ ํ์์ฑ
<220721>
My Page (๋ด ํ๋กํ) ์๋น์ค
#65Enhancement
: ์ฃผ๊ฐ ๊ณต๋ถ ๊ทธ๋ํ (๋์ ๊ทธ๋ํ X โ ์ผ๋ฐ ๊ทธ๋ํ O)
- #65
- ๊ธฐ๋ฅ ํ์์ฑ
- Ranking ํ๋ฉด์ ํตํด์ ์ผ์ฃผ์ผ๊ฐ์ ๊ณต๋ถ์๊ฐ ๋์ ๊ทธ๋ํ๋ ํ์ธํ ์ ์์ง๋ง, ์ผ๋ฐ ๊ทธ๋ํ, ์ฆ ์ผ์ฃผ์ผ๊ฐ์ ๋ด๊ฐ ํ๋ฃจํ๋ฃจ ์ผ๋ง๋ ๊ณต๋ถํ๋์ง์ ๋ํ ๊ทธ๋ํ๊ฐ ์์ด ๋ถํธ
- ๋ํ Profile์์์ ๊ทธ๋ํ๋ ๋์ ๊ทธ๋ํ๋ณด๋ค๋ ์ผ๋ฐ ๊ทธ๋ํ๊ฐ ๋์ฑ ํ์ (Bar Chart)
- ๊ตฌํ
-
๋จผ์ ๋ชจ๋ ๋ฉค๋ฒ๋ค์ ์ผ์ฃผ์ผ ๊ฐ์ post๋ฅผ ๊ฐ์ ธ์จ ํ ์๊ฐ ๊ณ์ฐ (
getStaticsData
)private Map<Integer, Times> getStaticsData(MemberDto member) { List<Post> posts; Map<Integer, Times> dayTimes = new HashMap<>(); DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); // 0-4 ์ฌ์ด ์์ฒญ (์ดํ์ ๊น์ง์ ๋ฐ์ดํฐ) if (LocalDateTime.now().getHour() < 4) { String end = LocalDateTime.now().minusDays(1).format(dateTimeFormatter); String start = LocalDateTime.now().minusDays(8).format(dateTimeFormatter); posts = postService.getLast7(member.getId(), start, end); for (int i = 8; i > 1; i--) { dayTimes.put(LocalDateTime.now().minusDays(i).getDayOfMonth(), new Times(0)); } } else {...} // ์ด์ธ์ ์์ฒญ (4~24 ์ฌ์ด ์์ฒญ, ํ๋ฃจ์ ๊น์ง์ ๋ฐ์ดํฐ) } for (Post post : posts) { Times time = getTimes(post.getTimes()); int today = (time.getHour() * 60 + time.getMin()); ... } return dayTimes; }
- ๋จผ์ ๋ ์ง๋ณ์ ์๊ฐ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ธฐ ์ํด Map ์ฌ์ฉ (๋ ์ง์ ์ธ๋ฑ์ค๊ฐ ์ผ์นํ์ง ์๊ธฐ ๋๋ฌธ์ List ๋ง๊ณ Map ์ฌ์ฉ)
- nativequery์์ Between์ ์ฌ์ฉํ์ฌ ์์ฒญ์๊ฐ์ ๋ฐ๋ฅธ post list๋ฅผ ๊ฐ์ ธ์ด (0-4 ์ฌ์ด ์์ฒญ โ ์ดํ์ ๊น์ง์ ๋ฐ์ดํฐ, ์ด์ธ์ ์์ฒญ(4~24 ์ฌ์ด ์์ฒญ) โ ํ๋ฃจ์ ๊น์ง์ ๋ฐ์ดํฐ) [
getLast7(Long memberId, String start, String end)
] - ๋ง์ง๋ง์ผ๋ก Times ๊ฐ์ฒด๋ฅผ ์ด์ฉํ์ฌ ์๊ฐ ๊ณ์ฐ ํ ํด๋น ์ ๋ณด๊ฐ ๋ค์ด์๋ dayTimes Map ๋ฐํ
-
๊ทธ ํ ํด๋น ๋ฐ์ดํฐ๋ฅผ view Template์ผ๋ก ๋ณด๋ธ ํ ์ด ๊ฐ์ Javascript๋ก ๋ฐ์์ BarChart์ ๋ฐ์ดํฐ ๊ฐ์ ๋ฃ์ด์ค (staticDays ๋ staticData์ key๋ฅผ ์ ๋ ฌํ ๊ฐ. โ ์ ๋ ฌ๋ ๋ ์ง)
var staticDays = [[ ${staticDays}]]; var data = [[ ${staticData}]] // Bar Chart var ctx = document.getElementById("myBarChart"); var myBarChart = new Chart(ctx, { datatsets: ...})
-
- ๊ธฐ๋ฅ ํ์์ฑ
<220720>
My Page (๋ด ํ๋กํ) ์๋น์ค ์ถ๊ฐ
#13Enhancement
: ์ฌ์ฉ์ ์ ๋ณด ๋ณด๊ธฐ
#53Back
: ๋ชจ๋ ๊ณต๋ถ ์๊ฐ
#67Back
: Spring Interceptor ์ ์ฉ
- #13
- ๊ธฐ๋ฅ ํ์์ฑ
- ์ง๊ธ๊น์ง๋ ์๋๋ฐฉ์ ์์ธ ํ๋กํ์ ํ์ธํ ์ ์์ ๋ฟ๋๋ฌ ์์ ์ ์์ธ ํ๋กํ๋ ํ์ธํ ์ ์์์
- ๋งํฌ, ๋ณ๋ช ๋ฑ ์์ ์ ์ ๋ณด, ๋ค๋ฅธ ์ฌ์ฉ์๋ค์ ์ ๋ณด๋ฅผ ๋ณด์ฌ์ค ํ์๊ฐ ์์
- ํด๊ฒฐ
- My Page๋ฅผ ์์ฑํด์ ์ฌ์ฉ์์ ์์ธ ์ ๋ณด๋ฅผ ๋ณผ ์ ์๋ ํ์ด์ง ์ถ๊ฐ (์ฌ์ฉ์๋ Session์ ์ ์ฅ๋ member โ ๋ก๊ทธ์ธ๋ ๋ฉค๋ฒ)
- Session์ ์ ์ฅ๋ member์ Id๋ฅผ ๋ฐ์์ ํด๋น member์ ์ ๋ณด๋ฅผ DB์์ ๊ฐ์ ธ์ ๋ณด์ฌ์ค. (login id, name, nickname, introduce, links)
@SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) Long loginMemberId
โMember oriMember = memberService.findOne(loginMemberId);
- DTO๋ก ๋ณ๊ฒฝ ํ ๋ณด์ฌ์ค ์ ๋ณด๋ง์ veiw Template์ ๋๊ฒจ์ค โ
MemberDto member = new MemberDto(oriMember);
- link๋ ํด๋ฆญ ์ ํด๋น link๋ก ์ด๋ํ ์ ์๋๋ก ์ค์
- ๊ธฐ๋ฅ ํ์์ฑ
- #53
- ๊ธฐ๋ฅ ์ค๋ช
- ํด๋น ๋ฉค๋ฒ๊ฐ ์ง๊ธ๊น์ง ์ผ๋ง๋ ๊ณต๋ถ๋ฅผ ํด์๋์ง ์๋ ค์ฃผ๋ ๊ธฐ๋ฅ (์๊ฐ)
- ๊ตฌํ
- ํ๋กํ์ ์ถ๊ฐ ํด๋น ๊ธฐ๋ฅ ์ถ๊ฐ
-
ํด๋น ๋ฉค๋ฒ์ ๋ชจ๋ post๋ฅผ ๊ฐ์ ธ์จ ํ ๊ฐ post์ times๋ค์ ์๊ฐ ๊ฐ์ ๊ณ์ฐ, ๊ทธ ํ member์ ์ ์ฅ โ
member.setTotalTime(getAllTimes(oriMember));
private Times getAllTimes(Member member) { List<Post> posts = member.getPosts(); int total = 0; for (Post post : posts) { if (post.getTimes().size() % 2 != 0) continue; Times times = getTimes(post.getTimes()); total += times.getHour() * 60 + times.getMin(); } return new Times(total); }
- ๊ธฐ๋ฅ ์ค๋ช
- #67
- ๊ธฐ๋ฅ ํ์์ฑ
- My Page ๊ฐ์ ๊ฒฝ์ฐ, ์์ ์ ์ ๋ณด๋ฅผ ํ์ธํ๊ณ ์์ ํ๋ ๊ณต๊ฐ์ด๋ฏ๋ก ๋ก๊ทธ์ธ ์ธ์ฆ ๋ฐ ํ์ ์ผ์น ์ธ์ฆ์ด ํ์
- ํด๊ฒฐ
- Login Interceptor์ ํด๋น url ์ถ๊ฐ
.addPathPatterns("/members/my-page", โฆ )
- ๋ง์ฝ ๋ก๊ทธ์ธ์ด ๋์ด์์ง ์๋ค๋ฉด ๋ก๊ทธ์ธ ํ ๋ค์ด์ฌ ์ ์๋๋ก ์ค์
- ๊ธฐ๋ฅ ํ์์ฑ
<220719>
#65
Bug
: static ๊ทธ๋ํ ์ค๋ฅ
- #65
- ๋ฐ์๋ Bug
- 0~4์์ ์์ฒญ์ ๋ํด์ ์ดํ์ ๊น์ง์ ๋ฐ์ดํฐ๋ง ๋ณด์ฌ์ ธ์ผ๋๋๋ฐ, 0์20๋ถ ์ฏค์ ์์ฒญํ์ ๋, ํ๋ฃจ์ ์ ๋ฐ์ดํฐ๊ฐ ๋ณด์ฌ์ง
- ๋์ ๋ฐ์ดํฐ์ธ๋ฐ, ์ค๊ฐ์ ๋์ ๋์ง ์๋ ํ์ ๋ฐ์
- ํด๊ฒฐ
- 0~4์์ ์์ฒญ์ ๋ํ ๋ถ๊ธฐ๋ฅผ if (0<nowTimeโฆ) ์ด๋ฐ ์์ผ๋ก ๋ฒ์ ์ค์ ์ ์๋ชปํจ. โ
if (now.getHour() < 4)
๋ก ๋ฒ์ ์์ - ๋์ ๋ฐ์ดํฐ ๋ฌธ์
- ๋ ์ง์ ๋ํ HashMap์ key๋ฅผ ๊ฐ์ ธ์ฌ๋, ๋ฐ๋ก ์ ๋ ฌํ์ง ์์ ๋ฐ์ โ keySet์ ํตํด ๊ฐ์ ธ์ค๋ฉด ๋น์ฐํ ์ ๋ ฌ์์ด ๊ฐ์ ธ์์ง.
-
์ด๋ keySet์ ๊ฐ์ ธ์ค๊ณ , ๋ ์ง๋ฅผ ์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ ฌํ์ฌ ํด๊ฒฐ
List<Integer> list = new ArrayList<>(dayTimes.keySet()); list.sort(Comparator.naturalOrder());
- keySet์ list๋ก ๋ณ๊ฒฝํ๊ณ sort๋ฅผ ํตํด ์ ๋ ฌ
- ์ด๋ ๊ฒ ๋๋ฉด ๋ ์ง๊ฐ ๋ค์ฃฝ๋ฐ์ฃฝ๋์ง ์๊ณ ์ค๋ฆ์ฐจ์์ผ๋ก ์งํ๋๊ธฐ ๋๋ฌธ์, ์ฝ๋ ์ ๋์ ์ด ์ ๋๋ก ์งํ๋จ
- 0~4์์ ์์ฒญ์ ๋ํ ๋ถ๊ธฐ๋ฅผ if (0<nowTimeโฆ) ์ด๋ฐ ์์ผ๋ก ๋ฒ์ ์ค์ ์ ์๋ชปํจ. โ
- ๋ฐ์๋ Bug
<220718>
#63
Bug
: ์ฒซ ๋ก๊ทธ์ธ ์ ๋ฐ์ํ๋ ์ค๋ฅ (session Id ์ด๋์ผ๋ก ์ธํ ๋ฌธ์ )
#64Enhancement
: static ์๋น์ค ๊ธฐ๋ฅ ์ถ๊ฐ (์ผ์ฃผ์ผ ๊ฐ์ ๊ณต๋ถ ํ์, ๊ณต๋ถ์, ์ถ์์ ๊ธฐ๋ฅ ์ถ๊ฐ)
- #63
- ๊ธฐ์กด์ ๋ฌธ์ ์
- ์ฒซ ๋ก๊ทธ์ธ ์ (์ธ์ ์ ์ฅ ์) ์ค๋ฅ ๋ฐ์
- ์ธ์ ์ ์ฅ ํ ํด๋น ๊ฐ์ url๋ก ๋ณด๋ด์ง๋ฉด์ ๋ฐ์ํ๋ ์ค๋ฅ๋ก ํ๋จ (์ฟ ํค๊ฐ ์ ์ฉ๋์ง ์๋ ์ํฉ์ ๋๋นํ servlet ์๋ ๊ธฐ๋ฅ โ traking-modes)
- ํด๊ฒฐ
- servlet ์ค์ ์ ํตํด ํด๋น ์๋ ๊ธฐ๋ฅ์ ๋ง์ (cookie๋ก ์ค์ ํจ์ผ๋ก์จ ์ฟ ํค๋ก๋ง session์ ์ธ์ํ๊ฒ ๋ค๋ ์ค์ )
server.servlet.session.tracking-modes: 'cookie'
- ๊ธฐ์กด์ ๋ฌธ์ ์
- #64
- ์ผ์ฃผ์ผ ๊ฐ์ ๊ณต๋ถ ํ์
- ์ผ์๋ก count ํ๋ฉฐ ๊ณต๋ถ์๊ฐ์ด 0์ธ post๋ค์ ๋ํด์ counting
- ๊ทธ ํ 7-cnt ๋ก ๊ณต๋ถ ํ์ ๊ธฐ๋ก
- ๋ง์ง๋ง์ผ๋ก ํด๋น ๊ฐ์ memberDto์ ์ ์ฅ, veiw Template์ผ๋ก ๋๊ฒจ์ค
- ๊ณต๋ถ์, ์ถ์์ ๊ธฐ๋ฅ
- ๊ณต๋ถ์ : ์ผ์ฃผ์ผ๊ฐ์ ๋์ ๊ณต๋ถ์๊ฐ์ด ๊ฐ์ฅ ๋ง์ ์ฌ๋
- ์ถ์์ : ์ผ์ฃผ์ผ๊ฐ์ ๊ณต๋ถ ํ์๊ฐ ๊ฐ์ฅ ๋ง์ ์ฌ๋
- ์ผ์ฃผ์ผ ๊ฐ์ ๊ณต๋ถ ํ์
<220717>
#62
Back
: ๋ฐฐ์ด๋ด์ฉ์ ์ฉ โ ์ต์ ํ
- Spring Security ์์ด ๋ก๊ทธ์ธ ๊ฐ๋ฐ (authentication โ session)
- session timeout ์ฐ์ฅ
#61
Front
: ๋ก๊ทธ์ธ ํ์ด์ง ์์ฑ
- #62-1
- ๊ธฐ์กด์ ๋ฌธ์ ์
- ์ ๋๋ก ๋ฐฐ์ฐ์ง ์์ Spring Security๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ ์ํ๋ ๊ธฐ๋ฅ์ ์ ๋ ์ ๋๋ก ์ด์ฉํ์ง ๋ชปํจ (session ์ค์ ๋ฑ) โ ์ถํ ํ์ต ํ ์ ์ฉ ์์
- ํด๊ฒฐ
- session์ ์ด์ฉํ login(์ธ์ฆ)์ผ๋ก ๊ตฌํ โ ๋ก๊ทธ์ธ ๊ฒ์ฆ ๋ฐ ๋ก๊ทธ์ธ์ ๋ชจ๋ ์ง์ ๊ตฌํ
- Spring Security์ ๊ด๋ จ๋ ๋ชจ๋ ์ฝ๋๋ฅผ ์ ๊ฑฐํ๊ณ session๊ณผ ๊ด๋ จ๋ ์ฝ๋๋ก ๋์ฒด (๋น๋ฐ๋ฒํธ ์ธ์ฝ๋ฉ ์ ์ธ)
-
๋ก๊ทธ์ธ
@PostMapping("/members/login") public String login(@Validated @ModelAttribute("loginForm") LoginForm loginForm, BindingResult bindingResult, @RequestParam(defaultValue = "/") String redirectURL, HttpServletRequest request) {...}
- ๋ก๊ทธ์ธ ์ ์ค๊ฐ์ ๋ก๊ทธ์ธ ์๊ตฌ์ ์ํด์ ๋ก๊ทธ์ธ์ ํ๋ ์ํฉ์ ๋๋นํด์ redirectURL์ ๋ฐ์์ด (์์ ๊ฒฝ์ฐ ๊ทธ๋ฅ home์ผ๋ก)
- session์ ๋ฐ์์ค๊ธฐ ์ํด HttpServletRequest ์ด์ฉ
-
๋ก๊ทธ์ธ ๊ฒ์ฆ
// form ํ์์ ๋ง์ง ์์ ์ ์ถ if (bindingResult.hasErrors()) { return "login"; } // ๋ก๊ทธ์ธ ๊ฒ์ฆ // Global Error -> Object ๋จ ์ค๋ฅ! (์ง์ ์ฒ๋ฆฌํด์ผ ๋๋ ๋ถ๋ถ) Optional<Member> loginMember = memberService.findByLoginId(loginForm.getLoginId()); BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); if (loginMember.isEmpty() || !passwordEncoder.matches(loginForm.getPassword(), loginMember.get().getPassword())) { bindingResult.reject("loginFail", "์์ด๋ ๋๋ ๋น๋ฐ๋ฒํธ๊ฐ ๋ง์ง ์์ต๋๋ค."); return "login"; }
- Form ํ์์ ๋ง์ง ์์ ์ ์ถ์์์ ๊ฒ์ฆ์ Bean Validation ์ฌ์ฉ (
FieldError
) - ์์ด๋ ๋ฐ ๋น๋ฐ๋ฒํธ ์ค๋ฅ ์
ObjectError
๋ฐ์ ํ veiw Template์ผ๋ก ๋๊ฒจ ์ค Optional
์ ํตํด ์ค๋ฅ ๊ฒ์ฆ
- Form ํ์์ ๋ง์ง ์์ ์ ์ถ์์์ ๊ฒ์ฆ์ Bean Validation ์ฌ์ฉ (
-
๋ก๊ทธ์ธ ์ฑ๊ณต
// ๋ก๊ทธ์ธ ์ฑ๊ณต HttpSession session = request.getSession(); // ์ธ์ ์ ๋ก๊ทธ์ธ ํ์ ์ ๋ณด ๋ณด๊ด session.setAttribute("loginMember", loginMember.get().getId()); return "redirect:"+ redirectURL;
- ๋ก๊ทธ์ธ ์ฑ๊ณต ์ session์ ํ์์ ๋ณด(member id) ์ ์ฅ
- member ๊ฐ์ฒด ์์ฒด๋ฅผ ์ ์ฅํ์ง ์๊ณ , member id๋ง์ ์ ์ฅํ์ฌ, ์ถํ ์ด๋ฅผ ํตํด repo์์ member๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐฉ์์ผ๋ก ์งํ
- ๊ธฐ์กด์ ๋ฌธ์ ์
- #62-2
- ๊ธฐ์กด์ ๋ฌธ์ ์
- session timeout์ ์ค์ ํ์ง ์์, ๋๋ฌด ์์ฃผ ๋ก๊ทธ์์๋์ด ์ฌ์ฉ ์ ๋ถํธํจ
- ํด๊ฒฐ
-
spring securrity๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ์ง์ session์ ์ด์ฉํ๊ณ , session timeout์ applications.yml ์ ์ค์ ํ์ฌ ๊ด๋ฆฌ (timeout์ 10์๊ฐ์ผ๋ก ์ค์ )
server.servlet.session.timeout: 36000
-
- ๊ธฐ์กด์ ๋ฌธ์ ์
- #61
- ๊ธฐ์กด์ ๋ฌธ์ ์
- ๋ก๊ทธ์ธ ํ์ด์ง ์์ด home์์ ๋ก๊ทธ์ธ์ ์งํํ๋ค ๋ณด๋ ์ธ๋ฐ์์ด ๋ฐ์ดํฐ๊ฐ ์ฃผ๊ณ ๋ฐ์์ง๋ ๊ฒฝ์ฐ๊ฐ ์์. (home์์ ๋ก๊ทธ์ธ ์ด์ ์๋ ๋ค๋์ ๋ฐ์ดํฐ๋ฅผ ๋ณด์ฌ์ฃผ๊ณ , ๋ก๊ทธ์ธ ํ์๋ ๋ค๋์ ๋ฐ์ดํฐ๋ฅผ ๋ณด์ฌ์ฃผ๊ณ ์์. โ ๋น ํจ์จ์ )
- redirect๋ฅผ ํตํ ๋ก๊ทธ์ธ ํ ํ์ด์ง ์ด๋์ด ๋ถ๊ฐ๋ฅ.
- ํด๊ฒฐ
- ์ผ๋ฐ์ ์ธ ์น์ฌ์ดํธ์ฒ๋ผ ๋ก๊ทธ์ธ ํ์ด์ง๋ฅผ ๋ฐ๋ก ๋ง๋ค์ด ์ ๊ณต
- ๋ก๊ทธ์ธ ํ์ด์ง๋ฅผ ์๋ก ์์ฑ
- ๊ธฐ์กด์ ๋ฌธ์ ์
- #30
- ๊ธฐ์กด์ ๋ฌธ์ ์
- ์ธ์ ๋ง๋ฃ ์ ์๋ฌํ์ด์ง ๋ฐ์
- ์ธ์ ๋ง๋ฃ์๋ ์๋น์ค๋ฅผ ์ ๋์ ์ผ๋ก ์ด์ฉํ๊ธฐ ์ํด ๋ก๊ทธ์ธ ํ์ด์ง ํ redirect๋ฅผ ํตํด ๋๋์๊ฐ๋ ๊ฒ์ด ํ์
- ํด๊ฒฐ
- Interceptor์์ ๋ก๊ทธ์ธ ํ์ด์ง๋ก ๋์ด๊ฐ๋ request์ redirectURL query parameter๋ฅผ ์ถ๊ฐ.
- ๋ก๊ทธ์ธ ํ ํด๋น redirectURL query parameter ๋ฅผ ํตํด ์ด์ ํ์ด์ง๋ก ๋๋์๊ฐ.
response.sendRedirect( "/members/login?redirectURL=" + request.getRequestURI())
@RequestParam(name = "redirectURL", defaultValue = "/") String redirectURL
โreturn "redirect:" + redirectURL
- ๊ธฐ์กด์ ๋ฌธ์ ์
<220714>
#48
Enhancement
: ์๋ก์ด ๋์๋ณด๋ (Static ์๋น์ค ๊ฐ์ )
- #48
-
๊ธฐ์กด์ ๋ฌธ์ ์
ํ์ด์ฌ์ผ๋ก ํต๊ณ๋ด์ด ํด๋น ๊ทธ๋ํ๋ฅผ ์ฌ์ง์ผ๋ก ์ ์ฅํ๊ณ , ๊ทธ ์ฌ์ง์ ๋ถ๋ฌ์ค๋ ํ์์ผ๋ก ์งํ, ํ์ง๋ง ์ด๋ ํตํฉ๋์ง ์๋ ๋ฌธ์ ๊ฐ ์์ผ๋ฉฐ, ์ฌ์ง์ผ๋ก ๋ณด์์ผ๋ก์จ ๋ถ๊ฐ์ ์ธ ์๋น์ค๋ฅผ ์ ๊ณตํ์ง ๋ชปํจ
-
ํด๊ฒฐ
- javascript๋ฅผ ์ด์ฉํ์ฌ ๊ทธ๋ํ๋ฅผ ๋ณด์ฌ์ฃผ๋ ํ์์ผ๋ก ์งํ.
- Model๋ก ๋ฐ์ดํฐ๋ฅผ ๋ด์์ thymeleaf in javascript ๊ธฐ์ ์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ ์ด์ฉ
- ๋ฉค๋ฒ๋น ์ต๊ทผ 1์ฃผ์ผ post๋ฅผ ๊ฐ์ ธ์ ํด๋น post์ ๋ชจ๋ ์๊ฐ์ ๋ํ ์๊ฐ์ ์ ์ฉ
- ์ค์ํ ์ ์ ์๋ฒฝ4์๋ฅผ ํ๋ฃจ์ ๋๊ณผ ์์์ผ๋ก ์ ํ๊ธฐ๋๋ฌธ์, ์์ฒญ ์๊ฐ์ด 0~4์ ์ฌ์ด์ผ ๊ฒฝ์ฐ์ ๋๋จธ์ง ์๊ฐ์ผ ๊ฒฝ์ฐ์ ๋ํ ์ฒ๋ฆฌ ๊ตฌ๋ถ ํ์
- ๊ทธ๋ํ๋ก๋ ๋์ ์๊ฐ์ ๋ณด์ฌ์ค
- ์ถ๊ฐ๋ก ํด๋น ์ผ์ฃผ์ผ๊ฐ์ ๋์ ์๊ฐ์ ๋ํ ๋ญํน ํ์
-
StaticController ์ฃผ์ ์ฝ๋
@GetMapping("/data") public String data(Model model, Authentication authentication) throws IOException { if (authentication == null) { return "redirect:/"; } List<MemberDto> members = memberService.findAll().stream().map(MemberDto::new).collect(Collectors.toList()); Map<MemberDto, Map<Integer, Times>> memberStatic = new HashMap<>(); List<Integer> days = getDays(LocalDateTime.now()); for (MemberDto member : members) { Map<Integer, Times> staticsData = getStaticsData(member); memberStatic.put(member, staticsData); member.setTime(staticsData.get(days.get(days.size()-1))); if (member.getTime().getHour() != 0) { Random rand = new Random(); int r = rand.nextInt(255); int g = rand.nextInt(255); int b = rand.nextInt(255); member.setColor("rgba(" + String.valueOf(r) + "," + String.valueOf(g) + "," + String.valueOf(b) + "," + "1)"); } else { member.setColor("rgba(236,236,236,1)"); } } members.sort(new TimeSorter()); ... }
- getDays : ๊ทธ๋ํ์ ํ์ํ ๋ ์ง๋ชจ์(์ผ)
- getStaticData : ๊ทธ๋ํ์ ํ์ํ ๋ฐ์ดํฐ ์์ฑ
- 0~4์์ ์์ฒญ : 8์ผ์ ~ ์ดํ์ ๊น์ง์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ด
- ์ด์ธ์ ์์ฒญ : 7์ผ์ ~ ํ๋ฃจ ์ ๊น์ง์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ด
- ์ถ๊ฐ๋ก ๋ ์ง๋ง๋ค์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด์ฃผ๊ธฐ ์ํด HashMap ์ฌ์ฉ (key: ๋ ์ง, value: ์๊ฐ) ์ด๋, ํด๋น ๋ ์ง์ post๊ฐ ์๋ ๊ฒฝ์ฐ ์ด์ ๋ฐ์ดํฐ๋ฅผ ๋๊ฒจ๋ฐ์ ์ฌ์ฉํ๋๋ก ์ค์ (๋์ ๋ฐ์ดํฐ์ด๋ฏ๋ก)
- ๋ํ ๊ฐ ๋ฉค๋ฒ๋ณ๋ก ๋๋คํ ์๊น์ ์ค์ ํ์ฌ ๊ฐ ๋ฉค๋ฒ๋ณ์ ๊ทธ๋ํ๊ฐ ๊ตฌ๋ถ ๊ฐ๋ฅํ๋๋ก ์ค์
- ๊ทธ ํ ๋ญํนํ์๋ฅผ ์ํด TimeSorter๋ก ์ ๋ ฌ
-
Javascript ์ฃผ์ ์ฝ๋
var datasets = []; [# th:each="user, stat : ${staticsDataMap}"] var user[[${stat.count}]] = [[${user.value}]]; if (user[[${stat.count}]][staticDays[6]].hour !== 0) { datasets.push({ label: [[${user.key.name}]], lineTension: 0.3, backgroundColor: "rgba(33,37,41,0)", borderColor: [[${user.key.color}]], pointRadius: 3, pointBackgroundColor: [[${user.key.color}]], pointBorderColor: [[${user.key.color}]], pointHoverRadius: 3, pointHoverBackgroundColor: [[${user.key.color}]], pointHoverBorderColor: [[${user.key.color}]], pointHitRadius: 10, pointBorderWidth: 2, data: [user[[${stat.count}]][staticDays[0]].hour + Math.round(user[[${stat.count}]][staticDays[0]].min/60), user[[${stat.count}]][staticDays[1]].hour+ Math.round(user[[${stat.count}]][staticDays[1]].min/60), user[[${stat.count}]][staticDays[2]].hour+ Math.round(user[[${stat.count}]][staticDays[2]].min/60), user[[${stat.count}]][staticDays[3]].hour+ Math.round(user[[${stat.count}]][staticDays[3]].min/60), user[[${stat.count}]][staticDays[4]].hour+ Math.round(user[[${stat.count}]][staticDays[4]].min/60), user[[${stat.count}]][staticDays[5]].hour+ Math.round(user[[${stat.count}]][staticDays[5]].min/60), user[[${stat.count}]][staticDays[6]].hour+ Math.round(user[[${stat.count}]][staticDays[6]].min/60)], }); } [/] var myLineChart = new Chart(ctx, { type: 'line', data: { labels: [staticDays[0]+'์ผ',staticDays[1]+'์ผ',staticDays[2]+'์ผ',staticDays[3]+'์ผ',staticDays[4]+'์ผ',staticDays[5]+'์ผ',staticDays[6]+'์ผ'], datasets: datasets, }, ...})
- thymeleaf in javascript ๊ธฐ์ ์ for each ๋ฅผ ์ฌ์ฉํ์ฌ user๋ฅผ ๋ง๋ค๊ณ ํด๋น user์ ๋ฐ์ดํฐ๋ฅผ dataset์ ๋ฃ์ด ๊ทธ๋ํ์ ๋์ .
-
<220713>
#42
Enhancement
: ํ๋ฃจ ๊ณต๋ถ์๊ฐ ๋ญํน
#62Back
: MVC ์ต์ ํ
- #42
-
๊ธฐ์กด์ ๋ฌธ์ ์
์ฐ์ธก ์ํฐํด์์ ๋์ ๊ณต๋ถ์๊ฐ ๊ทธ๋ํ๋ฅผ ์ฌ์ง์ผ๋ก ๋๋ต์ ์ผ๋ก ๋ณด์ฌ์ฃผ๋ ๋ถ๋ถ์ด ์์์ผ๋ ์ฌ์ค์ ์๋ฏธ๊ฐ ์๋ ๊ธฐ๋ฅ์ด์์ผ๋ฉฐ, ๋์๋ณด๋๋ฅผ ์ฌ์ง์ด ์๋ js๋ก ๊ตฌ์ฑํ๊ธฐ๋ก ๊ฒฐ์ . ์ถ๊ฐ๋ก ๊ณต๋ถ ๋๊ธฐ๋ถ์ฌ๋ฅผ ๋์ฌ์ฃผ๊ธฐ ์ํ ๊ธฐ๋ฅ์ด ํ์ํ์
-
ํด๊ฒฐ (ํ๋ฃจ ๊ณต๋ถ์๊ฐ ๋ญํน์ผ๋ก ๋์ฒด)
- ๊ธฐ์กด์ ์ ๊ณตํ๋ ๊ธฐ๋ฅ ์ค ํ๋ฃจ ๊ณต๋ถ์๊ฐ ๊ณ์ฐ ๋ก์ง(
getTotalStudyTimes
())์ ์ด์ฉ -
์ด ๋ก์ง์ ๋ชจ๋ Member๋ค์๊ฒ ์ ์ฉํ์ฌ ๊ฐ Member์ ํ๋ฃจ ๊ณต๋ถ์๊ฐ์ ๊ณ์ฐํ๋๋ก ์งํ
for (MemberDto m : memberDtos) { Optional<Post> eachOptionalPost = postService.getRecentPost(m.getId()); PostViewDto memberRecentPostDto = eachOptionalPost.map(PostViewDto::new).orElse(null); if (memberRecentPostDto != null) { m.setTime(getTotalStudyTimes(memberRecentPostDto)); } else { m.setTime(null); } }
- ์ด ์๊ฐ์ ๊ฐ๊ฐ์ MemberDto์ time property์ ์ ์ฅ ํ ์ด๋ฅผ View Template์์ ๋ฐ์, ์ด์ฉ.
-
์ฌ๊ธฐ์ ์ค์ํ ๋ถ๋ถ์, ํ๋ฃจ ๊ณต๋ถ์๊ฐ ๋ญํน์ด๊ธฐ ๋๋ฌธ์, ์ด๋ค์ ์๊ฐ(
Times
)์ ๋ฐ๋ผ ์ ๋ ฌ์ด ํ์ โ custom Comparator(TimeSorter
) ์์ฑ ํsort
์ ์ฉpublic class TimeSorter implements Comparator { @Override public int compare(Object o1, Object o2) { //o1 - o2 = ASC , o2 - o1 = DESC MemberDto m1 = (MemberDto) o1; MemberDto m2 = (MemberDto) o2; int totalTime1 = 0; int totalTime2 = 0; if (m1.getTime() != null) totalTime1 = m1.getTime().getHour() * 60 + m1.getTime().getMin(); if (m2.getTime() != null) totalTime2 = m2.getTime().getHour() * 60 + m2.getTime().getMin(); return totalTime2 - totalTime1; } }
- Times๊ฐ hour์ min์ผ๋ก ๊ตฌ์ฑ๋์ด ์๊ธฐ ๋๋ฌธ์, ์ด๋ฅผ ๋ชจ๋ minute์ผ๋ก ๋ณ๊ฒฝ ํ ์ด๋ค์ ๋ํ ์ ๋ ฌ์ ์คํ.
List<MemberDto> memberRanking = new ArrayList<>(memberDtos); memberRanking.sort(new TimeSorter());
- ๊ธฐ์กด์ ์ ๊ณตํ๋ ๊ธฐ๋ฅ ์ค ํ๋ฃจ ๊ณต๋ถ์๊ฐ ๊ณ์ฐ ๋ก์ง(
-
- #62
- ๊ธฐ์กด์ ๋ฌธ์ ์
- ํ์ด์ง์ ๋ฐ๋ฅธ Controller๊ฐ ์กด์ฌ โ ๋ฒ์กํ ๊ตฌ์ฑ
- Static ํ๋ฉด๋ HomeController์ ์กด์ฌ โ ๊ด์ฌ์ฌ ๋ถ๋ฆฌ ํ์
- ํด๊ฒฐ
- ํ์ด์ง Controller ํตํฉ โ
@RequestMapping({"/", "/{page}"})
,@PathVariable(name = "page", required = false) Integer page
,if (page == null) page = 1;
- url๋ก ๋ณ์๋ฅผ ๋ฐ์์ค๊ณ ํด๋น ๋ณ์๊ฐ ์๋ค๋ฉด 1๋ก ์ค์ ํ์ฌ main์ page 1๋ก ๊ฐ ์ ์๋๋ก ์ค์
- StaticController ์์ฑ โ (HomeController์ ๋ถ๋ฆฌ)
- ํ์ด์ง Controller ํตํฉ โ
- ๊ธฐ์กด์ ๋ฌธ์ ์
<220618> ~ <220630>
- Spring MVC ์ง์ค ๊ณต๋ถ! (๊ฐ์ ๋ฐ ๊ฐ์ธ ํ์ต์ผ๋ก ์ธํด ๊ฐ์์์ ์งํํ ๊ฐ๋ฐ ์์ธ์ ๊ฐ๋ฐ์ ์งํํ์ง ์์)
- ์ถํ ํด๋น ๊ณต๋ถํ ๋ด์ฉ์ ๋ฐํ์ผ๋ก Semogong Project๋ฅผ Upgrade ์ํฌ ์์
<220615>
Front
: ์ฌ์ฉ์ ํธ์๋ฅผ ์ํ ์ ๋๋ฉ์ด์ ์ถ๊ฐ
- ํ์ฌ ๋ฌธ์ ์
- Home ํ๋ฉด์์ ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋๊ณ ์๋ Point๊ฐ ์ด๋์ง ํ์ธ ๋ถ๊ฐ
- Static ํ๋ฉด์์ ํ์ฌ ์ธ์์ด ๋ณ๊ฒฝ๋๊ณ ์๋์ง ํ์ธ ๋ถ๊ฐ
- ํด๊ฒฐ
- Home ํ๋ฉด์ ํด๋น Point์ ๋ฌผ๊ฒฐ ์ ๋๋ฉ์ด์ ์ ์ถ๊ฐํ์ฌ ํ์ฌ ๋ฐ์ดํฐ๊ฐ ๋ณํ๊ณ ์๋ ์ง์ ์ ๋ํด Focusํ ์ ์๋๋ก ์ค์
- Static ํ๋ฉด์ Live ๋ฒํผ์ ํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๊ณ ์์ผ๋ฉด ์ด๋ก์ ๊น๋นก์์ ์ฃผ์ด ๋ฐ์ดํฐ๊ฐ ๋ฐ์๋๊ณ ์๋ค๋ ์ฌ์ค์ ์ฌ์ฉ์์๊ฒ ์ธ์งํ ์ ์๋๋ก ์ค์
<220614>
Back
: ์ธํฐ์ ํฐ๋ฅผ ํตํ ์ต์ ํ
- ํ์ฌ ๋ฌธ์ ์
- ํ์ฌ Temp โ Info๋ก ๋ฐ๊พธ๋ ๋ก์ง์ ํ ์๋น์ค๊ฐ ์์๋ ๋ ๋ชจ๋ Temp๋ฅผ Info๋ก ๋ฐ๊พธ๋ ์์ ๋ฐฉ์์ผ๋ก ์งํ ์ค
- ํ์ง๋ง ํ์ฌ ๋ฐฉ์์ ์ฌ์ค์ ๋นํจ์จ์ ์. ๋ชจ๋ DB๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ๋ณด๋ค, ์ต๊ทผ ์์ฒญ์์ ์ ๊ธฐ์ตํ๊ณ ๊ทธ ์ดํ๋ก ์๋ก ๋ค์ด์จ Temp๋ค๋ง์ Info๋ก ๋ฐ๊พธ๋ ๋ฐฉ๋ฒ์ด ํ์
- ํด๊ฒฐ
- Point์ ์ต๊ทผ Info์ ๋ณ๊ฒฝ์์ ์ ๊ธฐ๋กํ์ฌ
- ํด๋น ๋ณ๊ฒฝ์์ ์ดํ์ ์๋ก์ด Temp๊ฐ ์๋์ง ํ์ธํ์ฌ ํด๋น Temp๋ฅผ Info๋ก ๋ณ๊ฒฝํ๋ ๋ฐฉ์์ผ๋ก ์งํ
- ๋ํ ์ด๋ ์ด๋ค ์๋น์ค๋ ์์๋ ๋ ์ ์ฉ์ด ๋์ด์ผ ํ๋ฏ๋ก ์ธํฐ์ ํฐ ๊ฐ๋ ๋์
-
UpdateInterceptor
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { List<Point> pointList = pointService.findAll(); // find all Point for (Point point : pointList) { // each point infoService.createInfo(point.getId()); // make ์ฐ๊ด๊ด๊ณ with Point (์๋ก ์์ฑ๋ Temp๋ค์ ๋ํด์ ์๋ก์ด Info ์์ฑ) pointService.updatePoint(point.getId()); // point์ lastCommittedTime update (์ต๊ทผ Info update ์๊ฐ update) } return true; }
- CheckPoint ์ดํ ์๋ก ์์ฑ๋ Temp๋ค์ ๋ํด์ ์๋ก์ด Info ์์ฑ
- CheckPoint Update
- ๋ง์ง๋ง์ผ๋ก WebConfig๋ฅผ ํตํด Interceptor ๋ฑ๋ก
<220612>
Enhancement
: ๋์ ํต๊ณ ์ ๋ณด ์กฐํ ๊ฐ๋ฐ
- Static์์ ๋ณด์ฌ์ค ๋์ ํต๊ณ ์ ๋ณด์ ๋ํ ๊ฐ๋ฐ ์งํ
- ํต๊ณ ๋ก์ง
- ํด๋น Point์ ๋ํ ๋ชจ๋ Info๋ฅผ ์กฐํ
- ์กฐํํ ํ ๋ ์ง๋ณ๋ก Info๋ฅผ ๋๋๊ณ ํด๋น ๋ ์ง์ ๋ํ Info ๊ฐ์์ ํ๊ท ์น๋ฅผ model์ ๋ด์ rendering
- ์ผ์ฃผ์ผ๊ฐ์ ๋ฐ์ดํฐ, ์๊ฐ๋ณ ๋ฐ์ดํฐ ๋ชจ๋ ํ๊ณณ์ ์ ์ฅ
- ํด๋น ๋ฐ์ดํฐ๋ฅผ Pie,Arial Chart ๋ฅผ ๊ตฌ์ฑํ๋ js ์ ํ ๋น (ํฌํ๋ฆฟ ์ด์ฉ)
<220610>
Back
: Temp, Info Repository, Service ์ฌ์ ์
- Temp, Info Repository, Service ์ฌ์ ์
- ๊ธฐ์กด์ ์ฌ์ฉํ๋ Info์ Domain, Service, Repository๋ฅผ ๋ชจ๋ Temp๋ก ์ด์ , ๊ทธ ํ Info Repository, Service ์๋ก ์ ์
- ํต์ฌ์ Temp๋ก ๋ฐ์์จ ๋ผ์ด๋ธ ๋ฐ์ดํฐ๋ฅผ Info๋ก ๋ฐ๊พธ์ด ์ ์ฅํ๋ ๊ฒ. ์ฆ, Temp์ ๋ฐ์ดํฐ๋ฅผ ๊ทธ๋๋ก ๋ฐ์์ ์ฐ๊ด๊ด๊ณ๋ฅผ ์ ์ํ๊ณ Entity๋ก์จ ๊ด๋ฆฌ๋๊ฒ ๋ง๋๋ ๊ฒ
- Info Repository
- ์ ์ฅ๋ง ํ๋ฉด ๋จ (์กฐํ๋ ์ฐ๊ด๊ด๊ณ๋ฅผ ๋งบ์ Point๋ก ์งํ) โ
em.persist(info)
- ์ ์ฅ๋ง ํ๋ฉด ๋จ (์กฐํ๋ ์ฐ๊ด๊ด๊ณ๋ฅผ ๋งบ์ Point๋ก ์งํ) โ
- Info Service
- Info ์์ฑ ๋ฉ์๋๋ง ์กด์ฌ โ (๋งคํ ๋ก์ง: ) ํด๋น ๊ตฌ์ญ์ ๋ฐ๋ผ Point์ ๋งคํ์์ผ์ค ํ ์ ์ฅ. ๊ทธ ๊ฒฐ๊ณผ๋ก ์ธก์ ๋ ์์น๋ค์ ๋ฐํ์ผ๋ก Point๋ฅผ ์์
<220609>
Back
: ์ด์ Info ๋ฐ์ดํฐ์ Point์ ์ฐ๊ด๊ด๊ณ ์์ฑ ํ์Back
: Temp, Info Domain ์ฌ์ ์
- ๋ฐ๊ฒฌ๋ ๋ฌธ์ ์
- ์ค์๊ฐ ๋ฐ์ดํฐ๋ก ๋ฐ์์ค๋ Info๋ฅผ ๊ทธ ์ฆ์ Floating ํด์ฃผ๋ ๊ธฐ๋ฅ์ ๊ฐ๋ฅํ๋, Info์ ๊ณผ๊ฑฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ๋ ์ด๋ฏธ ํ๋ฒ ๋งคํ๋์๋ Point์ ๋ค์ ํ๋จ ๋ก์ง์ ํตํด ๋งคํ์ด ํ์ํจ
- ๋ํ Info๊ฐ Entity๋ก์จ ์ ์ฅ๋์ง ์์๊ธฐ์ ๋ฐ์ํ๋ ๋ถํธํจ ํด๊ฒฐ ํ์
- ํด๊ฒฐ๋ฒ
- ๊ธฐ์กด์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์์ ์๋ก Entity๋ก ๊ด๋ฆฌ๋๋ ๋ฐ์ดํฐ๋ฅผ ์์ฑ โ Temp๋ผ๋ Object๋ก ๊ธฐ์กด์ ๋ฐ์ดํฐ ๋ฐ์์ด
-
์ถ๊ฐ๋ก Info๋ฅผ ๊ฐ์ ธ์ฌ ๋ point์ ์ฐ๊ด๊ด๊ณ๋ฅผ ๋งบ์ด ์๋ก ์ฐธ์กฐํ ์ ์๋๋ก ์ค์
//==์ฐ๊ด๊ด๊ณ ๋ฉ์๋==// private void setPoint(Point point) { this.point = point; point.getInfos().add(this); }
- ๊ธฐ์กด์ ์ฌ์ฉํ๋ Info์ Domain, Service, Repository๋ฅผ ๋ชจ๋ Temp๋ก ์ด์ , ๊ทธ ํ Info ์๋ก ์ ์
<220608>
Front
: Home, Static ํ๋ฉด ์์ Back
: HomeRestController ๊ฐ๋ฐ
- Home, Static ํ๋ฉด ์์
- Home
- Kakao Map API๋ฅผ ์ด์ฉํ ์ง๋์ Point์ ์ขํ๋ฅผ ๋งคํ์์ผ floating
- ๊ฐ Point๋ค์ ๋ํ ์ค์๊ฐ ๋ณ๋๋ ํ์๋ฅผ ์ํ ๊ฐ๋ฐ โ ajax ๋น๋๊ธฐ ํต์ , REST API ์ด์ฉ โ REST API ๋ฅผ ์ํ Controller ๊ฐ๋ฐ ํ์
$( document ).ready(function detection_change() { interval = setInterval(function () { $.ajax({ url: '/infos', type: "GET" }) .done(function (response) { ... //๋ก์ง } })
- Static
- ์ค์๊ฐ ์ธ์ ์ธก์ ๋ ํ์ (๋ฒํผ์ ๋๋ฅด๋ฉด ๋ณผ ์ ์๊ณ , ์๋๋ฉด ์๋ณด์ฌ์ฃผ๋ ๋๋์ผ๋ก ์งํ โ ๋ฒํผ์ ๋๋ฅด๋ฉด interval ํจ์๋ฅผ ์ฌ์ฉํ์ฌ 3์ด๋ง๋ค ๋ฐ์ดํฐ๋ฅผ ์์ฒญ, JSON์ผ๋ก ๊ฐ์ ๋ฐ์์ด)
- ์ด ๋ํ ajax ๋น๋๊ธฐ ํต์ , REST API ์ด์ฉ โ REST API ๋ฅผ ์ํ Controller ๊ฐ๋ฐ ํ์
- Home
- HomeRestController ๊ฐ๋ฐ
- REST API ๋ฅผ ์ํ Controller ๊ฐ๋ฐ (
@RestController
) - Homeํ๋ฉด๊ณผ Static ํ๋ฉด์ ๋ฟ๋ ค์ค JSON ๋ฐ์ดํฐ ์์ฑ ๋ฐ ๋ฐํ
- JSON ๋ฐ์ดํฐ๋ ์ค์๊ฐ์ผ๋ก ์ธก์ ๋ ์ธ์์ ์๋ฅผ ๋ณด์ฌ์ฃผ๋ count์ ์ด ๋ฐ์ดํฐ ๋ฆฌ์คํธ๋ฅผ ๋ฐํ (
Result<T>
์ฌ์ฉ)
- REST API ๋ฅผ ์ํ Controller ๊ฐ๋ฐ (
<220606>
Back
: HomeController ๊ฐ๋ฐ
- ๊ณตํต
- Home ํ๋ฉด์ด๋ Static ํ๋ฉด์ด๋ ๋ชจ๋ Point๋ค์ ๋ํ ์ ๋ณด๊ฐ ํ์ํ๊ธฐ ๋๋ฌธ์ point list๋ฅผ ๊ธฐ๋ณธ์ ์ผ๋ก Model์ ์ถ๊ฐํด์ค. (
@ModelAttribute
์ฌ์ฉ)
- Home ํ๋ฉด์ด๋ Static ํ๋ฉด์ด๋ ๋ชจ๋ Point๋ค์ ๋ํ ์ ๋ณด๊ฐ ํ์ํ๊ธฐ ๋๋ฌธ์ point list๋ฅผ ๊ธฐ๋ณธ์ ์ผ๋ก Model์ ์ถ๊ฐํด์ค. (
- Home
- API๋ฅผ ์ด์ฉํ๊ธฐ ๋๋ฌธ์ ๋ฐ๋ก Model์ ์ถ๊ฐํด์ค ๊ฒ๋ค์ด ์์.
- Point List๋ ๋ฏธ๋ฆฌ ์ถ๊ฐ๋ ์ํ์ model ์ฌ์ฉ
- Statics
- ๊ฒ์ํด์ ๋ค์ด์ค๋ ์ํฉ๊ณผ, ๊ธฐ๋ณธ static ํ๋ฉด ๋ถ๋ฆฌ (๋ฐ์ดํฐ ๋ถ๋ฆฌ)
- ๊ทธ์ ๋ํ ์ถ๊ฐ์ ์ธ ์ ๋ณด(Live Count) ๋ฑ ์ถ๊ฐ
- ์ถ๊ฐ์ ์ผ๋ก ํ์ํ ๋ถ๋ถ : ๋ฐ์ดํฐ๊ฐ ์ถ๊ฐ๋๋ฉด ๋์ ํต๊ณ ๋ฐ์ดํฐ์ ๋ํ ์ฒ๋ฆฌ ํ์.
<220605>
Back
: Info Service, Repository ๊ฐ๋ฐ
- Info ๋๋ฉ์ธ์ ์ฃผ์์
- ์ด๋ฏธ ์ค์๊ฐ์ผ๋ก ์ ์ฅ๋์ด ์๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์์ floatingํ๋ ์ญํ
- ๊ทธ๋ฌ๋ฏ๋ก ๋ฐ๋ก ์ ์ฅํ ํ์๋ ์๊ณ , ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ์ญํ ๋ง ํ๋ฉด ๋จ
- ์ฌ๊ธฐ์ ๊ธฐ์กด์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด์ JpaRepository, NativeQuery ๋ฅผ ์ฌ์ฉํด์ผ ๋จ
- ๊ฐ๋ฐ
-
10์ด~ํ์ฌ ์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ method โ static ํ๋ฉด์์ ์ฌ์ฉ
@Query(value = "SELECT * " + "FROM temp t " + "where t.date >= DATE_SUB(CONVERT_TZ(NOW(),'SYSTEM','Asia/Seoul'), INTERVAL 10 SECOND);", nativeQuery = true) List<Temp> getLiveData();
- ํด๋น Entity๋ก ์ ์ฅ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ์ด ์๋ ๊ธฐ์กด์ ์๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด์ JpaRepository, NativeQuery ์ฌ์ฉ
- 10์ด ์ ~ํ์ฌ์ ๋์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ด โ DATE_SUB() sql๋ฌธ ์ฌ์ฉ
-
์ ์ฅ์ ๋ฐ๋ก ํ์์์
-
<220604>
Back
: Basic Point Service, Repository ๊ฐ๋ฐ
- Repository ๋จ
- ์ ํด์ง ์ง์ ์ ๋ํด์ ์ ์ฅํ๊ธฐ ๋๋ฌธ์
@PostConstruct
๋ฅผ ํตํด ๋ฏธ๋ฆฌ DB ์ ์ฅ. (1ํ์ฑ initDB) - ๋ค๊ฑด์กฐํ, ๋จ๊ฑด์กฐํ, ์ด๋ฆ์ผ๋ก ์กฐํ. 3๊ฐ์ง method ์์ฑ
- ์ ํด์ง ์ง์ ์ ๋ํด์ ์ ์ฅํ๊ธฐ ๋๋ฌธ์
- Service ๋จ
- ๋ฆฌํฌ์งํ ๋ฆฌ์ ์ญํ ์ ๋จ์ ์์
- ์ถ๊ฐํ ์
- ํ์ฌ๋ ๋์ ๋ ๋ฐ์ดํฐ๊ฐ ์๊ธฐ์ ๋์ ํต๊ณ๋์ ์ํ ๋ฐ์ดํฐ์ ๋ํ Repository๋ Service๊ฐ ์ ์๋์ด ์์ง์์ โ ๋ฐ์ดํฐ๊ฐ ์ด๋์ ๋ ๋์ ๋ ์ดํ ๊ฐ๋ฐ ํ์
<220602>
Back
: Domain ๊ฐ๋ฐ
- ํ์์ฑ
- ํ์ฌ ํ์ํ ๋ถ๋ถ์ ์ฅ์(๊ฒ์ถ ์ง์ )๋ฅผ ์ฐ๊ฒฐํ Point์ ์ค์๊ฐ์ผ๋ก DB์ ์ ์ฌ๋๋ ๊ฒ์ถ๊ฐ์ฒด์ ๋ณด๋ฅผ ์ฐ๊ฒฐํ Info๊ฐ ํ์
- ๊ฐ๋ฐ ๊ณผ์
- Point ๋๋ฉ์ธ ๊ฐ๋ฐ
- field ์ค์ , ์์ฑ ๋ฐ ์์ ๋ฉ์๋ ์์ฑ
- Info ๋๋ฉ์ธ ๊ฐ๋ฐ
- ๊ธฐ์กด์ DB์ ์ฐ๊ฒฐ
- field ์ค์ , ์์ฑ ๋ฐ ์์ ๋ฉ์๋ ์์ฑ
- Point ๋๋ฉ์ธ ๊ฐ๋ฐ
<220601>
Front
: ํฌํ๋ฆฟ ์ปค์คํ (home, static)
- ํ๋ก ํธ๋ฅผ ์ ๋ฌธ์ ์ผ๋ก ํ๋ ์ธ์์ด ์์ด, ๋ฌด๋ฃ๋ก ์ ๊ณต๋๋ ํ ํ๋ฆฟ์ ์ฌ์ฉํ๊ธฐ๋ก ๊ฒฐ์ . ์ฐ๋ฆฌ๊ฐ ํ๊ณ ์ ํ๋ ์๋น์ค์ ๋ง๋ ๋์๋ณด๋ ํฌํ๋ฆฟ์ ๋ฐ์์ ์ปค์คํ .
- ์ฌ๋ฌ html ํ์ผ ์ค home ํ๋ฉด๊ณผ static ํ๋ฉด๋ง ์ด๋ฆฌ๊ณ ์ด๋ค์ ๋ํด ์ปค์คํ ์งํ.
<2205010> ~ <220530>
- Spring MVC ์ง์ค ๊ณต๋ถ! (๊ฐ์ ๋ฐ ๊ฐ์ธ ํ์ต์ผ๋ก ์ธํด ๊ฐ์์์ ์งํํ ๊ฐ๋ฐ ์์ธ์ ๊ฐ๋ฐ์ ์งํํ์ง ์์)
- ์ถํ ํด๋น ๊ณต๋ถํ ๋ด์ฉ์ ๋ฐํ์ผ๋ก Semogong Project๋ฅผ Upgrade ์ํฌ ์์
<220508>
Tag : version 1.0.11
#39Enhancement
: ์ค์๊ฐ ํ์ต ์๊ฐ reload ๋ฒํผ ์ ๋๋ฉ์ด์ ์ถ๊ฐ
- #39
- ๊ธฐ์กด์ ๋ฌธ์ ์ : ์ค์๊ฐ ํ์ต ์๊ฐ reload ๋ฒํผ์ ๋๋ฌ๋ ์ ๋๋ ค์ก๋์ง๋ฅผ ํ์ธํ ๋ฐฉ๋ฒ์ด ์์์ โ alert์ ํ๋ คํ์ง๋ง, alert์ ๋จ๋ฉด ๊บผ์ผ๋๋ค๋ ๊ท์ฐฎ์ ํ์ธ
-
ํด๊ฒฐ : reload ๋ฒํผ์ ๋๋ฅผ๊ฒฝ์ฐ, reload img ๊ฐ 360๋ rotate ๋๋ฉด์ ์๊ฐ์ ์ผ๋ก ์ฌ๋ถํ ๋๋ ํจ๊ณผ ์ ๊ณต โ
<img id="reload" src="/images/reload.png" height="20px" width="20px">
.reload { transform: rotate( 360deg ); -moz-transform: rotate( 360deg ); -ms-transform: rotate( 360deg ); -o-transform: rotate( 360deg ); -webkit-transform: rotate( 360deg ); transition: transform 1000ms ease; -moz-transition: -moz-transform 1000ms ease; -ms-transition: -ms-transform 1000ms ease; -o-transition: -o-transform 1000ms ease; -webkit-transition: -webkit-transform 1000ms ease; }
var rotate = document.getElementById('reload') if (rotate) { rotate.addEventListener('click', function() { this.className = 'reload'; window.setTimeout(function() { rotate.className = '' }, 1000); }, false); }
<220507>
#39
Front
: ์ค์๊ฐ ํ์ต ์๊ฐ reload ๊ธฐ๋ฅ ์ถ๊ฐ
#39Bug
: 23์, 00์์ ์ฐจ์ด ์ค๋ฅ ํด๊ฒฐ
-
#39
- ๊ธฐ์กด์ ๋ฌธ์ ์ : ํ์ฌ ๊ณต๋ถ์๊ฐ์ ํ์ธํ๋ ค๋ฉด ๋ฌด์กฐ๊ฑด home์ reloadํด์ผ ๋๋ ๋นํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ ์ ํํด์ผ ํ์. โ ๋คํธ์ํฌ, ๋ ๋๋ง ๊ณผ๋ถํ ๊ฐ๋ฅ
-
ํด๊ฒฐ : ํ์ต ์๊ฐ ์์ฒด์ reload ๋ฒํผ์ ์ถ๊ฐํ์ฌ ๋ฒํผ์ ํด๋ฆญํ ๊ฒฝ์ฐ ajax api ํต์ ์ ํตํด ํด๋น ๊ณ์ฐ๋ ํ์ต ์๊ฐ๋ง ๋ฐ์์ ๋ ๋๋ง ํ ์ ์๋๋ก ์ค์
function reload_times(memberId) { $.ajax({ url: 'members/times/' + memberId, type: "GET" }) .done(function (response) { $('#member_time').replaceWith( '<div id="member_time"> ์ค๋์ ํ์ต ์๊ฐ : ' + response.hour + '์๊ฐ '+ response.min +'๋ถ </div>' ) }) }
<220506>
Tag : version 1.0.10
#2Bug
: ๋๊ธ submit enter ์ ๋ ฅํ ์ ์๋๋ก ์ค์ , apple์์์ ์ค๋ฅ ์์
#39Enhancement
: post edit ์์๋ ์ค์๊ฐ ํ์ต ์๊ฐ์ด ๋ณ๊ฒฝ๋๋๋ก
- #2
- ๊ธฐ์กด์ ๋ฌธ์ ์ : input์ onkeyup์ ์ฌ์ฉํ ๊ฒฝ์ฐ apple๊ธฐ๊ธฐ์์ ํ๊ธ๋ก ์์ฑํ ๊ฒฝ์ฐ ํด๋น ์ฐ๊ฒฐ๋ javascript ํจ์๊ฐ ์ฐ์ํด์ 2๋ฒ ์๋ํ๋ ์ค๋ฅ ๋ฐ์
- ํด๊ฒฐ: onkeyup์ ๋ชจ๋ onkeypress๋ก ๋ณ๊ฒฝ
- #39
- ๊ธฐ์กด์ ๋ฌธ์ ์ : post eidt ์ ์ค์๊ฐ ํ์ต ์๊ฐ์ ๋ณ๊ฒฝ๋์ง ์์์
- ํด๊ฒฐ :
- post edit ์ ๋ณ๊ฒฝ๋ ์๊ฐ์ ๋ฐ์์ ๊ทธ ์๊ฐ javascript ์์์ ํ์ฌ ํ์ต ์๊ฐ ๊ณ์ฐ ๋ก์ง(์์์ ์์ฑํ ๋ก์ง)์ ํตํด ํ์ฌ๊น์ง์ ํ์ต์๊ฐ์ ๋ฐ์ํ์ฌ ๋ณ๊ฒฝ.
- ์ด ๋ํ replace๋ฅผ ํตํด ์์๋ฅผ ํ์ฌ ๋ณ๊ฒฝ๋ ์์๋ก ๊ต์ฒด.
<220505>
Tag : version 1.0.9
#39Enhancement
: ์ค์๊ฐ ํ์ต ์๊ฐ ๊ธฐ๋ฅ ์ถ๊ฐ
- #39
- ๊ธฐ์กด์ ๋ฌธ์ ์ : ํ์ต ์๊ฐ์ด ๊ธฐ๋ก์ ๋์์ง๋ง, ์ด๋ฅผ ๊ทธ์ ์๊ฐ์ผ๋ก๋ง ๋ณด์ฌ์ฃผ์ด์ ์ฌ์ฉ์๊ฐ ์ค๋ ํ๋ฃจ ์ผ๋ง๋ ๊ณต๋ถ๋ฅผ ํ๋์ง ์ง์ ๊ณ์ฐํ๊ฑฐ๋ ๋์น๋ ๊ฒฝ์ฐ๊ฐ ๋ฐ์
- ํด๊ฒฐ: ํ๋ก๊ทธ๋จ์์ผ๋ก ์๋ ๊ณ์ฐํ์ฌ ์ง์์ ์ผ๋ก ์ง๊ธ๊น์ง ์์ ์ด ํ๋ฃจ ์ผ๋ง๋ ๊ณต๋ถ๋ฅผ ์งํํ๋์ง ํ์ธํ ์ ์๋๋ก ์ค์
getTotalStudyTimes
,getTimes
๋ฅผ ํตํด ํ์ฌ ์ํฉ์ ๋ง๋ ์๊ฐ ๊ณ์ฐ ์งํ-
๋ก์ง :
์กฐํ ์๊ฐ ๊ธฐ์ค (home์ผ๋ก ์ด๋)
- 04:00 - 24:00
- ๊ทธ member์ ๊ฐ์ฅ ์ต์ ๊ธ search
- ํด๋น member์ ์ต์ ๊ธ์ด ๋น์ผ 4์ ์ดํ create ๋์๋ค
- ๊ฐ์ ธ์์ times ๊ณ์ฐ 2. ๋น์ผ 4์ ์ด์ โ ์ด์ ๊ธ์ด๋ผ ํ๋จ
- โ๊ณต๋ถ๋ฅผ ์์ํ์ง ์์์ต๋๋คโ ์ถ๋ ฅ
- ๊ทธ member์ ๊ฐ์ฅ ์ต์ ๊ธ search
- 00:00 - 04:00
- ๊ทธ member์ ๊ฐ์ฅ ์ต์ ๊ธ search
- ํด๋น member์ ์ต์ ๊ธ์ด ๋น์ผ create
- ๊ฐ์ ธ์์ times ๊ณ์ฐ
2. ์ ๋ create
- 04์์ดํ create
- ๊ฐ์ ธ์์ times ๊ณ์ฐ 2. 04์ ์ด์ create
- โ๊ณต๋ถ๋ฅผ ์์ํ์ง ์์์ต๋๋คโ ์ถ๋ ฅ
- ๊ทธ member์ ๊ฐ์ฅ ์ต์ ๊ธ search
- 04:00 - 24:00
<220504>
Tag : version 1.0.8
#2Bug
: post edit์์ ์๊ฐ ๋ณ๊ฒฝ ์ ๋ฐ์๋์ง ์๋ bug ์์ , comment ์ญ์ , post ์ญ์ ์ ๋ชจ๋ฌ ์ ์ง
- #2
- ๊ธฐ์กด์ ๋ฌธ์ ์ : post๋ฅผ editํ ๋, main(home) ํ๋ฉด์ title, introduce๋ ์์ ๋์ง๋ง, ๋ณ๊ฒฝ๋ time์ด ๋ฐ์๋์ง ์์. โ ๋ times๋ค์ ๋ํด replace ํด์ค ํ์ ์์ ๋ํ, comment ์ญ์ , post ์ญ์ ๋ RestAPI๋ก ๊ต์ฒด ํ์
- ํด๊ฒฐ: ๊ธฐ์กด main ํ๋ฉด์ ํด๋น post์ times์ ์ ๋ณด๋ฅผ ๋ํ๋ด๊ณ ์๋ ์์๋ฅผ ๋น ์์๋ก replaceํ๊ณ ๋ณ๊ฒฝ๋ ์๊ฐ์ ๋ฐ๋ฅธ ์์๋ค์ appendํ๋ ๋ฐฉ์์ผ๋ก ์งํ
-
์๊ฐ์ ๋ฐ๋ฅธ ๋ณด์ฌ์ฃผ๋ ๋ก์ง์ ๊ธฐ์กด์ ๋ก์ง๊ณผ ๋์ผ
$('#post_times' + id).replaceWith( '<div id="post_times'+ id +'" class="card-text overflow-hidden d-sm-flex" style="margin: 2px 0px 0px 0px; max-width: 100%;"></div>' ) var cnt = 0; for (var i = 1; i < times.length; i+=2, cnt++) { if (cnt % 2 != 0) { $('#post_times' + id).append( '<p class="badge" style="margin: 3px; background-color:#8AA6A3;">' + times[i-1].value + ' ~ ' + times[i].value + '</p>' ); } else { $('#post_times' + id).append( '<p class="badge" style="margin: 3px; background-color:#A1A185;">' + times[i-1].value + ' ~ ' + times[i].value + '</p>' ); } } if (times.length % 2 == 1) { if ((times.length - 1) % 4 == 0) { $('#post_times' + id).append( '<p class="badge" style="margin: 3px; background-color:#A1A185;">' + times[times.length-1].value + ' ~' + '</p>' ); } else { $('#post_times' + id).append( '<p class="badge" style="margin: 3px; background-color:#8AA6A3;">' + times[times.length-1].value + ' ~' + '</p>' ); } }
-
comment, post ์ญ์ ์์ฒญ์ RestAPI๋ก ๊ต์ฒด
function post_delete_check(id) { var check = confirm("์ ๋ง ์ญ์ ํ์๊ฒ ์ต๋๊น?"); if (check){ //ํ์ธ alert("์ญ์ ๊ฐ ์๋ฃ ๋์์ต๋๋ค.") $.ajax({ url: 'posts/delete/' + id, type: "DELETE" }) .done(function () { location.reload(); }) }else{ //์ทจ์ return false; } }
function delete_check(postId, commentId) { var deleteForm = { postId : postId, commentId : commentId }; var check = confirm("์ ๋ง ์ญ์ ํ์๊ฒ ์ต๋๊น?"); if (check){ //ํ์ธ $.ajax({ url: 'comment/delete/' + commentId, type: "DELETE", data: deleteForm }) .done(function (fragment) {...} }
- post๋ฅผ ์ญ์ ํ ๋๋ ์ญ์ ํ ๋ฐ๋ก home์ผ๋ก ๊ฐ๋ฉด ๋์ง๋ง, comment๋ ์ญ์ ํด๋ ๋ชจ๋ฌ์ ์ ์งํ๋ฉฐ ํด๋น ์ญ์ ๋ฅผ ๋ฐ์ํ ์ํ์ comment list๋ฅผ ์๋ก ๋ณด์ฌ์ค ํ์๊ฐ ์๊ธฐ์ ์ญ์ ํ comment list(์ญ์ ๋ ํ์ comment list)๋ฅผ fragment๋ก ๋ฐ์์ replace ์งํ
-
<220503>
#2
Enhancement
: Post ์์ ์ ๋ชจ๋ฌ ์ ์ง
#28Enhancement
: ์ด๋ฏธ์ง Upload ์ API๋ก ๋ณด๋ผ ์ ์๋๋ก ์ค์
- #2
- ๊ธฐ์กด์ ๋ฌธ์ ์ : comment ์์ฑ ์ ์ ๋ชจ๋ฌ์ ์ ์งํ ํ์๊ฐ ์๋ค๊ณ ํ๋จํ์ฌ ํด๋น ๊ธฐ๋ฅ์ ์ ์ฉ, ํ์ง๋ง post ๋ํ ์์ ํ submit์ ๋๋ฅด๋ฉด ๋ณ๊ฒฝ๋ ์ฌํญ์ ํ์ธํ๊ธฐ ์ํด์๋ home์ผ๋ก ๋์๊ฐ์ผ ๋๊ณ , modal์ด ๋ด๋ ค๊ฐ๋ ํ์ ๋ฐ์ โ edit ํ ๋ฐ๋ก ๊ทธ ๋ชจ๋ฌ ์์ฒด์์ ํ์ธํ ์ ์๋๋ก ์ค์ ํ์ (comment์์์ ๋ฌธ์ ์ ์ ์ฌ)
- ํด๊ฒฐ: ์ด ๋ํ comment ์์ฑ ์ ๋์ํ๋ ๋ก์ง๊ณผ ์ ์ฌํ๊ฒ ์งํ โ Ajax Web API ์์ฒญ์ ํตํด post eidt์ Postํ๊ณ ํด๋น ๊ฒฐ๊ณผ ๊ฐ์ fragment๋ html๋ก ๋ฐ์์ ๊ธฐ์กด fragment๋ฅผ ๋ณ๊ฒฝํ๋ ๋ฐฉ์์ผ๋ก ์งํ (์ ๊ธ ์์ฑ์ ๋ชจ๋ฌ์ด ์๋, ๊ธฐ์กด ํผ์ผ๋ก ๋ณด์ฌ์ฃผ๋๋ก ์ค์ )
- post๋ get, post ๋ชจ๋ Ajax api๋ก ์์ฒญ (edit ๋ฒํผ์ ๋๋ฅผ ๊ฒฝ์ฐ ๋ํ ๋ชจ๋ฌ์์์ ์์ ๋ฐ ์์ ์๋ฃ ํ ๋ณ๊ฒฝ ์ฌํญ ํ์ธ์ ์ํจ)
-
@GetMapping("/posts/edit/{id}")
์ Ajax api๋ก ์์ฒญํ๋๋ก ์ค์ (๊ฒ์๊ธ ์์ ํผ)function edit_post(id) { $.ajax({ url: 'posts/edit/' + id, type: "GET", }) .done(function (fragment) { $('#postModal_content' + id).replaceWith(fragment); simplemde = new SimpleMDE({element: document.getElementById("content"),spellChecker: false}); document.getElementById("postEdit_container").scrollIntoView(); }); }
- ๋๊ฐ์ด ๊ธฐ์กด ๋ด์ฉ์ fragment๋ก ๋ฐ์ ์จ editForm html(
return "post/editPostForm :: #postEdit_container";
)๋ก ๊ต์ฒด - ๊ต์ฒด ํ markdown editor ์ถ๊ฐ.
- ์๋จ์ผ๋ก ์คํฌ๋กค ์๋ ์ด๋
- ๋๊ฐ์ด ๊ธฐ์กด ๋ด์ฉ์ fragment๋ก ๋ฐ์ ์จ editForm html(
-
@PostMapping("/posts/edit/{id}")
์ Ajax api๋ก ์์ฒญํ๋๋ก ์ค์ (๊ฒ์๊ธ ์์ )function post_edit(id) { var formData = $("#formPost").serializeArray(); formData[formData.length - 1].value = simplemde.value(); // content $.ajax({ url: '/posts/edit/' + id, type: "POST", data: formData }) .done(function (fragment) {...} }
- form์ ์๋ ๋ฐ์ดํฐ๋ค์ ๋ฐ์ํ๊ธฐ ์ํด form์ ์ ๋ ฅ๋ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ serializeArray๋ฅผ ํตํด ๋ฐ์์ด
- ์ฌ๊ธฐ์ simplemde๋ฅผ ์ฌ์ฉํ๋ฉด์ content์ ๋ด์ฉ์ด serializeArray์ ๋ด๊ฒจ์ค์ง ์์ ์ง์ simplemde์ ์ ๋ ฅ๋ ๊ฐ์ form์์ content์ ๋ฃ์ด์ค
- ์ดํ๋ ์์ comment ๋ณ๊ฒฝ ๋ก์ง๊ณผ ๋์ผํ๊ฒ ์งํ (ajax api, fragment replace, setAttribute(id), recentpost, โฆ)
- #28
- ๊ธฐ์กด์ ๋ฌธ์ ์ : ์ด๋ฏธ์ง๋ฅผ iframe์ form์ผ๋ก upload ์งํ. โ ๋นํจ์จ์ ์ธ ๋ฐฉ๋ฒ, Rest API๋ฅผ ํตํด ํด๊ฒฐ ๊ฐ๋ฅ
-
ํด๊ฒฐ : Ajax Web API ์์ฒญ์ Post๋ฅผ ์ด์ฉํ์ฌ ์ ๋ก๋๋ฅผ ํ๊ณ ๋ฐํ ๊ฐ์ผ๋ก ํด๋น Image ๊ฐ์ฒด (value: imgSrc, imgName)๋ฅผ Json ํ์์ผ๋ก ๋ฐ์ ์ด๋ฅผ ์ด์ฉํ์ฌ ๋ณ๊ฒฝ๋ ์ฌ์ง ์ ๋ณด๋ฅผ ์ถ๋ ฅ
@ResponseBody @PostMapping("/posts/edit/{id}/img") public Image postImgEdit(@PathVariable("id") Long id, @RequestParam("file") MultipartFile[] files) throws IOException { MultipartFile file = files[0]; Image image = s3Service.upload(file); postService.editPostImg(id, image); return image; // image ๊ฐ์ฒด๋ฅผ Json์ผ๋ก ๋ฐํ }
function image_upload(id){ var formData = new FormData(); var image = $("#file")[0].files[0]; formData.append( "file", image); if(image == null){ alert("ํ์ผ์ ์ ํํด์ฃผ์ธ์"); return; } $.ajax({ url : "/posts/edit/"+id+"/img" , type : "POST" , processData : false , contentType : false , data : formData }) }
- ์ด๋ฏธ์ง ์ ๋ก๋ ํ ๊ฐ์ฒด๋ฅผ Json์ผ๋ก ๋ฐํํด ์ค
- ์ด๋ฏธ์ง์ ๊ฐ์ file ๋ฐ์ดํฐ๋ formdata๋ก ํ๋ฒ ๋ฌถ์ด์ค์ ๋ณด๋ด์ฃผ๋ ๊ฒ์ด ์์ ํจ
- ๋ํ file ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ผ ๋๋ ํญ์
processData : false
,contentType : false
์ฃผ์
<220502>
#25
Enhancement
: ๋์ ๊ณต๋ถ์๊ฐ ํต๊ณ ๋์๋ณด๋
- #25
- ๊ธฐ์กด์ ๋ฌธ์ ์ : ๋ด๊ฐ ์ผ์ฃผ์ผ๋์ ์ผ๋งํผ ๊ณต๋ถ๋ฅผ ํ๊ณ ์๋์ง์ ๋ํ ์ ๋ณด๊ฐ ์์ด, ๋๊ธฐ๋ถ์ฌ๊ฐ ๋ถ์กฑ. ์ผ์ฃผ์ผ ๋์์ ๋์ ๊ณต๋ถ์๊ฐ ํต๊ณ๋์ ๋์๋ณด๋๋ฅผ ํตํด ์ฌ์ฉ์๋ค๋ผ๋ฆฌ ๋น๊ตํ์ฌ ๋ณด์ฌ์ฃผ๋ฉด ๋๊ธฐ๋ถ์ฌํ๋ ๋ฐ์ ์ข์ ํจ๊ณผ๊ฐ ์์ ๊ฒ์ด๋ผ๊ณ ํ๋จ
- ํด๊ฒฐ : ๋ถ์ ํด์ ํ์ด์ฌ์ด ๋ ์ต์ํ๊ธฐ์ ํ์ด์ฌ์ matplot์ ํตํด ์๊ฐ์ ๊ณ์ฐํ๊ณ ploting. ๊ทธ ํ ํด๋น ๊ฒฐ๊ณผ๋ฅผ ์ด๋ฏธ์ง๋ก ์ ์ฅํ์ฌ S3์ ์ ์ฅํ๊ณ , ์น์์๋ ํด๋น ์ด๋ฏธ์ง๋ฅผ ๋ถ๋ฌ์ ๋ณด์ฌ์ฃผ๋ ํ์์ผ๋ก ์งํ. (Side Widget์ Statics, Nav bar์ Data ๋ถ๋ถ)
- ์ถํ ํด๊ฒฐ : D3.js ์ ๊ฐ์ ํด์ ์ฌ์ฉํ์ฌ ์ข ๋ ์๊ฐ์ ํจ์จ์ฑ์ ๊ทน๋ํํ ์์
<220501>
#2
Enhancement
: Comment ์์ฑ ์ ๋ชจ๋ฌ ์ ์ง
- #2
- ๊ธฐ์กด ๋ฌธ์ ์ : Post ํด๋ฆญ ์ ์์ฑ๋๋ ๋ชจ๋ฌ์์ ๋๊ธ์ ์์ฑํ ์ ์์ฑ ํ submit ์ ํด๋ฆญํ ๊ฒฝ์ฐ modal ์ด๊ธฐ์ ์์ฑ๋ ๋๊ธ์ ํ์ธํ๋ ค๋ฉด home์ผ๋ก reload๋จ. โ ์์ฑ ํ ํ์ฌ ๋ชจ๋ฌ์ ์ ์งํ๋ฉด์ ์์ฑ๋ ๋๊ธ๋ชฉ๋ก๋ง์ reloadํ ํ์๊ฐ ์์
- ํด๊ฒฐ : Ajax Web API ์์ฒญ์ ํตํด comment๋ฅผ postํ๊ณ ํด๋น ๊ฒฐ๊ณผ ๊ฐ์ fragment๋ html๋ก ๋ฐ์์ ๊ธฐ์กด fragment๋ฅผ ๋ณ๊ฒฝํ๋ ๋ฐฉ์์ผ๋ก ์งํ
-
@PostMapping("/comment/api/new/{id}")
๋ฅผ ajax์ post ์์ฒญ์ผ๋ก mappingfunction submit_comment(id) { var commentForm = { postId : id, comment : $("#comment_content"+id).val() }; $.ajax({ url: 'comment/api/new/' + id, type: "POST", data: commentForm, }) .done(function (fragment) {...}
- fragment๋ ๋ชจ๋ฌ์ ์ผ๋ถ๋ถ์ธ commentList ๋ฅผ replaceํ๊ธฐ ์ํ ๋ ๋๋ง๋ html ํ์ผ
- ์ฆ, post๊ฐ ์๋ฃ๋๋ฉด ์๋ก ๊ฐฑ์ ๋ ํด๋น Post์ comment list (๋ฐฉ๊ธ ์์ฑ๋ ๋๊ธ์ ์ถ๊ฐํ ๋๊ธ ๋ฆฌ์คํธ)๋ฅผ ๋ ๋๋งํ html ํ์ผ์ ๋ฐ์์ ์ด๋ฅผ ๊ธฐ์กด์ comment list์ ๊ต์ฒด. โ ์์ฑ๋ ๋๊ธ์ url reload ํ์ ์์ด ๋ฐ๋ก ํ์ธ ๊ฐ๋ฅ
- fragment๋ thymeleaf์์ ์ ๊ณตํ๋ html ์ผ๋ถ๋ง์ ๋ฐํํด์ฃผ๋ ๊ธฐ๋ฅ ์ฌ์ฉ :
return "components/commentList :: #commentPart";
โ ํด๋น id๋ฅผ ๊ฐ์ง ์์๋ง ๋ฐํํด์ค. -
๋ฐํ๋ fragment๋ก ๊ธฐ์กด ์์๋ฅผ ๊ต์ฒดํ ํ, id๋ฅผ ์๋ก ํ ๋น โ ๋ชจ๋ฌ์ด๊ธฐ์, ๋ค๋ฅธ post๋ค์ commentPart์ ๊ตฌ๋ถํ๊ธฐ ์ํจ.
var commentPart =document.getElementById("commentPart"); commentPart.setAttribute("id", "commentPart"+id.toString());
- ๋ํ, ๋ณ๊ฒฝ๋ ์ฌํญ์ modal ๋ฟ๋ง์๋, home์ ํด๋น post์ comment ๊ฐ์์๋ ๋ฐ์ํด์ค ํ์๊ฐ ์์ โ ํด๋น post id๋ฅผ ๊ฐ์ง post์ comment ๊ฐ์๋ฅผ ํํํ๋ ์์๋ฅผ replace ํด์ค
- ๋ํ, recent post๋ผ๊ณ ํ์ฌ ์์ ์ด ์์ฑ ์ค(๊ณต๋ถ๋ฅผ endํ์ง ์์ ์ํ์ post)์ธ post๋ฅผ ๋ณด์ฌ์ฃผ๋ ๊ธฐ๋ฅ์ด ์๊ธฐ ๋๋ฌธ์, ๋๊ธ ์์ฑ์ด ์ด๋ฃจ์ด์ง post๊ฐ ๊ทธ recent post์ ๋์ผํ ๊ฒฝ์ฐ recent post ๋ํ ์์ ๊ณผ์ ์ ์ ์ฉ (comment ๊ฐ์ ๋ณ๊ฒฝ)
-
<220427>
Tag : version 1.0.7
#28Enhancement
: Post Image ๋ณ๊ฒฝ ์ ๋ณ๊ฒฝ๋ ์ด๋ฏธ์ง ๋์์ฃผ๊ธฐ
#31Back
: ํฌ๋ง์ง๋ฌด ์ ํ์ง ๋ถ์ฌ (์ ํ์ง์ ์ํ๋ ์ง๋ฌด๊ฐ ์์ ์ ์ง์ ์ถ๊ฐ)
#15Front
: OG ํ๊ทธ ๋ถ์ฌ
- #28
- ๊ธฐ์กด ๋ฌธ์ ์ : ํ์ฌ ์ด๋ฏธ์ง์ ์ด๋ฆ๋ง์ ์๋ ค์ฃผ๊ณ , ํ์ฌ ์ด๋ฏธ์ง ์์ฒด๋ฅผ ๋ณด์ฌ ์ฃผ์ง ์์์. ๋ํ, Upload ์ ๋ฐ๋ก ๋ณ๊ฒฝ์ด ๋ฐ์๋์ง ์์ ์ฑ๋ก edit์ ์งํํ๊ฒ ์ค์ ํจ
- ํด๊ฒฐ : ์ด๋ฏธ์ง๋ฅผ ๋์์ฃผ๊ณ Upload ์ ๋ฐ๋ก ๋ณ๊ฒฝํ์ฌ ๋ณ๊ฒฝ๋ ์ด๋ฏธ์ง๋ฅผ ๋ณด์ฌ์ค ์ ์๋๋ก ์ค์ ํ์
-
Upload ๋ฒํผ์ ๋๋ฅผ ์ a ํ๊ทธ๋ฅผ ํตํด ๋ฐ๋ก img upload ๋ก์ง์ ์คํํ๋ ๊ฒ์ด ์๋, onclick=โupload_check()โ์ ํตํด javascript ์ฝ๋๋ฅผ ๊ฑฐ์ณ ์งํ๋๋๋ก ์ค์
function upload_check() { setTimeout(function(){alert("Upload์๋ฃ ๋์์ต๋๋ค!");location.reload();},500); } // 0.5์ด ํ์ ์๋์ผ๋ก ํ์ด์ง๊ฐ reload ๋๋๋ก ์ค์ . -> reload ๋๋ฉด ๋ณ๊ฒฝ๋ ์ ๋ณด๋ฅผ ๋์ธ ์ ์์.
-
- #31
- ๊ธฐ์กด ๋ฌธ์ ์ : ํฌ๋ง ์ง๋ฌด์ ์ ํ์ง๋ฅผ ์ฃผ์ง ์์, ์ ํด์ง ํ์ ์์ด ํฌ๋ง ์ง๋ฌด๋ฅผ ์ ๊ฒ ๋จ โ ๋๊ฐ์ ์ง๋ฌด๋ผ๋ ์ฌ์ฉ์๋ง๋ค ๋ค๋ฅธ ์ด๋ฆ์ผ๋ก ์ค์ ํ๋ ๊ฒฝ์ฐ๊ฐ ๋ฐ์
-
ํด๊ฒฐ : ViewTemplate ์ jobs ๋ผ๋ ์ค์ ๋ ์ง๋ฌด List๋ฅผ ๋๊ฒจ์ค datalist๋ก ์ ํํ ์ ์๋๋ก ์ค์ + ์ํ๋ ์ง๋ฌด๊ฐ ์์ผ๋ฉด ์ง์ ์ ์ ์ ์๋๋ก Input์ text๋ก ์ค์
public class DesiredJob { static final List<String> jobList = Arrays.asList("๋ฐฑ์๋ ์์ง๋์ด", "๋ฐ์ดํฐ ์์ง๋์ด", "ML ์์ง๋์ด", "ํ๋ก ํธ์๋ ์์ง๋์ด"); public static List<String> getJobList() { return jobList; } }
<div class="input-group mb-3"> <input **type="text"** autocomplete="off" class="form-control" list="datalistOptions" th:field="*{desiredJob}" placeholder="ํฌ๋ง ์ง๋ฌด๋ฅผ ์ ํํ๊ฑฐ๋ ์ ๋ ฅํ์ธ์!"> <**datalist** id="datalistOptions" > <th:block **th:each="job : ${jobs}"**> <option **th:value="${job}"**> </th:block> </**datalist**> </div>
- #15
- ๊ธฐ์กด ๋ฌธ์ ์ : ๋งํฌ๋ฅผ ๊ณต์ ํด๋ ์ ํด์ง ํ์ ์์ด ์ด์ํ ํํ๋ก ๊ณต์ ํ๋ฉด์ด ๋์์ง
-
ํด๊ฒฐ : Og ํ๊ทธ๋ฅผ ํตํด์ ์ ํด์ง ๊น๋ํ ํ์์ผ๋ก ๊ณต์ ๋ ์ ์๋๋ก ์ค์
<meta property="og:title" content="์ธ๋ชจ๊ณต - ์ธ์์ ๋ชจ๋ ๊ณต๋ถ" /> <meta property="og:url" content="http://semogong.site/" /> <meta property="og:type" content="website" /> <meta property="og:image" content="https://semogong-bucket.s3.ap-northeast-2.amazonaws.com/SEMOGONG.jpg" /> <meta property="og:description" content="TIL ๊ณต์ ์ฌ์ดํธ, ์ค๋ ํ ๊ณต๋ถ๋ฅผ ๊ณต์ ํด๋ณด์ธ์!" />
<220425>
Tag : version 1.0.6
#32Enhancement
: Comment ์์ฑ ์๊ฐ ํ์
#35Bug
Back
: State ๋ณ๊ฒฝ ์ ์ค๋ฅ ๋ฐ์
#36Front
: ๊ธ ๋ฐ ๋๊ธ ์ญ์ ์ Confirm
- #32
- ๊ธฐ์กด ๋ฌธ์ ์ : ๋๊ธ์ ์์ฑํ์ ๋, ํด๋น ๋๊ธ์ด ์ธ์ ๋ฌ๋ฆฐ ๊ฑด์ง ๊ตฌ๋ถ์ด ์๋ ๋๊ฐ ์์์. โ ๋๊ธ์ด ์ธ์ ๋ฌ๋ฆฐ ๊ฒ์ธ์ง ํ๊ธฐ ํ์
- ํด๊ฒฐ : ๋๊ธ์ด ๋ฌ๋ฆฐ ์๊ฐ ํ๊ธฐ
-
๋ก์ง : CommetViewDto์์ ๋๊ธ์ด ๋ฌ๋ฆฐ ์๊ฐ์ธ CreateDateTime๊ณผ ํ์ฌ ์๊ฐ์ธ LocalDateTime.now()์ ์ด์ฐจ์ด ๋ฅผ Duration.between์ ํตํด ๊ณ์ฐํ์ฌ ํด๋น DTO์ ์ ์ฅํ๊ณ veiwTemplate์ ๋ณด๋ด์ค ํ, ViewTemplate(Thymeleaf) ์์์
- 60๋ถ์ด ์ง๋์ง ์์์ผ๋ฉด โx๋ถ ์ โ์ผ๋ก
- 60๋ถ์ด ์ง๋ฌ๊ณ 24์๊ฐ์ด์ ์ด๋ฉด โx์๊ฐ ์ โ์ผ๋ก
- 24์๊ฐ์ด ์ง๋ฌ์ผ๋ฉด โx์ผ ์ โ์ผ๋ก ํ๊ธฐ
-
์ด๋, Thmeleaf์์ Math.round๋ฅผ ์ ์ฉํ๊ธฐ ์ํด ThymeMath Component๋ฅผ ์์ฑํ์ฌ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋ก โ ๋น์ผ๋ก ๋ฑ๋ก๋ Object๋ Thymeleaf ์์
@thymeMath
ํํ๋ก ์ฌ์ฉ ๊ฐ๋ฅ.
-
- #35
- ๊ธฐ์กด ๋ฌธ์ ์ : State ๋ณ๊ฒฝ ์ค๋ฅ ์ ๋ณ ๋ค๋ฅธ ์ค๋ฅ ์ฒ๋ฆฌ ์์ด ๊ทธ๋ฅ ํ์ผ๋ก ๋์๊ฐ๊ฒ ์ค์ โ ๋ณ๊ฒฝ๋์๋์ง, ์ค๋ฅ๊ฐ ๋์ง ์ฌ์ฉ์๊ฐ ์ธ์งํ๊ธฐ ์ด๋ ค์
- ํด๊ฒฐ : State ๋ณ๊ฒฝ ์ค๋ฅ ์ alert์ ํตํด ์๋ชป๋ state ๋ณ๊ฒฝ์ด๋ผ๊ณ ์๋ ค์ค
- ๋ก์ง : ViewTemplate(Thymeleaf) ์์ ํ์ฌ state ๊ฐ์ ๋ฐ์์จ ํ
( Studying -> Studying / Breaking, End -> Breaking / End -> End ) ์ ๊ฐ์ ๋ณ๊ฒฝ ์ค๋ฅ์ ๋ํด์ if ์ ์ ํตํด alert์ ๋์ธ ์ ์๋๋ก ์ค์
- ๋ก์ง : ViewTemplate(Thymeleaf) ์์ ํ์ฌ state ๊ฐ์ ๋ฐ์์จ ํ
- #36
- ๊ธฐ์กด ๋ฌธ์ ์ : ๊ธ ๋ฐ ๋๊ธ ์ญ์ ์ โ์ญ์ โ ๋ฒํผ์ ๋๋ฅด๋ฉด ๊ทธ๋ฅ ๋ฐ๋ก ์ญ์ ๋จ โ ์ฌ์ฉ์๊ฐ ์ค์๋ก ์ญ์ ๋ฅผ ๋๋ฅด๋ ๊ฒฝ์ฐ์ ๋ํ ์ฒ๋ฆฌ๊ฐ ํ์.
- ํด๊ฒฐ :
-
๋ก์ง : ๋ฐ๋ก a ํ๊ทธ๋ก ์ญ์ URL๋ก ์์ฒญ์ ๋ณด๋ด๋ ๊ฒ์ด ์๋, button์ผ๋ก ๋ฐ๊พผ ํ onclick์ผ๋ก javascript delete_check ํจ์๋ฅผ ํตํด confirmํ ์ ์๋๋ก ์ค์
detele_check : ์ธ์๋ก ์ญ์ ํ๊ณ ์ ํ๋ Entity์ id๋ฅผ ๋ฐ์์ค๊ณ confrim ์งํ. confirm์์ ํ์ธ์ ๋๋ฅผ ์ location.href ๋ฅผ ํตํด delete ์์ฒญ์ ์งํ. ์ทจ์๋ฅผ ๋๋ฅผ ์ ์๋ฌด๋์ํ์ง ์๋๋ก ์ค์
-
<220420>
Tag : version 1.0.5
#10Back
Front
: State๋ง๋ค ๊ตฌ๋ถํ ์ ์๋๋ก ๊ณ ์ ์ ๋ถ์ฌ ํ์
#11Back
: ๊ฐ Post ๋น comment ๊ฐ์๋ฅผ ์ธ์งํ ์ ์๋๋ก ์ค์ ํ์
#16Back
: Side Widget์ All Members๋ฅผ StudyingโBreakingโEnd ์์ผ๋ก ์ ๋ ฌ ํ์
#18Front
: ํ ๋ง ๊ธ๊ผด ์ค์ ํ์
#20Front
: ํต์ผ๋ Header ์์ฑ ํ์
#24Back
Front
: ๊ฐ Post์ CreateDate ํ๊ธฐ ํ์
- #10
- ๊ธฐ์กด์ ๋ฌธ์ ์ : State๋ง๋ค ๊ตฌ๋ถ์ด ์๋์ด ์์ด, ์๊ฐ์ ์ผ๋ก ํจ์จ์ ์ด์ง ๋ชปํจ. ์ฆ๊ฐ ์ธ์งํ๊ธฐ๊ฐ ์ด๋ ค์.
- ํด๊ฒฐ : ๊ฐ State์ ๋ง๋ ์์ ๋ถ์ฌ (thymeleaf์ if ๋ฌธ๋ฒ์ ์ฌ์ฉ)
- #11
- ๋ฌธ์ ์ : comment๋ฅผ ๋ฌ ์๋ ์์ง๋ง, ๊ฐ post์ comment๊ฐ ๋ฌ๋ฆฐ์ง ์๋ฌ๋ฆฐ์ง ์ธ๋ถ์์๋ ํ์ธ ๋ถ๊ฐ
- ํด๊ฒฐ : ViewTemplate์๊ฒ DTO๋ฅผ ๋ณด๋ด์ค ๋, DTO์์ Comment Count๋ผ๋ ๋ณ์๋ฅผ ์ถ๊ฐํ์ฌ ๊ฐ post ๋น ๋ฌ๋ฆฐ comment์ ๊ฐ์๋ฅผ ํ์ถํด์ค. (๊ฐ post ์ฐ์๋จ์ ํํ)
- #16
- ๊ธฐ์กด์๋ ์ด๋ฆ์์ผ๋ก ์ ๋ ฌํ๋ All members๋ฅผ Studying โ Breaking โ End ์์ผ๋ก ์ ๋ ฌํ์ฌ ํํ
- ํด๊ฒฐ ๋ก์ง :
- ์ผ๋จ ๋ชจ๋ ๋ฉค๋ฒ๋ฅผ DB์์ ๊ฐ์ ธ์จ ํ Memory ๋จ์์ ์ง์ ์ ๋ ฌ ์คํ. โ O(N)
- ๋น ๋ฆฌ์คํธ๋ฅผ ์์ฑํ์ฌ
- ๋ชจ๋ ๋ฉค๋ฒ๋ฅผ ๋๋ฉด์ Studying์ธ ๋ฉค๋ฒ ์ถ๊ฐ
- ๊ทธ ํ ๋ ๋ชจ๋ ๋ฉค๋ฒ๋ฅผ ๋๋ฉด์ Breaking์ธ ๋ฉค๋ฒ ์ถ๊ฐ
- ๊ทธ ํ ๋ง์ง๋ง์ผ๋ก ๋ชจ๋ ๋ฉค๋ฒ๋ฅผ ๋๋ฉด์ End์ธ ๋ฉค๋ฒ ์ถ๊ฐ
- #18
- Body์ font-family๋ฅผ NanumSquareRound ์ ์ฉ โ ๊ธฐ์กด๋ณด๋ค ํจ์ฌ ๋ณด๊ธฐ ์ข์์ง
- #20
- ํต์ผ๋ header,footer๋ฅผ ๋ง๋ ํ ๋ชจ๋ html์ด fragment๋ก ๋ฐ์์ฌ ์ ์๋๋ก ์ค์
- edit,create ํ๋ฉด ๊ฐ์ ๊ฒฝ์ฐ bootstarp ์ด์ธ์ css๋ฅผ ๋ฐ์ผ๋ฉด ์๋๋ฏ๋ก addheader๋ฅผ ์ถ๊ฐ๋ก ์์ฑํ์ฌ home.html์ด fragment๋ก ๋ฐ๋๋ก ์ค์
- #24
- Post Entity์ FormatCreateDate๋ฅผ ์ถ๊ฐํ์ฌ LocalDateTime class๊ฐ ์๋ String์ผ๋ก DB์ ํด๋น ๋ ์ง๋ฅผ ์ํ๋ format ํ์์ผ๋ก ์ ์ฅํ ์ ์๋๋ก ์ค์ (โApril 14, 2022โ ํ์์ผ๋ก ์ ์ฅ)
- ๊ทธ ํ DTO์๋ FormatCreateDate๋ฅผ ์ถ๊ฐํ์ฌ ViewTemplate์ ๊ฐ์ ์ ๋ฌํ ์ ์๋๋ก ์ค์
- ๊ฐ post ์ข์๋จ์ ํ๊ธฐ
<220418>
#14
Back
: Member๊ฐ ์ด๋ฏธ ๊ทธ๋ ๊ณต๋ถ๋ฅผ ์ข ๋ฃํ์ง๋ง, ๋ค์ ๊ณต๋ถ๋ฅผ ์์ํ ๊ฒฝ์ฐ์ ๋ํ ์กฐ์น
#21Front
: ์๋ก์ด Member ๊ฐ์ ๊ณผ ๊ธฐ์กด Member ์ ๋ณด ์์ html์ด ๋ถ๋ฆฌ๋์ง ์์
#7Bug
: ๋ก๊ทธ์ธ์ด ์๋ ์ํ์์ post์ ๋๊ธ์ ๋ฌ ๊ฒฝ์ฐ ์ค๋ฅ ๋ฐ์
#6Back
: Posting ์ญ์ ๊ธฐ๋ฅ ๋ฐ ์ญ์ ๋ฒํผ ์์ฑ
#4Front
: ์ฌ๋ฌ ์ ๋ ฅ placeholder ์์
- #14
-
๊ธฐ์กด์ ๋ฌธ์ ์
Member๊ฐ ๊ณต๋ถ๋ฅผ ์ข ๋ฃํ ํ ๋ค์ ๊ณต๋ถ๋ฅผ ์์ํ๊ณ ์ถ์ ๋ ๊ณต๋ถ ๊ธฐ๋ก์ ์งํํ๋ ๊ธ์ด ๋ถ๋ฌ์์ง๋ ๊ฒ์ด ์๋, ์๋ก์ด ๊ธ์ ์์ฑ๊ฒ๋ ์ค์ ๋์ด ์์์. ์ฆ, ๊ณต๋ถ์ข ๋ฃ๋ฅผ ํ์ง๋ง, ๋ค์ ๊ณต๋ถ๋ฅผ ํ๋ ๊ฒฝ์ฐ์ ๋ํ ์์ธ์ฒ๋ฆฌ๊ฐ ํ์ํ์
-
ํด๊ฒฐ ๋ก์ง
์ผ๋จ ๊ธฐ๋ณธ์ ์ผ๋ก 04์๋ฅผ ํ๋ฃจ์ ์์๊ณผ ๋์ผ๋ก ์ค์ (์๋ฒฝ๋ฐ ๊ณ ๋ ค)
์ฌ์ฉ์๊ฐ End -> Studying ์ผ๋ก State๋ฅผ ๋ณ๊ฒฝํ ์ (๊ณต๋ถ์๋ฃ -> ๊ณต๋ถ์์)์ ์ํฉ- ์ฌ์ฉ์๊ฐ ํ์ฌ ์ด ๊ธ์ด ์กด์ฌํ๋ ์ง ํ๋จ (์ฆ, ์ ๊ท ํ์์ธ์ง ์๋์ง ํ๋จ)
- true (์ด ๊ธ์ด ์กด์ฌ)
- ์ฌ์ฉ์๊ฐ ๊ฐ์ฅ ์ต๊ทผ์ ์์ฑํ ๊ธ์ด ํด๋น ๋ ์ง์ ์์ฑํ ๊ธ์ด๋ฉด์ ์์ฑ ํ ์๊ฐ์ด 04์ ์ดํ์ธ์ง ํ๋จ
- true => ํด๋น ๊ธ์ ๊ฐ์ ธ์์ ์ด์ด ์์ฑํ ์ ์๋๋ก ์ค์
- false
- ํ์ฌ State ๋ณ๊ฒฝ ์์ ์ด 04์ ์ด์ ์ธ์ง ํ๋จ
- true
- ๊ทธ ์ ๋ ์์ฑํ ๊ธ์ด ์กด์ฌํ๋ ์ง, ํด๋น ๊ธ์ด 04์ ์ดํ ์์ฑํ ๊ธ์ธ์ง ํ๋จ
- true => ํด๋น ๊ธ์ ๊ฐ์ ธ์์ ์ด์ด ์์ฑํ ์ ์๋๋ก ์ค์
- flase => ์๋ก์ด ๊ธ ์์ฑ
- ๊ทธ ์ ๋ ์์ฑํ ๊ธ์ด ์กด์ฌํ๋ ์ง, ํด๋น ๊ธ์ด 04์ ์ดํ ์์ฑํ ๊ธ์ธ์ง ํ๋จ
- false => ์๋ก์ด ๊ธ ์์ฑ
- true
- ํ์ฌ State ๋ณ๊ฒฝ ์์ ์ด 04์ ์ด์ ์ธ์ง ํ๋จ
- ์ฌ์ฉ์๊ฐ ๊ฐ์ฅ ์ต๊ทผ์ ์์ฑํ ๊ธ์ด ํด๋น ๋ ์ง์ ์์ฑํ ๊ธ์ด๋ฉด์ ์์ฑ ํ ์๊ฐ์ด 04์ ์ดํ์ธ์ง ํ๋จ
- false => ์๋ก์ด ๊ธ ์์ฑ
- true (์ด ๊ธ์ด ์กด์ฌ)
- ์ฌ์ฉ์๊ฐ ํ์ฌ ์ด ๊ธ์ด ์กด์ฌํ๋ ์ง ํ๋จ (์ฆ, ์ ๊ท ํ์์ธ์ง ์๋์ง ํ๋จ)
-
- #21
- ์ถํ์ bug๊ฐ ๋ฐ์ํ ๊ฒ์ ๋๋นํ์ฌ sign up ํ๋ฉด ๊ณผ eidt ํ๋ฉด์ ๋ถ๋ฆฌ
- createMemberForm.html โ createMemberForm.html + editMemberForm.html
- #7
- ๋ก๊ทธ์ธ์ด ์๋ ์ ์ ๊ฐ Post์ ๋๊ธ์ ๋ฌ ๊ฒฝ์ฐ, alert (โ๋ก๊ทธ์ธ ํ ๋๊ธ์ ๋ค์ค ์ ์์ต๋๋ค.โ) ์ฐฝ์ ๋์ฐ๋๋ก ์ค์
- #6
- ์์์ ์ผ๋ก DeleteMapping์ผ๋ก Controller ์ ์ค์ ํ ๊ฒ์ด ์๋ GetMapping์ผ๋ก ์ค์ ํด๋ . โ ์ถํ DeleteMapping๊ณผ API๋ฅผ ์ฌ์ฉํ์ฌ ํด๊ฒฐ ์์
- edit ํ๋ฉด์ post ์ญ์ ๋ฒํผ ์์ฑ
- #4
- placeholder ์์ (๋์๋ฅผ ์ ๋ ฅํ์ธ์. ๋ฑ ๊ด๋ จ์๋ ๊ฐ๋ค์ด default๊ฐ์ผ๋ก ์ฃผ์ด ์ก์์)