본문 바로가기
Develop/React

붕어빵 프로젝트 업데이트 v0.2

by ys2ys2 2024. 12. 18.

 

🎯v0.2 업데이트 내용  

 

 

💡마커 로고 업데이트  

 

✅ 지도에 더 많은 로고가 업데이트되었습니다. 군고구마, 호떡 등이 추가되었습니다.

 

 

💡정보 저장 시 구분값 추가  

 

✅ 어떤 간식이 메인인지 마커로 구별할 수 있게 각 가게마다 gubun 값을 추가했습니다.

 

✅ 간식 가게 정보 저장 시 구분값을 선택할 수 있게 하였습니다.

 

 

💡지번 주소 업데이트 

✅ 현재 위치에서 도로명 주소가 없을 시 지번주소로 대체해서 저장할 수 있게 수정했습니다.

 

 

 

 


 

 

 

 

📒업데이트 공부하기

 

✏️gubun 컬럼 추가

 

가게 정보 수집하려고 돌아다니면서 느낀건 붕어빵 말고도 호떡이나 군고구마 등 여러가지를 파는 가게들도 많이 보였다.

이런 가게들도 따로 구분으로 분류하고 구분값에 따라 지도 마커 로고를 다르게 설정하면 사용자들이 더 편하게 볼 수 있을것 같아서 수정했다.

 

 

Entity

Int 형식의 gubun값을 추가해줬다. 1 = 붕어빵, 2 = 군고구마, 3 = 호떡 으로 사용할 예정

@Column(nullable = false)
private Integer gubun; //1: 붕어빵, 2: 군고구마, 3: 호떡, 4: 기타

 

 

 

Controller

@PostMapping
public ResponseEntity<FishstoreEntity> saveFishstore(
        @RequestParam("storeName") String storeName,
        @RequestParam("gubun") Integer gubun, //구분값 추가
        @RequestParam("storeAddress") String storeAddress,
        @RequestParam("storeX") Double storeX,
        @RequestParam("storeY") Double storeY,
        @RequestParam(value = "storeMenu", required = false) String storeMenu,
        @RequestParam(value = "storeInfo", required = false) String storeInfo,
        @RequestParam(value = "storeImage", required = false) MultipartFile storeImage) {

    FishstoreEntity savedFishstore = service.saveFishstore(storeName, gubun, storeAddress, storeX, storeY, storeMenu, storeInfo, storeImage);
    return ResponseEntity.ok(savedFishstore);
}

 

 

Service, ServiceImpl

FishstoreEntity saveFishstore(String storeName, Integer gubun, String storeAdress, Double storeX, Double storeY, String storeMenu, String storeInfo, MultipartFile storeImage);
@Override
public FishstoreEntity saveFishstore(String storeName, Integer gubun, String storeAddress, Double storeX, Double storeY, String storeMenu, String storeInfo, MultipartFile storeImage) {
    byte[] imageBytes = null;

    try {
        // MultipartFile을 byte[]로 변환
        if (storeImage != null && !storeImage.isEmpty()) {
            imageBytes = storeImage.getBytes();
        }
    } catch (Exception e) {
        throw new RuntimeException("이미지 변환 중 오류 발생: " + e.getMessage());
    }

    FishstoreEntity fishstore = new FishstoreEntity();
    fishstore.setStoreName(storeName);
    fishstore.setGubun(gubun); //구분 추가
    fishstore.setStoreAddress(storeAddress);
    fishstore.setStoreX(storeX);
    fishstore.setStoreY(storeY);
    fishstore.setStoreMenu(storeMenu);
    fishstore.setStoreInfo(storeInfo);
    fishstore.setStoreImage(imageBytes);

    return repository.save(fishstore);
}

 


 

✏️ 프론트 드롭다운 리스트 추가

 

formData에 gubun값 추가

const [formData, setFormData] = useState({
    storeName: "",
    storeAddress: "",
    gubun: "1", //기본값: 붕어빵 (1) // 군고구마(2), 호떡(3)
    storeX: "",
    storeY: "",
    storeMenu: "",
    storeImage: null,
    storeInfo: "",
  });

 

입력 폼에 구분 label 추가

<label>
    <span>구분</span>
    <select
      name="gubun"
      value={formData.gubun}
      onChange={handleChange}
      className="dropdown"
    >
      <option value="1">붕어빵</option>
      <option value="2">군고구마</option>
      <option value="3">호떡</option>
      <option value="4">기타</option>
    </select>
</label>

 

지도에 구분값에 따른 마커 추가

  const addStoreMarkers = (fishstores, map) => {
    markersRef.current.forEach(marker => marker.setMap(null));
    markersRef.current = [];
  
    fishstores.forEach((store, index) => {
      const markerPosition = new window.kakao.maps.LatLng(store.storeX, store.storeY);

      let imageSrc;
      if (store.gubun === 1) {
        imageSrc = "public/images/markerlogo.png"; // 붕어빵(1)
      } else if (store.gubun === 2) {
        imageSrc = "public/images/goguma.png"; // 군고구마(2)
      } else {
        imageSrc = "public/images/hodduk.png"; // 호떡(3)
      }
      const imageSize = new window.kakao.maps.Size(40, 40);
      const markerImage = new window.kakao.maps.MarkerImage(imageSrc, imageSize);
  
      const marker = new window.kakao.maps.Marker({
        position: markerPosition,
        map: map,
        image: markerImage,
        zIndex: 30,
      });

 

 


 

 

✏️ 도로명주소 + 지번주소로 수정

 

실시간으로 현재 위치를 제공하지만 정확한 좌표가 아니면 도로명 주소가 나오지 않는 문제점이 있었다.

카카오 지도의 coord2Address는 도로명 주소가 없으면 지번주소를 제공하고 있었는데 그걸 받기만 하고 사용하지 않고 있었다...

도로명 주소가 없으면 지번 주소인 jibunAddress값을 사용하고, 최종적으로 finalAddress로 저장되게 했다.

서버에 저장 요청을 할 때는 storeAddress: finalAddress를 통해 formData에 담아 가게 주소를 저장하게 했다.

 

입력 폼에서는 setAddress(finalAddress)를 통해 useState로 정의된 address에 상태를 전달해서 finalAddress가 address로 상태가 바뀌고 입력 폼에서 address값으로 사용자에게 제공되게 했다.

 useEffect(() => {
    if (currentPosition.lat && currentPosition.lng) {
      setFormData((prevState) => ({
        ...prevState,
        storeX: currentPosition.lat.toFixed(6),
        storeY: currentPosition.lng.toFixed(6),
      }));
  
      // Kakao Maps Geocoder
      if (window.kakao && window.kakao.maps) {
        const geocoder = new window.kakao.maps.services.Geocoder();
        geocoder.coord2Address(
          currentPosition.lng,
          currentPosition.lat,
          (result, status) => {
            if (status === window.kakao.maps.services.Status.OK) {
              const roadAddress = result[0]?.road_address?.address_name; // 도로명 주소
              const jibunAddress = result[0]?.address?.address_name;     // 지번 주소
  
              // 도로명 주소가 없으면 지번 주소 사용
              const finalAddress = roadAddress || jibunAddress || "주소 없음";
  
              setAddress(finalAddress);
              setFormData((prevState) => ({
                ...prevState,
                storeAddress: finalAddress, // formData에 최종 주소 추가
              }));
            } else {
              console.error("주소 변환 실패");
            }
          }
        );
      }
    }
  }, [currentPosition]);
<label>
    <span>주소</span>
    <input
      type="text"
      value={address} // 도로명 or 지번
      readOnly
      placeholder="주소 가져오는 중..."
    />
</label>