瀏覽代碼

Merge branch 'dbs333' of http://wcollector.idatabank.com:5230/dbs333/RealWorld into dbs347

Gayeon Park 3 年之前
父節點
當前提交
c088beec54

+ 5 - 4
realworld/src/main/java/com/dbs/realworld/common/Views.java

@@ -1,9 +1,10 @@
 package com.dbs.realworld.common;
 
 public class Views {
-    public static final String MAIN = "main"; // 메인
-    public static final String SIGNUP_FORM = "user/signup"; // 회원가입 폼
-    public static final String SIGNIN_FORM = "user/signin"; // 로그인 폼
-    public static final String ARTICLE_FORM = "article/article"; // 아티클 폼
+    public static final String MAIN = "main";                             // 메인
+    public static final String SIGNUP_FORM = "user/signup";               // 회원가입 폼
+    public static final String SIGNIN_FORM = "user/signin";               // 로그인 폼
+    public static final String USER_SETTING_FORM = "user/settings";       // 세팅 폼
+    public static final String ARTICLE_FORM = "article/article";          // 아티클 폼
     public static final String ARTICLE_DETAIL = "article/articleDetails"; // 아티클 상세
 }

+ 44 - 0
realworld/src/main/java/com/dbs/realworld/controller/UserController.java

@@ -16,6 +16,8 @@ import org.springframework.ui.ModelMap;
 import org.springframework.web.bind.annotation.DeleteMapping;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PatchMapping;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -106,6 +108,7 @@ public class UserController {
         return "redirect:/";
     }
 
+
     // 사용자 팔로우
     @PostMapping("/follow")
     public ResponseEntity follow(HttpServletRequest request, @RequestBody FollowDTO followDTO) {
@@ -117,6 +120,7 @@ public class UserController {
         return ResponseEntity.status(HttpStatus.CREATED).build();
     }
 
+
     // 사용자 언팔로우
     @DeleteMapping("/unfollow")
     public ResponseEntity unfollow(HttpServletRequest request, @RequestBody FollowDTO followDTO) {
@@ -127,4 +131,44 @@ public class UserController {
         this.userService.unfollow(followDTO);
         return ResponseEntity.ok().build();
     }
+
+
+    // 사용자 프로필 페이지
+    @GetMapping("/settings/{userId}")
+    public String initUserSettingForm(HttpServletRequest request, ModelMap model) {
+        String email = (String) request.getSession().getAttribute("ssEmail");
+        UserDTO userDTO = this.userMapper.selectUserByEmail(email);
+        userDTO.setPassword("");
+        model.addAttribute("user", userDTO);
+        return Views.USER_SETTING_FORM;
+    }
+
+
+    // 사용자 프로필 업데이트 API
+    @PatchMapping("/settings/{userId}")
+    public ResponseEntity updateUserSetting(HttpServletRequest request, @PathVariable("userId") int userId, @RequestBody UserDTO userDTO, ModelMap model) {
+        userDTO.setId(userId);
+        
+        /**
+         * 변경하려는 사용자의 이메일이 중복되지는 않는지? 체크해야 함
+         */
+        // UserDTO findedByEmail = this.userMapper.selectUserByEmail(userDTO.getEmail());
+        // if (findedByEmail != null && userId != findedByEmail.getId()) {
+            // 변경하려는 이메일이 이미 있는 경우 처리
+            // TODO 이메일이 중복되었다고 알려줘야 함
+            // return Views.USER_SETTING_FORM;
+        // }
+
+        this.userService.update(userDTO);
+
+        HttpSession session = request.getSession();
+        if (userDTO.getEmail() != null) {
+            session.setAttribute("ssEmail", userDTO.getEmail());
+        }
+        if (userDTO.getUsername() != null) {
+            session.setAttribute("ssUsername", userDTO.getUsername());
+        }
+
+        return ResponseEntity.ok().build();
+    }
 }

+ 5 - 0
realworld/src/main/java/com/dbs/realworld/dto/UserDTO.java

@@ -1,5 +1,7 @@
 package com.dbs.realworld.dto;
 
+import java.time.LocalDateTime;
+
 import lombok.*;
 
 @Data
@@ -10,4 +12,7 @@ public class UserDTO {
     private String username;
     private String email;
     private String password;
+    private String shortBio;
+    private LocalDateTime created;
+    private LocalDateTime updated;
 }

+ 1 - 0
realworld/src/main/java/com/dbs/realworld/mapper/UserMapper.java

@@ -10,6 +10,7 @@ import org.springframework.stereotype.Repository;
 @Mapper
 public interface UserMapper {
     void insertUser(UserDTO dto);
+    void update(UserDTO dto);
     UserDTO selectUserByEmail(String email);
     void insertFollow(FollowDTO dto);
     void deleteFollow(FollowDTO dto);

+ 4 - 0
realworld/src/main/java/com/dbs/realworld/service/UserService.java

@@ -45,4 +45,8 @@ public class UserService {
     public void unfollow(FollowDTO followDTO) {
         this.userMapper.deleteFollow(followDTO);
     }
+
+    public void update(UserDTO userDTO) {
+        this.userMapper.update(userDTO);
+    }
 }

+ 32 - 1
realworld/src/main/resources/mybatis/mapper/user/UserMapper.xml

@@ -11,13 +11,44 @@
         ]]>
     </insert>
 
+    <update id="update" parameterType="UserDTO">
+      <![CDATA[
+          UPDATE	user_mst
+             SET 	update_datetime = NOW()
+      ]]>
+      <if test='username != null and username != ""'>
+        <![CDATA[
+          , name = #{username}
+        ]]>	
+      </if>
+      <if test='email != null and email != ""'>
+        <![CDATA[
+          , email = #{email}
+        ]]>	
+      </if>
+      <if test='password != null and password != ""'>
+        <![CDATA[
+          , pwd = #{password}
+        ]]>	
+      </if>
+      <if test='shortBio != null'>
+        <![CDATA[
+          , short_bio = #{shortBio}
+        ]]>	
+      </if>
+        <![CDATA[
+          WHERE id = #{id}
+        ]]>	
+    </update>
+
     <select id="selectUserByEmail" parameterType="String" resultType="UserDTO">
       <![CDATA[
         SELECT
           id         AS id,
           name       AS username,
           email      AS email,
-          pwd        AS password
+          pwd        AS password,
+          short_bio  AS shortBio
         FROM user_mst
         WHERE
           email = #{email}

+ 3 - 2
realworld/src/main/webapp/WEB-INF/jsp/include/header.jsp

@@ -1,4 +1,5 @@
 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
 
 <nav class = "navbar col-12">
@@ -61,8 +62,8 @@
                 </li>
                 <li class="nav-item">
                     <a
-                        href="/user/settings"
-                        class="link <c:if test="${ssPath eq '/user/settings'}">active</c:if>" 
+                        href="/user/settings/${ssId}"
+                        class="link <c:if test="${fn:contains(ssPath, '/user/settings')}">active</c:if>" 
                     >
                         <i class="fas fa-cog"></i> Settings
                     </a>

+ 69 - 14
realworld/src/main/webapp/WEB-INF/jsp/user/settings.jsp

@@ -8,6 +8,55 @@
 <jsp:include page="/WEB-INF/jsp/include/head.jsp"></jsp:include>
 <script>
 
+let settingForm = null;
+const originalSetting = {};
+
+window.onload = () => {
+    settingForm = window.document.querySelector('#setting-form');
+}
+
+const submitForm = () => {
+    // 밸리데이션 하는 부분 필요
+
+    const json = {};
+
+    // 이름
+    if (settingForm['username'].value !== "${user.username}") {
+        json.username = settingForm['username'].value;
+    }
+
+    // 이메일
+    if (settingForm['email'].value !== "${user.email}") {
+        json.email = settingForm['email'].value;
+    }
+
+    // 비번
+    if (settingForm['password'].value !== "") {
+        json.password = settingForm['password'].value;
+    }
+
+    json.shortBio = settingForm['shortBio'].value;
+    json.id = "${user.id}"
+
+    const options = {
+        body: JSON.stringify(json),
+        method: 'PATCH',
+        headers: {
+            "Content-Type": "application/json"
+        }
+    };
+
+    fetch("/user/settings/${user.id}", options)
+        .then(response => {
+            if (response.status === 200) {
+                location.href = '/user/settings/${user.id}'
+            }
+        })
+}
+
+
+
+
 </script>
 </head>
 <body>
@@ -21,31 +70,35 @@
                     name="settingForm"
                     id="setting-form"
                     class="form-group"
-                    method="post"
-                    action="/user/settings">
-                    <div class="form-data">
+                    onsubmit="return false"
+                >
+                    <!-- method="post"
+                    action="/user/settings" -->
+
+                    <!-- <div class="form-data">
                         <input 
-                            type="text" 
+                            type="file" 
                             class="form-control form-control-sm" 
                             placeholder ="URL of profile picture" 
                             autocomplete="off"
-                            value="<c:out value='${profileImg}'/>">
-                    </div>
+                            value="${profileImg}">
+                    </div> -->
                     <div class="form-data">
                         <input 
                             type="text" 
                             class="form-control" 
                             placeholder ="Username" 
                             autocomplete="off"
-                            value="<c:out value='${username}'/>">
+                            name="username"
+                            value="${user.username}">
                     </div>
                     <div class="form-data">
                         <textarea 
                             class="form-control" 
                             rows="8" 
-                            name="article-body" 
+                            name="shortBio" 
                             placeholder="Short bio about you"
-                            value="<c:out value='${userBio}'/>"></textarea>
+                        >${user.shortBio}</textarea>
                     </div>
                     <div class="form-data">
                         <input 
@@ -53,16 +106,18 @@
                             class="form-control" 
                             placeholder ="Email" 
                             autocomplete="off"
-                            value="<c:out value='${email}'/>">
+                            name="email"
+                            value="${user.email}">
                     </div>
                     <div class="form-data">
                         <input 
-                            type="password" 
-                            class="form-control" 
-                            placeholder="New Password" 
+                            type="password"
+                            class="form-control"
+                            placeholder="New Password"
+                            name="password"
                             autocomplete="off">
                     </div>
-                    <button class="btn-settings">Update Settings</button>
+                    <button class="btn-settings" onclick="submitForm()">Update Settings</button>
                 </div>
                 <hr>
                 <button type="button" class="btn-logout" onclick="location.href='/'">Or click here to logout.</button>