project/모임웹프로젝트

모임 웹 프로젝트 회원가입 코드수정 (5)

naspeciallist 2024. 9. 29. 00:20

프런트를 구성하고 나니 수정해야 할 부분이 3가지가 보였습니다.

 

첫번째로는 프로필사진 저장 관련 로직입니다.

프로필사진 저장 로직은 백엔드를 구성하기 전에 file에 관한 모듈을 만들어 프로필사진에 저장과 불러오기에 대한 기능을 처리 할려고 합니다.

두번째는 주소도 받아야 하는데 주소 받는 걸 빼먹었습니다. 상세주소를 받을 수 있는 api를 통해 주소를 받는 로직을 추가하겠습니다.

 

세번째는 계정 활성화 비활성화 로직입니다. 계정 활성화 비활성화 여부를 설정해서 회원가입 요청이 들어왔을 때 일단 비활성화 처리를 한 뒤 운영진의 심사를 통해서 계정을 활성화 시킬 예정입니다.

 

첫번째로 파일을 저장하고 불러올 수 있는 모듈을 만들어 보겠습니다.

package org.zerock.wantuproject.controller;

import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Controller
public class FileController {

    private final Path rootLocation = Paths.get("uploads"); // 파일이 저장될 로컬 경로

    // 생성자에서 폴더 생성
    public FileController() throws IOException {
        Files.createDirectories(rootLocation);
    }

    // 여러 개의 파일 업로드 처리
    @PostMapping("/uploadMultiple")
    public ResponseEntity<List<String>> handleMultipleFileUpload(@RequestParam("files") MultipartFile[] files) {
        List<String> uploadedFileNames = new ArrayList<>();

        for (MultipartFile file : files) {
            try {
                String savedFileName = saveFile(file); // 파일 저장
                uploadedFileNames.add(savedFileName);  // 저장된 파일 이름 추가
            } catch (IOException e) {
                return ResponseEntity.badRequest().body(null);
            }
        }
        return ResponseEntity.ok(uploadedFileNames); // 저장된 파일들의 이름 반환
    }

    // 파일 저장 메서드
    private String saveFile(MultipartFile file) throws IOException {
        String fileName = UUID.randomUUID().toString() + "_" + file.getOriginalFilename(); // 고유한 파일 이름 생성
        Files.copy(file.getInputStream(), rootLocation.resolve(fileName)); // 파일 저장
        return fileName; // 저장된 파일 이름 반환
    }

    // 파일 불러오기 처리
    @GetMapping("/files")
    public ResponseEntity<Resource> serveFile(@RequestParam String fileName) {
        try {
            Path file = rootLocation.resolve(fileName);
            Resource resource = new UrlResource(file.toUri());

            if (resource.exists() || resource.isReadable()) {
                return ResponseEntity.ok()
                        .header(HttpHeaders.CONTENT_TYPE, "image/jpeg") // MIME 타입을 이미지로 설정
                        .body(resource); // 파일 반환
            } else {
                return ResponseEntity.badRequest().body(null);
            }
        } catch (MalformedURLException e) {
            return ResponseEntity.badRequest().body(null);
        }
    }
}

프로필 사진을 여러개를 추가해야 하기 때문에 파일을 배열 형식으로 받고 그걸 처리 할 수 있는 로직입니다.

파일의 이름을 고유한 파일이름으로 만들어 저장한 뒤 다시 반환 할 수 있도록 설정을 하였습니다.

 

두번째는 주소를 받을 수 있는 로직입니다.
상세주소는 받지 않고 카카오 api를 통해서 대략적인 주소만 받을 수 있도록 처리를 해보겠습니다.
먼저 user엔티티에 주소 컬럼을 추가를 해줍니다.

@Column
private String address;

@Builder
    public User(String name, String email,String password, String nickname,LocalDate birthDate, String gender, String introduce, String roleUser,String uid, String address) {
        this.uid = uid;
        this.name = name;
        this.email = email;
        this.password = password;
        this.nickname = nickname;
        this.birthDate =  birthDate;
        this.gender = gender;
        this.introduce = introduce;
        this.role = roleUser;
        this.address = address;
    }


빌더 객체에도 추가를 해준뒤 dto에도 추가를 해줍니다.

@Getter
@Setter
public class AddUserRequest {
    private String email;
    private String uid;
    private String password;
    private String nickname;
    private String name;
    private String gender;
    private String indroduce;
    private LocalDate birthDate;
    private List<String> interests;
    private List<MultipartFile> profileImages;
    private String address;
}

 

그 뒤에 signup폼에 api를 추가를 해줍니다.

<script>
    // 카카오 API 초기화 (JavaScript 키를 넣어주세요)
    Kakao.init('YOUR_JAVASCRIPT_KEY');
  </script>
  <style>
    /* 추가된 주소 입력 스타일 */
    .form-group {
      margin-bottom: 20px;
    }
    #address {
      width: 500px;
      padding: 10px;
      border: 1px solid black;
      border-radius: 15px;
    }
    .address-button {
      margin-left: 10px;
      padding: 8px 15px;
      background-color: #ff6b6b;
      color: white;
      border: none;
      border-radius: 15px;
      cursor: pointer;
    }
  </style>
</head>
<body>
<h1>계정 만들기</h1>

<form action="/user" method="POST" enctype="multipart/form-data">
  <!-- 기타 기존 폼 코드들 -->

  <div class="form-group">
    <label for="address">주소</label>
    <input type="text" id="address" name="address" required readonly>
    <button type="button" class="address-button" onclick="execDaumPostcode()">주소 검색</button>
  </div>

  <!-- 기타 기존 폼 코드들 -->
  <button type="submit" class="submit-btn">회원가입하기</button>
</form>

<script>
  // 주소 검색 API를 호출하는 함수
  function execDaumPostcode() {
    new daum.Postcode({
      oncomplete: function(data) {
        // 선택한 주소 정보를 가져와서 해당 인풋에 삽입
        document.getElementById('address').value = data.address;
      }
    }).open();
  }

  // 카카오 주소 검색 API 스크립트 로드
  var script = document.createElement('script');
  script.src = 'https://t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js';
  document.body.appendChild(script);
</script>

 

그러면

 

이렇게 api를 통해 주소를 받아 올 수 있는 걸 확인 할 수 있습니다.

 

계정 활성화 비활성화 로직은 백엔드 로직을 구성 한 뒤 추가를 하겠습니다.