
classList.toggle()querySelectorAll()nodeList. for๋ฌธ ๋๋ foreach ๋ฌธ์ ์ฌ์ฉ.MyConst public final String PROFILE = "profile";
public final String PROFILE_LIST = "profileList";
public final String RESULT = "result";
public final String YOU_FOLLOW_ME = "youFollowMe";
commonHeader.html<header th:fragment="header">
<span id="globalConst" sec:authorize="isAuthenticated()"
th:with="auth=${#authentication.getPrincipal().getUser()}"
th:attr="data-iuser=${auth.iuser}, data-writer=${auth.nm}, data-writer-profile=${auth.mainProfile}"></span>
...
<ul class="menus" sec:authorize="isAuthenticated()" th:with="auth=${#authentication.getPrincipal().getUser()}">
<li>
<a th:href="@{/user/profile}">
<span class="span__profile">
<img class="profile wh50" th:if="${auth.mainProfile != null}"
th:src="@{/pic/profile/{iuser}/{img}(iuser=${auth.iuser}, img=${auth.mainProfile})}">
<span th:text="${auth.nm}"></span>
</span>
</a>
</li>
...
</ul>
- ๋ก๊ทธ์ธํ ์ ์ ์ธ ๊ฒฝ์ฐ
auth์ ์ ๋ณด๊ฐ ๋ด๊ธด๋ค- ์ฌ์ง ๋๋ ์ด๋ฆ์ ๋๋ฅด๋ฉด
/user/profile๋ด ํ๋กํ๋ก ์ด๋ํ๋ค
feed.jsfunction moveToProfile(iuser) {
location.href = `/user/profile?iuser=${iuser}`;
}
- ํผ๋์์ ํ๋กํ์ฌ์ง์ ๋๋ฅด๋ฉด
/user/profile?iuser=${iuser}๊ทธ ์ฌ๋์ ํ๋กํ๋ก ์ด๋ํ๋ค.
UserController@GetMapping("/profile")
public void profile(Model model, UserEntity param, @AuthenticationPrincipal CustomUserPrincipal userDetails) {
System.out.println(param);
UserDTO param2 = new UserDTO();
param2.setYouIuser(param.getIuser());
if(param2.getYouIuser() == 0) {
param2.setYouIuser(userDetails.getUser().getIuser());
param.setIuser(userDetails.getUser().getIuser());
}
model.addAttribute(myConst.PROFILE, service.selUserProfile(param2));
model.addAttribute(myConst.PROFILE_LIST, service.selUserProfileList(param));
}
- ํ๋ผ๋ฏธํฐ๋ก ๋์ด์จ
UserEntity์iuser๊ฐ์ด ์๋ค๋ฉด
- ์ฆ, ๋์ ํ๋กํ๋ก ์ด๋ํ๋ ๊ฑฐ๋ผ๋ฉด
youIuser(UserDTO)์iuser(UserEntity)๋ ๋์ด๋ค.html๋กprofile : UserDomain ๊ฐ์ฒด,profileList : List<UserProfileEntity> ๊ฐ์ฒด๋ฅผ ๋๊ฒจ์ค๋ค.
UserSerivce@Autowired private IAuthenticationFacade auth;
public UserDomain selUserProfile(UserDTO param) {
param.setMeIuser(auth.getLoginUserPk());
return profileMapper.selUserProfile(param);
}
UserDTO๋ฅผ ์ธํ ํด์ฃผ๊ณmapper์ ๊ฒฐ๊ณผUserDomain์ ๊ฐ์ฒด๋ฅผ ๋ฆฌํดํ๋ค.
- ๋์ ํ๋กํ๋ก ์ด๋ํ ๊ฒฝ์ฐ
YouIuser = ๋ , MeIuser = ๋- ๋ค๋ฅธ ์ฌ๋์ ํ๋กํ๋ก ์ด๋ํ ๊ฒฝ์ฐ
YouIuser = ๊ทธ์ฌ๋ , MeIuser = ๋
UserProfileMapperUserDomain selUserProfile(UserDTO param);
<select id="selUserProfile" resultType="UserDomain">
SELECT
A.iuser, A.email, A.nm, A.tel, A.mainProfile, A.regdt
, (SELECT COUNT(ifeed) FROM t_feed WHERE iuser = ${youIuser}) AS cntFeed
, (SELECT COUNT(iuserMe) FROM t_user_follow WHERE iuserMe = ${youIuser}) AS cntFollow
, (SELECT COUNT(iuserYou) FROM t_user_follow WHERE iuserYou = ${youIuser}) AS cntFollower
, (SELECT COUNT(iuserMe) FROM t_user_follow WHERE iuserMe = ${youIuser} AND iuserYou = ${meIuser}) AS isYouFollowMe
, (SELECT COUNT(iuserMe) FROM t_user_follow WHERE iuserMe = ${meIuser} AND iuserYou = ${youIuser}) AS isMeFollowYou
FROM t_user A
WHERE A.iuser = ${youIuser}
</select>
cntFeed
iuser=๋ด ํ๋กํ : ๋,๋ค๋ฅธ์ฌ๋ ํ๋กํ : ๊ทธ์ฌ๋=${youIuser}- ๋ด ํ๋กํ์ ๋ค์ด๊ฐ ๋๋ [ ๋ ]์.
- ๋ค๋ฅธ์ฌ๋ ํ๋กํ์ ๋ค์ด๊ฐ ๋๋ [ ๊ทธ์ฌ๋์ ]
ifeed๊ฐฏ์๋ฅผ.
cntFollow
iuserMe=๋ด ํ๋กํ : ๋,๋ค๋ฅธ์ฌ๋ ํ๋กํ : ๊ทธ์ฌ๋=${youIuser}- ๋ด๊ฐ ๋ค๋ฅธ์ฌ๋์ ํ๋ก์ฐํ(
iuserMe) ๊ฐฏ์๋ฅผ (iuserMe๊ฐ [ ๋ ]์ ์ ์ฅ์์ [ ๋ค๋ฅธ์ฌ๋ ]์ ํ๋ก์ฐํ ๊ฒ์ด๋ค.)- ๋ด ํ๋กํ์ ๋ค์ด๊ฐ ๋๋
๋ด๊ฐ [ ๋ ] , (iuserMe = ${youIuser})- ๋ค๋ฅธ ์ฌ๋ ํ๋กํ์ ๋ค์ด๊ฐ ๋๋
๊ทธ์ฌ๋์ด [ ๋ ]
cntFollower
iuserYou=๋ด ํ๋กํ : ๋,๋ค๋ฅธ์ฌ๋ ํ๋กํ : ๊ทธ์ฌ๋=${youIuser}- ๋ค๋ฅธ์ฌ๋์ด ๋๋ฅผ ํ๋ก์ฐํ(iuserYou) ๊ฐฏ์๋ฅผ (
iuserYou๊ฐ [ ๋ ]์ ์ ์ฅ์์ ๋ค๋ฅธ ์ฌ๋๋ค์ด ๋๋ฅผ ํ๋ก์ฐ ํ ๊ฒ์ด๋ค.)- ๋ด ํ๋กํ์ ๋ค์ด๊ฐ ๋๋
๋ด๊ฐ [ ๋ ] (iuserYou = ${youIuser})- ๋ค๋ฅธ์ฌ๋ ํ๋กํ์ ๋ค์ด๊ฐ ๋๋
๊ทธ์ฌ๋์ด [ ๋ ]
isYouFollowMe
iuserMe=๋ด ํ๋กํ : ๋,๋ค๋ฅธ์ฌ๋ ํ๋กํ : ๊ทธ์ฌ๋=${youIuser}iuserYou=๋ด ํ๋กํ : ๋,๋ค๋ฅธ์ฌ๋ ํ๋กํ : ๋=${meIuser}- ๋ด๊ฐ ๋ค๋ฅธ์ฌ๋์ ํ๋ก์ฐํ(
iuserMe)๊ฐฏ์๋ฅผ (iuserMe๊ฐ [ ๋ ]์ ์ ์ฅ์์ [ ๋ค๋ฅธ์ฌ๋ ]๋ค์ ํ๋ก์ฐํ ๊ฒ์ด๋ค.)- ๋ดํ๋กํ์ ๋ค์ด๊ฐ ๋๋
๋ด๊ฐ [ ๋ ] ,๋ด๊ฐ [ ๋ค๋ฅธ์ฌ๋ ]- ๋ค๋ฅธ์ฌ๋ ํ๋กํ์ ๋ค์ด๊ฐ ๋๋
๊ทธ์ฌ๋์ด [ ๋ ] ,๋ด๊ฐ [ ๋ค๋ฅธ์ฌ๋ ]iuserMe=${youIuser},iuserYou=${meIuser}- ๊ทธ๋์ ๋ดํ๋กํ์ ๋ค์ด๊ฐ ๋๋ ๋ฌด์กฐ๊ฑด
isYouFollowMe๋ 0์ด ๋์ค๊ณ ,- ๋ค๋ฅธ์ฌ๋ ํ๋กํ์ ๋ค์ด๊ฐ ๋๋ (
๊ทธ์ฌ๋์ด [ ๋ ] ,๋ด๊ฐ [ ๋ค๋ฅธ์ฌ๋ ])๊ทธ์ฌ๋์ด๋๋ฅผ ํ๋ก์ฐํ์ ๋๋ง 1์ด ๋์จ๋ค.
isMeFollowYou
- ๋ด๊ฐ ๋ค๋ฅธ์ฌ๋์ ํ๋ก์ฐํ(iuserMe) ๊ฐฏ์๋ฅผ (
iuserMe๊ฐ [ ๋ ]์ ์ ์ฅ์์ [ ๋ค๋ฅธ์ฌ๋ ]๋ค์ ํ๋ก์ฐํ ๊ฒ์ด๋ค.)- ๋ด ํ๋กํ์ ๋ค์ด๊ฐ ๋๋
๋ด๊ฐ [ ๋ ],๋ด๊ฐ [ ๋ค๋ฅธ์ฌ๋ ]- ๋ค๋ฅธ์ฌ๋ ํ๋กํ์ ๋ค์ด๊ฐ ๋๋
๋ด๊ฐ [ ๋ ],๊ทธ์ฌ๋์ด [ ๋ค๋ฅธ์ฌ๋ ]iuserMe=${meIuser},iuserYou=${youIuser}- ๊ทธ๋์ ๋ด ํ๋กํ์ ๋ค์ด๊ฐ ๋๋ ๋ฌด์กฐ๊ฑด
isYouFollowMe์isMeFollowYou๋ 0์ด ๋์ค๊ณ- ๋ค๋ฅธ์ฌ๋ ํ๋กํ์ ๋ค์ด๊ฐ ๋๋ (
๋ด๊ฐ [ ๋ ],๊ทธ์ฌ๋์ด [ ๋ค๋ฅธ์ฌ๋ ])๋ด๊ฐ๊ทธ์ฌ๋์ ํ๋ก์ฐํ์ ๋๋ง 1์ด ๋์จ๋ค.
cntFollow: ๋ด ํ๋กํ - ๋ด๊ฐ ํ๋ก์ฐ , ๋ค๋ฅธ์ฌ๋ ํ๋กํ - ๊ทธ์ฌ๋์ด ํ๋ก์ฐ (iuserMe)
cntFollower: ๋ดํ๋กํ - ๋๋ฅผ ํ๋ก์ฐ, ๋ค๋ฅธ์ฌ๋ ํ๋กํ - ๊ทธ์ฌ๋์ ํ๋ก์ฐ (iuserYou)
isYouFollowMe: ๋ค๋ฅธ์ฌ๋ ํ๋กํ - ๊ทธ์ฌ๋์ด ๋๋ฅผ ํ๋ก์ฐ (iuserMe=${youIuser},iuserYou=${meIuser})
isMeFollowYou: ๋ค๋ฅธ์ฌ๋ ํ๋กํ - ๋ด๊ฐ ๊ทธ์ฌ๋์ ํ๋ก์ฐ (iuserMe=${meIuser},iuserYou=${youIuser})
tableCREATE TABLE t_user_follow (
iuserMe INT UNSIGNED,
iuserYou INT UNSIGNED,
regdt DATETIME DEFAULT NOW(),
PRIMARY KEY(iuserMe, iuserYou),
FOREIGN KEY (iuserMe) REFERENCES t_user(iuser),
FOREIGN KEY (iuserYou) REFERENCES t_user(iuser)
);
UserFollowEntitypublic class UserFollowEntity {
private int iuserMe;
private int iuserYou;
private String regdt;
}
UserEntity private int iuser;
private String provider;
private String email;
private String pw;
private String nm;
private String tel;
private String authCd;
private String mainProfile;
private String regdt;
UserDomainpublic class UserDomain extends UserEntity {
private int cntFeed; //ํผ๋ ์นด์ดํธ
private int cntFollower; //ํ๋ก์ ์นด์ดํธ
private int cntFollow; //ํ๋ก์ฐ ์นด์ดํธ
private int isYouFollowMe; //๋๋ ๋๋ฅผ ํ๋ก์ฐ ํ๋
private int isMeFollowYou; //๋๋ ๋๋ฅผ ํ๋ก์ฐ ํ๋
}
UserDTOpublic class UserDTO {
private int meIuser;
private int youIuser;
}
profile.html<div id="localConst" th:attr="data-iuser=${profile.iuser}"></div>
<td th:unless="${auth.iuser eq profile.iuser}">
<th:block th:if="${profile.isMeFollowYou eq 1}">
<input type="button" class="instaBtn instaBtnEnable" id="btnFollow" data-follow="1" value="ํ๋ก์ฐ ์ทจ์">
</th:block>
<th:block th:unless="${profile.isMeFollowYou eq 1}">
<th:block th:if="${profile.isYouFollowMe eq 1}">
<input type="button" class="instaBtn" id="btnFollow" data-follow="0" value="๋งํ๋ก์ฐ">
</th:block>
<th:block th:unless="${profile.isYouFollowMe eq 1}">
<input type="button" class="instaBtn" id="btnFollow" data-follow="0" value="ํ๋ก์ฐ">
</th:block>
</th:block>
</td>
- ์๋๋ฐฉ์ ํ์ด์ง
- ๋ด๊ฐ ์ด ์ฌ๋์ ํ๋ก์ฐ ํ์ผ๋ฉด
ํ๋ก์ฐ ์ทจ์๋ฒํผ.- ๋ด๊ฐ ์ด ์ฌ๋์ ํ๋ก์ฐ ํ์ง ์์์ผ๋ฉด
๋งํ๋ก์ฐ๋ฒํผ. ๐ ๊ทผ๋ฐ ์๋๋ฐฉ์ ๋๋ฅผ ํ๋ก์ฐ ํ๋ค๋ฉดํ๋ก์ฐ๋ฒํผ. ๐ ์๋๋ฐฉ๋ ๋๋ฅผ ํ๋ก์ฐ ํ์ง ์์๋ค๋ฉด
profile.jsconst btnFollowElem = document.querySelector('#btnFollow'); //ํ๋ก์ฐ ๋ฒํผ
//ํ๋ก์ฐ ์ฒ๋ฆฌ
//type: 0 > ํ๋ก์ฐ ์ฒ๋ฆฌ
//type: 1 > ํ๋ก์ฐ ์ทจ์
function followProc(type, iuserYou, btnElem) {
const init = {};
const param = { iuserYou };
let queryString = '';
switch (type) {
case 0:
init.method = 'POST';
init.headers = { 'Content-Type': 'application/json' };
init.body = JSON.stringify(param);
break;
case 1:
init.method = 'DELETE';
queryString = `?iuserYou=${iuserYou}`;
break;
}
fetch('follow' + queryString, init)
.then(res => res.json())
.then(myJson => {
if(myJson.result === 1) {
let buttnNm = 'ํ๋ก์ฐ ์ทจ์';
if(btnElem.dataset.follow === '1') {
if(myJson.youFollowMe == null) { buttnNm = 'ํ๋ก์ฐ'; }
else { buttnNm = '๋งํ๋ก์ฐ'; }
}
btnElem.classList.toggle('instaBtnEnable');
btnElem.value = buttnNm;
btnElem.dataset.follow = 1 - btnElem.dataset.follow;
} else {
alert('์๋ฌ๊ฐ ๋ฐ์ํ์์ต๋๋ค.');
}
});
}
if(btnFollowElem) {
btnFollowElem.addEventListener('click', () => {
const follow = parseInt(btnFollowElem.dataset.follow);
const iuser = localConstElem.dataset.iuser;
followProc(follow, iuser, btnFollowElem);
});
}
UserController @ResponseBody
@PostMapping("/follow")
public Map<String, Object> doFollow(@RequestBody UserFollowEntity param) {
return service.insUserFollow(param);
}
@ResponseBody
@DeleteMapping("/follow")
public Map<String, Object> cancelFollow(UserFollowEntity param) {
return service.delUserFollow(param);
}
UserFollowEntity,iuserYou: ๋ค๋ฅธ ์ฌ๋ ํ๋กํ(๊ทธ์ฌ๋)
UserService //ํ๋ก์ฐ ํ๊ธฐ
public Map<String, Object> insUserFollow(UserFollowEntity param) {
param.setIuserMe(auth.getLoginUserPk());
Map<String, Object> res = new HashMap();
res.put(myConst.RESULT, mapper.insUserFollow(param));
return res;
}
//ํ๋ก์ฐ ์ทจ์
public Map<String, Object> delUserFollow(UserFollowEntity param) {
param.setIuserMe(auth.getLoginUserPk());
int result = mapper.delUserFollow(param);
Map<String, Object> res = new HashMap();
res.put(myConst.RESULT, result);
if(result == 1) {
UserFollowEntity param2 = new UserFollowEntity();
param2.setIuserMe(param.getIuserYou());
param2.setIuserYou(param.getIuserMe());
UserFollowEntity result2 = mapper.selUserFollow(param2);
res.put(myConst.YOU_FOLLOW_ME, result2);
}
return res;
}
insUserFollow:
UserFollowEntity,iuserYou: ๋ค๋ฅธ ์ฌ๋ ํ๋กํ(๊ทธ์ฌ๋) ,iuserMe: ๋- ๋ด๊ฐ ๊ทธ ์ฌ๋์ ํ๋ก์ฐ ํ๋ค.
Map<String, Object> res:"result",0 ๋๋ 1
delUserFollow:
UserFollowEntity,iuserYou: ๋ค๋ฅธ ์ฌ๋ ํ๋กํ(๊ทธ์ฌ๋) ,iuserMe: ๋- ๋ด๊ฐ ๊ทธ ์ฌ๋์ ํ๋ก์ฐ ํ๋ค.
UserFollowEntity,iuserYou: ๋ ,iuserMe: ๋ค๋ฅธ ์ฌ๋ ํ๋กํ(๊ทธ์ฌ๋)- ๊ทธ ์ฌ๋์ด ๋๋ฅผ ํ๋ก์ฐ ํ๋ค.
Map<String, Object> res:
"result",0 ๋๋ 1"youFollowMe",null ๋๋ UserFollowEntity(iuserYou : ๋ , iuserMe : ๋ค๋ฅธ ์ฌ๋ ํ๋กํ(๊ทธ์ฌ๋))
UserMapperint insUserFollow(UserFollowEntity param);
UserFollowEntity selUserFollow(UserFollowEntity param);
int delUserFollow(UserFollowEntity param);
<insert id="insUserFollow">
INSERT INTO t_user_follow
( iuserMe, iuserYou )
VALUES
( ${iuserMe}, ${iuserYou} )
</insert>
<delete id="delUserFollow">
DELETE from t_user_follow
WHERE iuserMe = ${iuserMe} AND iuserYou = ${iuserYou}
</delete>
<select id="selUserFollow" resultType="UserFollowEntity">
SELECT iuserMe, iuserYou, regdt FROM t_user_follow
WHERE iuserMe = ${iuserMe}
AND iuserYou = ${iuserYou}
</select>
insUserFollow:( ${iuserMe} : ๋ , ${iuserYou} : ๊ทธ์ฌ๋ )delUserFollow:( ${iuserMe} : ๋ , ${iuserYou} : ๊ทธ์ฌ๋ )insUserFollow:( ${iuserMe} : ๊ทธ์ฌ๋ , ${iuserYou} : ๋ )
header์์ ๋๋ feed์์ ํ๋กํ๊ฐ๊ธฐ๋ฅผ ๋๋ฅธ๋ค.
/user/profile/user/profile?iuser=${iuser}๐ @controller
๋ด ํ๋กํ : UserDTO.youIuser = ๋
๋ค๋ฅธ์ฌ๋ ํ๋กํ : UserDTO.youIuser = ๊ทธ์ฌ๋
๐ @service
๋ด ํ๋กํ : UserDTO.meIuser = ๋ , youIuser = ๋
๋ค๋ฅธ์ฌ๋ ํ๋กํ : UserDTO.meIuser = ๋ , youIuser = ๊ทธ์ฌ๋
๐ @mapper
๋ด ํ๋กํ
UserDomain.๋์iuser , email , nm , tel , mainProfile , regdt , cntFeed , cntFollow , cntFollowerisYouFollowMe(0) , isMeFollowMe(0)๋ค๋ฅธ์ฌ๋ ํ๋กํ
UserDomain.๊ทธ์ฌ๋์iuser , email , nm , tel , mainProfile , regdt , cntFeed , cntFollow , cntFollowerisYouFollowMe , isMeFollowMe๐ @controller
"profile" , UserDomain
๐ profile.html
๐ profile.js - ๋ด ํ๋กํ์ผ๊ฒฝ์ฐ ์ฌ๊ธฐ๋ก ์ฌ ์ ์๋ค.
btnFollowElem.dataset.follow : 0(ํ๋ก์ฐ) , 1(ํ๋ก์ฐ์ทจ์)
localConstElem.dataset.iuser : profile.iuser(๊ทธ์ฌ๋)
followProc( follow, iuser, btnFollowElem)
follow (0-@Post /user/follow | 1-@Delete /user/follow) iuser (profile.iuser(๊ทธ์ฌ๋) = UserFollowEntity.iuserYou)ํ๋ก์ฐ์ฒ๋ฆฌ : "result" , 1
btnNm = 'ํ๋ก์ฐ์ทจ์'classList = instaBtn instaBtnEnabledataset.follow = 1<input type="button" class="instaBtn" id="btnFollow" data-follow="0" value="(๋ง)ํ๋ก์ฐ"><input type="button" class="instaBtn instaBtnEnable" id="btnFollow" data-follow="1" value="ํ๋ก์ฐ ์ทจ์">ํ๋ก์ฐ์ทจ์์ฒ๋ฆฌ : "result" , 1 | "youFollowMe" , null ๋๋ UserFollowEntity(iuserMe ๊ทธ์ฌ๋ , iuserYou ๋)
btnNm = 'ํ๋ก์ฐ์ทจ์' ๐ 'ํ๋ก์ฐ' | '๋งํ๋ก์ฐ'classList = instaBtndataset.follow = 0<input type="button" class="instaBtn instaBtnEnable" id="btnFollow" data-follow="1" value="ํ๋ก์ฐ ์ทจ์"><input type="button" class="instaBtn" id="btnFollow" data-follow="0" value="(๋ง)ํ๋ก์ฐ">profile.html<header th:fragment="header">
<span id="globalConst" sec:authorize="isAuthenticated()" th:with="auth=${#authentication.getPrincipal().getUser()}"
th:attr="data-iuser=${auth.iuser}, data-writer=${auth.nm}, data-writer-profile=${auth.mainProfile}"></span>
<div id="localConst" th:attr="data-iuser=${profile.iuser}"></div>
<td class="pointer follower">ํ๋ก์</td>
<td class="pointer follower" th:text="${profile.cntFollower}"></td>
<td class="pointer follow">ํ๋ก์ฐ</td>
<td class="pointer follow" th:text="${profile.cntFollow}"></td>
<div class="modal-follow hide">
<div>
<div class="container">
<div class="top">
<div id="title">ํ๋ก์ฐ</div>
<i id="modal-follow-close" class="moodal_clse fas fa-times"></i>
</div>
<div class="followCont"></div>
</div>
</div>
</div>
ํ๋ก์ฐ,ํ๋ก์ฐ ์๋๋ํ๋ก์,ํ๋ก์ ์๋ฅผ ๋๋ฅด๋ฉด ์ฌ์ฉ์๋ฆฌ์คํธ ๋ชจ๋ฌ์ฐฝ์ด ๋ฌ๋ค.
profile.jsconst followerElemArr = document.querySelectorAll('.pointer.follower');
const followElemArr = document.querySelectorAll('.pointer.follow');
const modalFollowElem = document.querySelector('.modal-follow');
const modalFollowTitleElem = modalFollowElem.querySelector('#title');
const modalFollowCloseElem = document.querySelector('.modal-follow #modal-follow-close');
const modalFollowItemConElem = modalFollowElem.querySelector('.followCont');
if(followerElemArr) {
followerElemArr.forEach(item => {
item.addEventListener('click', () => {
modalFollowTitleElem.innerText = 'ํ๋ก์';
modalFollowElem.classList.remove('hide');
modalFollowItemConElem.innerHTML = '';
//ํ๋กํ ์ฌ์ฉ์๋ฅผ ํ๋ก์ฐํ ์ฌ๋๋ค ๋ฆฌ์คํธ
fetch(`getFollowerList?iuserYou=${localConstElem.dataset.iuser}`)
.then(res => res.json())
.then(myJson => {
if(myJson.length > 0) {
myJson.forEach(item => {
const cont = makeFollowItem(item);
modalFollowItemConElem.append(cont);
});
}
});
});
});
}
if(followElemArr) {
followElemArr.forEach(item => {
item.addEventListener('click', () => {
modalFollowTitleElem.innerText = 'ํ๋ก์ฐ';
modalFollowElem.classList.remove('hide');
modalFollowItemConElem.innerHTML = '';
//ํ๋กํ ์ฌ์ฉ์๊ฐ ํ๋ก์ฐํ ์ฌ๋๋ค ๋ฆฌ์คํธ
fetch(`getFollowList?iuserYou=${localConstElem.dataset.iuser}`)
.then(res => res.json())
.then(myJson => {
if(myJson.length > 0) {
myJson.forEach(item => {
const cont = makeFollowItem(item);
modalFollowItemConElem.append(cont);
});
}
});
});
});
}
if(modalFollowCloseElem) {
modalFollowCloseElem.addEventListener('click', () => {
modalFollowElem.classList.add('hide');
});
}
function makeFollowItem(item) {
const globalContElem = document.querySelector('#globalConst');
const loginIuser = globalContElem.dataset.iuser;
const cont = document.createElement('div');
cont.className = 'follow-item';
const img = document.createElement('img');
img.className = 'profile wh30 pointer';
img.src = `/pic/profile/${item.iuser}/${item.mainProfile}`;
img.onerror = () => { img.style.visibility = 'hidden'; }
img.addEventListener('click', ()=> {
moveToProfile(item.iuser); //feed.js ์ ์๋ ๋ฉ์๋
});
const nm = document.createElement('div');
const nmText = document.createElement('span');
nmText.innerText = item.nm;
nmText.className = 'pointer';
nmText.addEventListener('click', ()=> {
moveToProfile(item.iuser); //feed.js ์ ์๋ ๋ฉ์๋
});
nm.append(nmText);
const btn = document.createElement('input');
btn.className = 'instaBtn pointer';
btn.dataset.follow = '0';
btn.addEventListener('click', () => {
const follow = parseInt(btn.dataset.follow);
followProc(follow, item.iuser, btn);
});
cont.append(img);
cont.append(nm);
if(parseInt(loginIuser) !== item.iuser) {
btn.type = 'button';
if(item.isMeFollowYou) {
btn.dataset.follow = '1';
btn.value = 'ํ๋ก์ฐ ์ทจ์';
} else {
btn.classList.add('instaBtnEnable');
btn.value = 'ํ๋ก์ฐ';
}
cont.append(btn);
}
return cont;
}
followerElemArr:<td class="pointer follower">ํ๋ก์</td><td class="pointer follower" th:text="${profile.cntFollower}"></td>followElemArr:<td class="pointer follow">ํ๋ก์ฐ</td><td class="pointer follow" th:text="${profile.cntFollow}"></td>modalFollowElem:<div class="modal-follow hide"> <div> <div class="container"> <div class="top"> <div id="title">ํ๋ก์ฐ</div> <i id="modal-follow-close" class="moodal_clse fas fa-times"></i> </div> <div class="followCont"></div> </div> </div> </div>modalFollowTitleElem:<div id="title">ํ๋ก์ฐ</div>modalFollowCloseElem:<i id="modal-follow-close" class="moodal_clse fas fa-times"></i>modalFollowItemConElem:<div class="followCont"></div>
UserController@ResponseBody
@GetMapping("/getFollowerList")
public List<UserDomain> getFollowerList(UserFollowEntity param) {
return service.selUserFollowerList(param);
}
@ResponseBody
@GetMapping("/getFollowList")
public List<UserDomain> getFollowList(UserFollowEntity param) {
return service.selUserFollowList(param);
}
UserServicepublic List<UserDomain> selUserFollowerList(UserFollowEntity param) {
param.setIuserMe(auth.getLoginUserPk());
return mapper.selUserFollowerList(param);
}
public List<UserDomain> selUserFollowList(UserFollowEntity param) {
param.setIuserMe(auth.getLoginUserPk());
return mapper.selUserFollowList(param);
}
UserMapperList<UserDomain> selUserFollowerList(UserFollowEntity param);
List<UserDomain> selUserFollowList(UserFollowEntity param);
<select id="selUserFollowerList" resultType="UserDomain">
SELECT B.iuser, B.nm, B.mainProfile
, CASE WHEN C.iuserMe IS NULL THEN 0 ELSE 1 END AS isMeFollowYou
FROM t_user_follow A
INNER JOIN t_user B
ON A.iuserMe = B.iuser
LEFT JOIN t_user_follow C
ON C.iuserMe = ${iuserMe} -- ๋ก๊ทธ์ธํ ์ฌ๋ pk
AND C.iuserYou = A.iuserMe
WHERE A.iuserYou = ${iuserYou} -- ํ๋กํ ์ฃผ์ธ์ฅ pk
</select>
<select id="selUserFollowList" resultType="UserDomain">
SELECT B.iuser, B.nm, B.mainProfile
, CASE WHEN C.iuserMe IS NULL THEN 0 ELSE 1 END AS isMeFollowYou
FROM t_user_follow A
INNER JOIN t_user B
ON A.iuserYou = B.iuser
LEFT JOIN t_user_follow C
ON C.iuserMe = ${iuserMe} -- ๋ก๊ทธ์ธํ ์ฌ๋ pk
AND C.iuserYou = A.iuserYou
WHERE A.iuserMe = ${iuserYou} -- ํ๋กํ ์ฃผ์ธ์ฅ pk
</select>
profile.js followerElemArr.forEach(item => { item.addEventListener('click', () => {})});
getFollowList?iuserYou=${localConstElem.dataset.iuser}
${localConstElem.dataset.iuser}=${profile.iuser}๐ [ ๋ ] ๋๋ [ ๊ทธ์ฌ๋ ]์ iuser
๐
UserController. getFollowerList()
@ResponseBody
@GetMapping("/getFollowerList")
public List<UserDomain> getFollowerList(UserFollowEntity param) {
return service.selUserFollowerList(param);
}
UserFollowEntity.iuserYou(๊ทธ์ฌ๋ ๋๋ ๋)
๐
UserService.selUserFollowerList()
public List<UserDomain> selUserFollowerList(UserFollowEntity param) {
param.setIuserMe(auth.getLoginUserPk());
return mapper.selUserFollowerList(param);
}
UserFollowEntity.iuserYou(๊ทธ์ฌ๋ ๋๋ ๋) | iuserMe(๋)
๐
UserMapper.selUserFollowerList()
<select id="selUserFollowerList" resultType="UserDomain">
SELECT B.iuser, B.nm, B.mainProfile
, CASE WHEN C.iuserMe IS NULL THEN 0 ELSE 1 END AS isMeFollowYou
FROM t_user_follow A
INNER JOIN t_user B
ON A.iuserMe = B.iuser
LEFT JOIN t_user_follow C
ON C.iuserMe = ${iuserMe} -- ๋ก๊ทธ์ธํ ์ฌ๋ pk
AND C.iuserYou = A.iuserMe
WHERE A.iuserYou = ${iuserYou} -- ํ๋กํ ์ฃผ์ธ์ฅ pk
</select>
iuserMe๊ฐ [ ๋ ]์ ์ ์ฅ์์ [ ๋ค๋ฅธ์ฌ๋ ]์ ํ๋ก์ฐ ํ ๊ฒ์ด๋ค.A.iuserMe=B.iuser๋A.iuserYou=${iuserYou}: [๊ทธ์ฌ๋ ๋๋ ๋]๋ฅผ ํ๋ก์ฐํ ์ฌ๋๋ค์ด๋ค.C.iuserMe=${iuserMe}: [ ๋ ]- ์ฆ,
C.iuserMe=${iuserMe}[ ๋ ]์ธ๋ฐ,A.iuserYou=${iuserYou}[ ๊ทธ ์ฌ๋ ๋๋ ๋ ]๋ฅผ ํ๋ก์ฐํ๋A.iuserMe=B.iuser=C.iuserYou๋ฅผ ํ๋ก์ฐํ๋ ์ง ์์๋ณด๋ ๊ฒ์ด๋ค.
๐
profile.js makeFollowItem(item)
item: [ ๊ทธ์ฌ๋ ๋๋ ๋ ]๋ฅผ ํ๋ก์ฐํ๋ ์ฌ๋์iuser, nm, mainprofile,iuserMe([ ๋ด ] ๊ฐ [๊ทธ์ฌ๋ ๋๋ ๋]๋ฅผ ํ๋ก์ฐํ๋ ์ฌ๋์ ํ๋ก์ฐํ๋์ง)
const globalContElem = document.querySelector('#globalConst');
const loginIuser = globalContElem.dataset.iuser;
globalContElem:<span id="globalConst" sec:authorize="isAuthenticated()" th:with="auth=${#authentication.getPrincipal().getUser()}" th:attr="data-iuser=${auth.iuser}, data-writer=${auth.nm}, data-writer-profile=${auth.mainProfile}"></span>loginIuser: [ ๋ ]
const cont = document.createElement('div');
cont.className = 'follow-item';
<div class="follow-item"></div>
const img = document.createElement('img');
img.className = 'profile wh30 pointer';
img.src = `/pic/profile/${item.iuser}/${item.mainProfile}`;
img.onerror = () => { img.style.visibility = 'hidden'; }
img.addEventListener('click', ()=> {
moveToProfile(item.iuser); //feed.js ์ ์๋ ๋ฉ์๋
});
<img class="profile wh30 pointer" src="/pic/profile/${item.iuser}/${item.mainProfile}">
const nm = document.createElement('div');
const nmText = document.createElement('span');
nmText.innerText = item.nm;
nmText.className = 'pointer';
nmText.addEventListener('click', ()=> {
moveToProfile(item.iuser); //feed.js ์ ์๋ ๋ฉ์๋
});
nm.append(nmText);
<div> <span class="pointer" onclick="moveToProfile(item.iuser)">item.nm</span> </div>
const btn = document.createElement('input');
btn.type = 'button';
btn.className = 'instaBtn pointer';
btn.dataset.follow = '0';
btn.addEventListener('click', () => {
const follow = parseInt(btn.dataset.follow);
followProc(follow, item.iuser, btn);
});
<input type="button" class="instaBtn pointer" data-follow="0">
cont.append(img);
cont.append(nm);
<div class="follow-item"> <img class="profile wh30 pointer" src="/pic/profile/${item.iuser}/${item.mainProfile}" onerror="" onclick="moveToProfile(item.iuser)"> <div> <span class="pointer" onclick="moveToProfile(item.iuser)">item.nm</span> </div> </div>
if(parseInt(loginIuser) !== item.iuser) {
if(item.isMeFollowYou) {
btn.classList.add('instaBtnEnable');
btn.dataset.follow = '1';
btn.value = 'ํ๋ก์ฐ ์ทจ์';
} else {
btn.value = 'ํ๋ก์ฐ';
}
cont.append(btn);
}
return cont;
}
if(parseInt(loginIuser) !== item.iuser): [ ๋ ] ์ [ ๋ ๋๋ ๊ทธ์ฌ๋ ]์ ํ๋ก์ฐํ๋ ์ฌ๋์ด ๊ฒน์น๋ค๋ฉด ,
์ฆ, [ ๊ทธ ์ฌ๋ ]์ ํ๋ก์ฐํ๋ ์ฌ๋ ์ค์ [ ๋ด ]๊ฐ ์๋ค๋ฉดํ๋ก์ฐ ๋ฒํผ์ ๋ฃ์ง ์๊ฒ ๋ค.
<div class="follow-item"> <img class="profile wh30 pointer" src="/pic/profile/${item.iuser}/${item.mainProfile}" onerror="" onclick="moveToProfile(item.iuser)"> <div> <span class="pointer" onclick="moveToProfile(item.iuser)">item.nm</span> </div> <input type="button" class="instaBtn pointer" data-follow="0" value="ํ๋ก์ฐ" onclick=" followProc(follow, item.iuser, btn);"> <input type="button" class="instaBtn instaBtnEnable pointer" data-follow="1" value="ํ๋ก์ฐ ์ทจ์" onclick=" followProc(follow, item.iuser, btn);"> </div>
๐
profile.js followerElemArr.forEach(item => { item.addEventListener('click', () => {})});
........
modalFollowTitleElem.innerText = 'ํ๋ก์';
modalFollowElem.classList.remove('hide');
modalFollowItemConElem.innerHTML = '';
........
.then(myJson => {
if(myJson.length > 0) {
myJson.forEach(item => {
const cont = makeFollowItem(item);
modalFollowItemConElem.append(cont);
});
}
๐ ๊ฒฐ๊ณผ
<div class="modal-follow">
<div>
<div class="container">
<div class="top">
<div id="title">ํ๋ก์</div>
<i id="modal-follow-close" class="moodal_clse fas fa-times"></i>
</div>
<div class="followCont">
<div class="follow-item">
<img class="profile wh30 pointer" src="/pic/profile/${item.iuser}/${item.mainProfile}"
onerror="" onclick="moveToProfile(item.iuser)">
<div>
<span class="pointer" onclick="moveToProfile(item.iuser)">item.nm</span>
</div>
<input type="button" class="instaBtn pointer" data-follow="0"
value="ํ๋ก์ฐ" onclick=" followProc(follow, item.iuser, btn);">
<input type="button" class="instaBtn instaBtnEnable pointer" data-follow="1"
value="ํ๋ก์ฐ ์ทจ์" onclick=" followProc(follow, item.iuser, btn);">
</div>
</div>
</div>
</div>
</div>