๐Ÿ‘ป [WHYGRAM] | ๋กœ์ง.zip

๐ŸŸฆ ํŒ”๋กœ์šฐ, ํŒ”๋กœ์›Œ ๋ฆฌ์ŠคํŠธ ๋กœ์ง

  • ๋ฆฌ์ŠคํŠธ์—์„œ ํ•„์š”ํ•œ ๊ฒƒ
    : users_id(๊ทธ์‚ฌ๋žŒ์˜ ํŒ”๋กœ์›Œ/ํŒ”๋กœ์šฐ), users_img(๊ทธ์‚ฌ๋žŒ์˜ ํŒ”๋กœ์›Œ/ํŒ”๋กœ์šฐ), users_name(๊ทธ์‚ฌ๋žŒ์˜ ํŒ”๋กœ์›Œ/ํŒ”๋กœ์šฐ), users_nickname(๊ทธ์‚ฌ๋žŒ์˜ ํŒ”๋กœ์›Œ/ํŒ”๋กœ์šฐ), isYourFollower(๋‚ด๊ฐ€ ํŒ”๋กœ์›Œ/ํŒ”๋กœ์šฐ๋ฅผ)
  • ProfileMapper
    • List<UserDomain> selFollowerList(FollowEntity param);
    • FollowEntity (hisFollower : ๋‚˜, him : ๊ทธ์‚ฌ๋žŒ)
    • List<UserDomain> selFollowList(FollowEntity param);
    • FollowEntity(hisFollower : ๊ทธ์‚ฌ๋žŒ , him : ๋‚˜)

โœ… FROM follow๋ž‘ INNER JOIN users์˜ ๊ฒฐ๊ณผ๋ฅผ LEFT JOIN followํ•˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋ฅผ SELECTํ•˜๋Š” ๊ฒƒ์ด๋‹ค~!!!

  • List<UserDomain> selFollowerList(FollowEntity param); , hisFollower : ๋‚˜, him : ๊ทธ์‚ฌ๋žŒ
  • ๊ทธ ์‚ฌ๋žŒ์˜ ํŒ”๋กœ์›Œ๋“ค๊ณผ ๊ทธ ํŒ”๋กœ์›Œ๋“ค์ด ๋‚ด๊ฐ€ ํŒ”๋กœ์šฐ ํ•˜๋Š”์ง€ ๊ตฌํ•œ๋‹ค.
SELECT U.users_id, U.users_img, U.users_name, U.users_nickname, 
-- ๊ทธ์‚ฌ๋žŒ์„ ํŒ”๋กœ์šฐํ•˜๋Š” ์‚ฌ๋žŒ๋“ค 
CASE WHEN W.follow_hisFollower IS NULL THEN 0 ELSE 1 END AS isYourFollower 
-- ๊ทธ์‚ฌ๋žŒ์„ ํŒ”๋กœ์šฐํ•œ ์‚ฌ๋žŒ์„ ๋‚ด๊ฐ€ ํŒ”๋กœ์šฐ ํ•˜๋Š”๊ฐ€ ๐Ÿ‘‰ W.hisFollower = ๋‚˜ , W.him = ๊ทธ์‚ฌ๋žŒ์„ ํŒ”๋กœ์šฐํ•˜๋Š” ์‚ฌ๋žŒ๋“ค
FROM follow F
-- F.follow_him = ๊ทธ ์‚ฌ๋žŒ , F.hisFollower = ๊ทธ์‚ฌ๋žŒ์„ ํŒ”๋กœ์šฐํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์„ 
-- ์„ค์ •(WHERE)ํ•ด์ฃผ๊ธฐ ์œ„ํ•ด์„œ FROM์€ follow์—์„œ
INNER JOIN  users U
-- ๊ทธ์‚ฌ๋žŒ์„ ํŒ”๋กœ์šฐํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์„ ๊ตฌํ•˜๊ธฐ ์œ„ํ•ด INNER JOIN
ON  F.follow_hisFollower=U.users_id 
-- F.follow_him = ๊ทธ ์‚ฌ๋žŒ , F.hisFollower = ๊ทธ์‚ฌ๋žŒ์„ ํŒ”๋กœ์šฐํ•˜๋Š” ์‚ฌ๋žŒ๋“ค = U.users_id = W.him 
LEFT JOIN follow W 
-- ๊ทธ์‚ฌ๋žŒ์„ ํŒ”๋กœ์šฐํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์„ ๋‚ด๊ฐ€ ํŒ”๋กœ์šฐ ํ•˜๋Š”์ง€ ๊ตฌํ•˜๊ธฐ ์œ„ํ•ด LEFT JOIN
ON W.follow_him = F.hisFollower AND W.follow_hisFollower=${๋‚˜} 
WHERE  F.follow_him = ${๊ทธ์‚ฌ๋žŒ}
  • List<UserDomain> selFollowList(FollowEntity param); , hisFollower : ๊ทธ์‚ฌ๋žŒ, him : ๋‚˜
  • ๊ทธ ์‚ฌ๋žŒ์ด ํŒ”๋กœ์šฐ ํ•˜๋Š” ์‚ฌ๋žŒ๋“ค๊ณผ ๊ทธ ํŒ”๋กœ์šฐ๋“ค์„ ๋‚ด๊ฐ€ ํŒ”๋กœ์šฐ ํ•˜๋Š”์ง€ ๊ตฌํ•œ๋‹ค.
SELECT U.users_id, U.users_img, U.users_name, U.users_nickname, 
CASE WHEN W.follow_hisFollower IS NULL THEN 0 ELSE 1 END AS isYourFollower 
FROM follow F
-- ๊ทธ ์‚ฌ๋žŒ์ด ํŒ”๋กœ์šฐ ํ•˜๋Š” ์‚ฌ๋žŒ๋“ค = F.him , ๊ทธ์‚ฌ๋žŒ = F.hisFollower 
-- ์„ค์ •(WHERE)ํ•ด์ฃผ๊ธฐ ์œ„ํ•ด์„œ FROM์€ follow์—์„œ
INNER JOIN users U
-- U.users_id = F.him = ๊ทธ ์‚ฌ๋žŒ์ด ํŒ”๋กœ์šฐํ•˜๋Š” ์‚ฌ๋žŒ๋“ค
ON F.follow_him=U.users_id
LEFT JOIN follow W
-- ๊ทธ ์‚ฌ๋žŒ์ด ํŒ”๋กœ์šฐํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์„ ๋‚ด๊ฐ€ ํŒ”๋กœ์šฐ ํ•˜๋Š”์ง€  
-- ๐Ÿ‘‰ W.him = F.him = U.users_id , W.hisFollower = ๋‚˜
ON W.follow_him=F.follow_him AND W.follow_hisFollower=${๋‚˜}
WHERE F.follow_hisFollower=${๊ทธ์‚ฌ๋žŒ}

  • ๋กœ๊ทธ์ธํ•œ ์‚ฌ๋žŒ์˜ pk : mypageConstElem.dataset.uid
  • ํ”„๋กœํ•„ ์ฃผ์ธ์˜ pk : mypageConstElem.dataset.pid
  • ๋ชจ๋‹ฌ ๋ฆฌ์ŠคํŠธ์˜ pk : item.users_id
  • item์— ๋“ค์–ด์žˆ๋Š” ๊ฒƒ : users_id , users_img , users_name , users_nickname , isYourFollower
  • ๋ชจ๋‹ฌ ๋ฆฌ์ŠคํŠธ ๊ตฌ์กฐ
<tr> 
  <td> <img> ๐Ÿ‘ˆclassName(pointer, wh30, profileRadius) , src , ifnull , onerror , click </td>
  <td> <span>์ด๋ฆ„</span> ( <span> ๋‹‰๋„ค์ž„ </span> ) </td> ๐Ÿ‘ˆpointer , click
  <td> <div> <i></i> </div> </td> ๐Ÿ‘ˆpointer , click(followProc)
</tr>

[profileTr] 
[profileImgTd] - [imgTg] 
[profileNmTd] - [nmSpn] , [nickNmSpn]  
[profileFollowTd] - [btnFollow] - [followIcn]
  • <td> <button> <i></i> </button> </td>
btnFollow.id = 'btnFollow'

isYourFollower = 0 
btnFollow.dataset.follow = 'follow1';
followIcn.className = 'follow-icon bi bi-person';

isYourFollower = 1
btnFollow.dataset.follow = 'unfollow1';
followIcn.className = 'follow-icon bi bi-person-check';

๐ŸŸฆ ๋งˆ์ดํŽ˜์ด์ง€ ๋ฆฌ์ŠคํŠธ ๊ตฌ์กฐ

  • ์„œ๋ฒ„์—์„œ ๊ฐ€์ ธ์™€์•ผ ํ•  ์ •๋ณด
  • feed_id , contents_img[0], isFav, favCnt, CmtCnt, isCmt
  • ์„œ๋น„์Šค์—์„œ userForFav , userForCmt ์„ค์ • ํ•„์š”

๐Ÿ”น html

  • bootstrap - grid , image , spinners
  • mypage.html
<div id="mypageFeed">
  <!---
  <div id="mypageFeedContainer" th:attr="data-fid=${feed_id}"> ๐Ÿ”ธ ๐Ÿ”„* ๋ฐ˜๋ณต ์ถœ๋ ฅ 
          <img src="/pic/feed/{feed_id}/{contents_img}" class="img-thumbnail" 
          onerror="this.src=/img/feed/error.png">
  </div>
  -->
</div>

<div class="hide m-5 d-flex justify-content-center" id="loading">
  <button class="btn btn-primary" type="button" disabled>
    <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
    Loading...
  </button>
</div>
  • ์ด๋ฏธ์ง€
    • th:attr , /pic/feed/{feed_id}/{contents_img} , onerror="this.src=/img/feed/error.png"

๐Ÿ”น js

  • mypageFeed.js
    • feedElem
    • loadingElem
    • mypage_id ๐Ÿ‘‰๐ŸŸฆgetFeedList๐ŸŸฆ
    • limit ๐Ÿ‘‰๐ŸŸฆgetFeedList๐ŸŸฆ
    • itemLength ๐Ÿ‘‰๐ŸŸฆgetFeedList , scrollInfinity๐ŸŸฆ
    • getFeedList
    • makeFeedList
    • scrollInfinity
    • hideLoading
    • showLoading
FeedObj = {
feedElem : document.querySelector('#mypageFeed'),
loadingElem : document.querySelector('#loading'),
mypageList : mypageConstElem.dataset.pid,
limit : 12,
itemLength : 0,
getFeedList : function(page) {
  this.showLoading();
  fetch(`/profile/mypageList?mypage_id=${this.users_id}  ๐Ÿ‘‰๐ŸŸฆusers_id , limit๐ŸŸฆ
  &page=${page}&limit=${this.limit}`)
    .then(res => res.json())
    .then(myJson => {
      console.log(myJson);
      this.itemLength = myJson.length; ๐Ÿ‘‰๐ŸŸฆitemLength (์ธํ”ผ๋‹ˆํ‹ฐ์Šคํฌ๋กค์—์„œ ์“ฐ์ž„)๐ŸŸฆ
      this.makeFeedList(myJson);
    }).catch(err => {
      console.log(err);
      feedElem.innerHTML(`<img src="/img/feed/error.png" class="img-thumbnail wh400">`)
    }).then(() => {
      this.hideLoading();
    });
},
makeFeedList: function(data) {
        if(data.length == 0) { return; }

        for(let i=0; i<data.length; i++) {
            const item = data[i];
      }
},
setScrollInfinity: function(target) {
    target.addEventListener('scroll', () => {
        const {
            scrollTop,
            scrollHeight,
            clientHeight
        } = document.documentElement;

        if (scrollTop + clientHeight >= scrollHeight - 5 && this.itemLength === this.limit) {
            this.itemLength = 0;
            this.getFeedList(++this.currentPage);
        }
    }, { passive: true });
},
hideLoading: function() { this.loadingElem.classList.add('hide');},
showLoading: function() { this.loadingElem.classList.remove('hide'); }
}

๐Ÿ”น java , sql

  • FeedDTO
    • int mypage_id
    • int page
    • int limit
    • int user4FavCmt
    • public int getStartIdx( )
  • FeedDomain
    • (int feed_id)
    • int isFav
    • int isCmt
    • int favCnt
    • int cmtCnt
    • ContentsEntity contents (contents_id , contents_img) - resultMap
  • FeedMapper
    • feedํ…Œ์ด๋ธ”์˜ feed_id์— ๋Œ€ํ•ด ํŠน์ •ํ•œ ๊ฒŒ์‹œ๋ฌผ์— ๋Œ€ํ•œ ์ •๋ณด(๋Œ€ํ‘œ์‚ฌ์ง„๊ณผ ์‚ฌ์ง„์˜ ๊ธฐ๋ณธํ‚ค, ์ข‹์•„์š” ๊ฐœ์ˆ˜์™€ ๋Œ“๊ธ€ ๊ฐœ์ˆ˜, ๋กœ๊ทธ์ธ ์œ ์ €์˜ ์ข‹์•„์š” ์—ฌ๋ถ€์™€ ๋Œ“๊ธ€ ์—ฌ๋ถ€)๋ฅผ ์–ป๊ธฐ ์œ„ํ•œ SQL
    • List<FeedDomain> selMypageList(FeedDTO param)

๐Ÿ”น hover

  • https://github.com/WHYGRAM/DONELISTS-ERRORS/issues/48#issuecomment-894040980
  • ๋ฆฌ์ŠคํŠธ ์ค‘ ํŠน์ •ํ•œ ๊ฒŒ์‹œ๋ฌผ ์œ„์— ๋งˆ์šฐ์Šค๋ฅผ ์˜ฌ๋ ธ์„ ๋•Œ,
    • ๊ทธ ๊ฒŒ์‹œ๋ฌผ์˜ ์ข‹์•„์š” ์ˆ˜์™€ ๋Œ“๊ธ€ ์ˆ˜๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.
  • ๋กœ๊ทธ์ธ์œ ์ €๊ฐ€ ๊ฒŒ์‹œ๋ฌผ์— ์ข‹์•„์š”๋ฅผ ๋ˆŒ๋ €์„ ๋•Œ๋Š”
    • <i class="bi bi-heart-fill"></i> ๊ฒ€์ • ํ•˜ํŠธ
  • ์ข‹์•„์š”๋ฅผ ๋ˆ„๋ฅด์ง€ ์•Š์•˜์„ ๋•Œ๋Š”
    • <i class="bi bi-heart"></i> ๋นˆ ํ•˜ํŠธ
  • ๋Œ“๊ธ€์„ ๋‹ฌ์•˜์„ ๋•Œ๋Š”
    • <i class="bi bi-chat-left-quote-fill"></i> ๊ฒ€์ • ๋งํ’์„ 
  • ๋Œ“๊ธ€์„ ๋‹ฌ์ง€ ์•Š์•˜์„ ๋•Œ๋Š”
    • <i class="bi bi-chat-left-quote"></i> ๋นˆ ๋งํ’์„ 
const mementos = [];
mementos.push(feedElem.innerHTML);
mementos.push(`
<div class="wh70 blurImg"></div>
`);

๐ŸŸฆ ๋งˆ์ดํŽ˜์ด์ง€ ๋””ํ…Œ์ผ ๊ตฌ์กฐ

  • mypage.html.id : mypageDetailModal
  • mypageDetail.js : showMypageDetail(feed_id, mypage_id, isFav, isCmt)
    • โ†ณgetMypageDetail(feed_id, mypage_id, isFav, isCmt)
    • /profile/mypageDetail?feed_id=${feed_id}&mypage_id=${mypageId}&isFav=${isFav}&isCmt=${isCmt}
      • โ†ณsetMypageDetail(data)
        • โ†ณ set Profile - users_img, users_nickname, getDateTimeInfo(users_regdt)
        • setImgSlide - contents , bootstrap
        • setFav - feed_fav , isFav
        • setCmt - cmt , cmt_fav , isCmt
  • FeedDTO
  • FeedDomain
  • ProfileController
    • @ResponseBody , @GetMapping(/mypageDetail)
    • FeedDomain mypageDetail(FeedDTO)
  • ProfileService : FeedDomain selMypageDetail(FeedDTO param)
  • ProfileMapeer : FeedDomain selMypageDetail(FeedDTO param)

๐ŸŸฆ ๋Œ“๊ธ€๋ฆฌ์ŠคํŠธ

๐Ÿ”น getCmtList

๐Ÿ”น CmtDomain ๐Ÿ‘‰LIST

  • getCmtList์—์„œ ๊ตฌํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ
  • users_img , users_nickname
  • (CmtEntity) cmt : (cmt_id , feed_id , users_id , cmt_cmt , cmt_regdt)
  • (CmtFavEntity) cmtFav : (users_id , feed_id , cmt_id)
  • cmtFavCnt , isCmtFav

์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ