From fb5e66ac909e326896b5f36e9393907dc613dfb1 Mon Sep 17 00:00:00 2001 From: HYESOO KIM Date: Thu, 28 Dec 2023 16:38:13 +0900 Subject: [PATCH 1/2] =?UTF-8?q?[FEAT=20#87=20]=20Feign=20=EC=A0=84?= =?UTF-8?q?=EB=8B=AC=20=EA=B0=9D=EC=B2=B4=20=EC=A0=95=ED=98=95=EC=84=B1=20?= =?UTF-8?q?=EA=B5=90=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../farmted/auctionservice/vo/ProductVo.java | 10 ++- front-service/src/App.tsx | 3 +- .../bidding/biddingList/BiddingList.tsx | 84 +++++++++++++------ .../board/boardRoute/BoardRouteController.tsx | 2 + .../components/user/authentication/index.tsx | 2 +- .../controller/ProductController.java | 2 +- .../vo/ResponseAuctionGetVo.java | 12 +-- 7 files changed, 77 insertions(+), 38 deletions(-) diff --git a/auction-service/src/main/java/com/farmted/auctionservice/vo/ProductVo.java b/auction-service/src/main/java/com/farmted/auctionservice/vo/ProductVo.java index 38fa7b7b..8e4bfaa7 100644 --- a/auction-service/src/main/java/com/farmted/auctionservice/vo/ProductVo.java +++ b/auction-service/src/main/java/com/farmted/auctionservice/vo/ProductVo.java @@ -1,8 +1,10 @@ package com.farmted.auctionservice.vo; +import com.fasterxml.jackson.annotation.JsonProperty; + public record ProductVo( - String name, - int stock, - String source, - String image + @JsonProperty("name") String name, + @JsonProperty("stock") int stock, + @JsonProperty("source") String source, + @JsonProperty("image") String image ){} diff --git a/front-service/src/App.tsx b/front-service/src/App.tsx index dc518ae5..5758d093 100644 --- a/front-service/src/App.tsx +++ b/front-service/src/App.tsx @@ -15,8 +15,7 @@ const GlobalStyle = createGlobalStyle` const App = () => ( - - {/*
*/} +
); diff --git a/front-service/src/components/bidding/biddingList/BiddingList.tsx b/front-service/src/components/bidding/biddingList/BiddingList.tsx index 5c107830..a1534773 100644 --- a/front-service/src/components/bidding/biddingList/BiddingList.tsx +++ b/front-service/src/components/bidding/biddingList/BiddingList.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react'; -import { useParams } from 'react-router-dom'; +import styled from 'styled-components'; interface BiddingResponseDto { biddingPrice: number; @@ -11,29 +11,51 @@ interface BiddingResponseDto { image: string; } +const AuctionDetailContainer = styled.div` + margin-top: 16px; +`; + +const AuctionDetailTable = styled.table` + width: 100%; + margin-bottom: 16px; +`; + +const AuctionDetailRow = styled.tr` + display: flex; + justify-content: space-between; +`; + +const AuctionDetailTitle = styled.th` + font-size: 18px; + margin-bottom: 8px; + text-align: left; +`; + +const AuctionDetailContent = styled.td` + font-size: 16px; + margin-bottom: 8px; + text-align: right; +`; + const BiddingList = () => { const [biddingList, setBiddingList] = useState([]); - // const { memberUuid } = useParams<{ memberUuid: string }>(); const memberUuid = '6036e646-97d3-4e53-aee4-f88e00b57a4b'; useEffect(() => { - let isMounted = true; // Flag to check if the component is mounted - - + let isMounted = true; const fetchBiddingList = async () => { - try { const response = await fetch(`/api/auction-service/bidding-service/${memberUuid}/bidding`); - + if (!response.ok) { const errorText = await response.text(); console.error('입찰 목록을 가져오는 데 실패했습니다:', errorText); throw new Error('입찰 목록을 가져오는 데 실패했습니다'); } - + const data = await response.json(); - + if (isMounted) { console.log('Data:', data); setBiddingList(data); @@ -45,34 +67,46 @@ const BiddingList = () => { fetchBiddingList(); - // Cleanup function to set isMounted to false when component is unmounted return () => { isMounted = false; }; }, [memberUuid]); return ( -
+

입찰 목록입니다

회원 {memberUuid}의 입찰 목록

{biddingList.length > 0 ? ( -
    - {biddingList.map((biddingItem, index) => ( -
  • -

    입찰 가격: {biddingItem.biddingPrice}

    -

    입찰 시간: {biddingItem.biddingTime}

    -

    회원 UUID: {biddingItem.memberUuid}

    -

    이름: {biddingItem.name}

    -

    재고: {biddingItem.stock}

    -

    출처: {biddingItem.source}

    - {`${biddingItem.name}에 -
  • - ))} -
+ + + + 입찰 가격 + 입찰 시간 + 이름 + 재고 + 출처 + 이미지 + + + + {biddingList.map((biddingItem, index) => ( + + {biddingItem.biddingPrice} + {biddingItem.biddingTime} + {biddingItem.name} + {biddingItem.stock} + {biddingItem.source} + + {`${biddingItem.name}에 + + + ))} + + ) : (

입찰 목록이 없습니다.

)} -
+ ); }; diff --git a/front-service/src/components/board/boardRoute/BoardRouteController.tsx b/front-service/src/components/board/boardRoute/BoardRouteController.tsx index 487f2774..8f1eee68 100644 --- a/front-service/src/components/board/boardRoute/BoardRouteController.tsx +++ b/front-service/src/components/board/boardRoute/BoardRouteController.tsx @@ -5,6 +5,7 @@ import BoardBody from "../BoardBody" import CreateBoard from "../createBoard/CreateBoard" import BoardDetail from "../boardDetail/BoardDetail" import Authentication from "../../user/authentication"; +import BiddingList from "../../bidding/biddingList/BiddingList" const BoardRouteController = () => { return( @@ -15,6 +16,7 @@ const BoardRouteController = () => { }> } /> + }/> } /> }/> }/> diff --git a/front-service/src/components/user/authentication/index.tsx b/front-service/src/components/user/authentication/index.tsx index 9f41dcb7..49a0ce3e 100644 --- a/front-service/src/components/user/authentication/index.tsx +++ b/front-service/src/components/user/authentication/index.tsx @@ -81,7 +81,7 @@ export default function Authentication() { body: JSON.stringify(requestBody), } ).then( - ()=>{ navigator("/boards");} + ()=>{ navigator("/bidding");} ); }; diff --git a/product-service/src/main/java/com/farmted/productservice/controller/ProductController.java b/product-service/src/main/java/com/farmted/productservice/controller/ProductController.java index 72a5b839..82260c66 100644 --- a/product-service/src/main/java/com/farmted/productservice/controller/ProductController.java +++ b/product-service/src/main/java/com/farmted/productservice/controller/ProductController.java @@ -124,7 +124,7 @@ public ResponseEntity closedAuctionFromProduct(@PathVariable String productUu @Operation(summary = "상품 세부 내역 조회") public ResponseEntity getProductDetail(@PathVariable (value = "board_uuid") String boardUuid){ ProductResponseDto productDetail = productService.getProductDetail(boardUuid); - return ResponseEntity.ok(GlobalResponseDto.of(productDetail)); + return ResponseEntity.ok(productDetail); } } diff --git a/product-service/src/main/java/com/farmted/productservice/vo/ResponseAuctionGetVo.java b/product-service/src/main/java/com/farmted/productservice/vo/ResponseAuctionGetVo.java index 6cb9499f..e5b14057 100644 --- a/product-service/src/main/java/com/farmted/productservice/vo/ResponseAuctionGetVo.java +++ b/product-service/src/main/java/com/farmted/productservice/vo/ResponseAuctionGetVo.java @@ -1,11 +1,13 @@ package com.farmted.productservice.vo; +import com.fasterxml.jackson.annotation.JsonProperty; + import java.time.LocalDateTime; public record ResponseAuctionGetVo ( - Integer auctionPrice, // 경매 가격 == 낙찰 가격 - LocalDateTime auctionDeadline, // 경매 종료 - String productUuid, - String auctionBuyer, // 낙찰자 - boolean auctionStatus){ } + @JsonProperty("auctionPrice") Integer auctionPrice, // 경매 가격 == 낙찰 가격 + @JsonProperty("auctionDeadline") LocalDateTime auctionDeadline, // 경매 종료 + @JsonProperty("productUuid") String productUuid, + @JsonProperty("auctionBuyer") String auctionBuyer, // 낙찰자 + @JsonProperty("auctionStatus") boolean auctionStatus){ } From 4fbed9e62446edbd5f24d2b8c423a0bc871e4599 Mon Sep 17 00:00:00 2001 From: HYESOO KIM Date: Thu, 28 Dec 2023 18:40:22 +0900 Subject: [PATCH 2/2] =?UTF-8?q?[FEAT=20#87=20]=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EC=9E=85=EC=B0=B0=20=EC=8B=A0=EC=B2=AD=20=EC=8B=9C=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BiddingResponseDto.java | 2 + .../bidding/biddingList/BiddingList.tsx | 82 ++++++++++++------ .../biddingList/BiddingModalComponent.tsx | 85 +++++++++++++++++++ 3 files changed, 143 insertions(+), 26 deletions(-) create mode 100644 front-service/src/components/bidding/biddingList/BiddingModalComponent.tsx diff --git a/auction-service/src/main/java/com/farmted/auctionservice/dto/ResponseBiddingDto/BiddingResponseDto.java b/auction-service/src/main/java/com/farmted/auctionservice/dto/ResponseBiddingDto/BiddingResponseDto.java index 00e3bf37..3d55c0f6 100644 --- a/auction-service/src/main/java/com/farmted/auctionservice/dto/ResponseBiddingDto/BiddingResponseDto.java +++ b/auction-service/src/main/java/com/farmted/auctionservice/dto/ResponseBiddingDto/BiddingResponseDto.java @@ -18,6 +18,7 @@ public class BiddingResponseDto { private int stock; private String source; private String image; + private String boardUuid; public BiddingResponseDto(Bidding bidding, ProductVo productVo){ biddingPrice = bidding.getBiddingPrice(); @@ -27,5 +28,6 @@ public BiddingResponseDto(Bidding bidding, ProductVo productVo){ stock = productVo.stock(); source=productVo.source(); image = productVo.image(); + boardUuid = bidding.getBoardUuid(); } } diff --git a/front-service/src/components/bidding/biddingList/BiddingList.tsx b/front-service/src/components/bidding/biddingList/BiddingList.tsx index a1534773..f4dd7a40 100644 --- a/front-service/src/components/bidding/biddingList/BiddingList.tsx +++ b/front-service/src/components/bidding/biddingList/BiddingList.tsx @@ -1,5 +1,9 @@ +// BiddingList.tsx + import React, { useEffect, useState } from 'react'; import styled from 'styled-components'; +import BiddingModalComponent from './BiddingModalComponent'; + interface BiddingResponseDto { biddingPrice: number; @@ -9,6 +13,7 @@ interface BiddingResponseDto { stock: number; source: string; image: string; + boardUuid: string; // boardUuid를 추가 } const AuctionDetailContainer = styled.div` @@ -18,27 +23,34 @@ const AuctionDetailContainer = styled.div` const AuctionDetailTable = styled.table` width: 100%; margin-bottom: 16px; + border-collapse: collapse; `; const AuctionDetailRow = styled.tr` display: flex; justify-content: space-between; + border-bottom: 1px solid #d6d6d6; + cursor: pointer; `; const AuctionDetailTitle = styled.th` font-size: 18px; margin-bottom: 8px; text-align: left; + padding: 10px; `; const AuctionDetailContent = styled.td` font-size: 16px; margin-bottom: 8px; text-align: right; + padding: 10px; `; const BiddingList = () => { const [biddingList, setBiddingList] = useState([]); + const [selectedBiddingItem, setSelectedBiddingItem] = useState(null); + const [isModalOpen, setIsModalOpen] = useState(false); const memberUuid = '6036e646-97d3-4e53-aee4-f88e00b57a4b'; useEffect(() => { @@ -72,37 +84,55 @@ const BiddingList = () => { }; }, [memberUuid]); + const handleRowClick = (biddingItem: BiddingResponseDto) => { + setSelectedBiddingItem(biddingItem); + setIsModalOpen(true); + }; + return (

입찰 목록입니다

-

회원 {memberUuid}의 입찰 목록

+

사용자님의 입찰 목록

{biddingList.length > 0 ? ( - - - - 입찰 가격 - 입찰 시간 - 이름 - 재고 - 출처 - 이미지 - - - - {biddingList.map((biddingItem, index) => ( - - {biddingItem.biddingPrice} - {biddingItem.biddingTime} - {biddingItem.name} - {biddingItem.stock} - {biddingItem.source} - - {`${biddingItem.name}에 - + <> + + + + 입찰 가격 + 입찰 시간 + 이름 + 재고 + 판매처 + 이미지 - ))} - - + + + {biddingList.map((biddingItem, index) => ( + handleRowClick(biddingItem)}> + {biddingItem.biddingPrice} + {biddingItem.biddingTime} + {biddingItem.name} + {biddingItem.stock} + {biddingItem.source} + + {`${biddingItem.name}에 + + + ))} + + + + {/* 모달 컴포넌트 */} + {isModalOpen && selectedBiddingItem && ( + setIsModalOpen(false)} + isOpen={isModalOpen} + closeModal={() => setIsModalOpen(false)} + modalContent={`${selectedBiddingItem.biddingPrice}`} /> + )} + ) : (

입찰 목록이 없습니다.

)} diff --git a/front-service/src/components/bidding/biddingList/BiddingModalComponent.tsx b/front-service/src/components/bidding/biddingList/BiddingModalComponent.tsx new file mode 100644 index 00000000..59cc1059 --- /dev/null +++ b/front-service/src/components/bidding/biddingList/BiddingModalComponent.tsx @@ -0,0 +1,85 @@ +// BiddingModal.tsx + +import React, { useState } from 'react'; +import styled from 'styled-components'; + +interface BiddingModalProps { + boardUuid: string; + memberUuid: string; + onClose: () => void; + isOpen: boolean; + closeModal: () => void; + modalContent: string; +} + +const ModalWrapper = styled.div` + border: 2px solid #007bff; + padding: 20px; + background-color: #fff; + width: 600px; + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +`; + +const BiddingModal: React.FC = ({ boardUuid, memberUuid, onClose, isOpen, closeModal, modalContent }) => { + const [newBiddingPrice, setNewBiddingPrice] = useState(); + const [memberPrice, setMemberPrice] = useState(10000); + const [biddingAutoPrice, setBiddingAutoPrice] = useState(null); + const [warningMessage, setWarningMessage] = useState(null); + + const handleBiddingSubmit = async () => { + if (newBiddingPrice && newBiddingPrice > memberPrice) { + setWarningMessage('입찰 가격이 회원 가격보다 큽니다. 다시 입력해주세요.'); + return; + } + + try { + const response = await fetch(`/api/auction-service/bidding-service/bid/${boardUuid}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'UUID': memberUuid, + }, + body: JSON.stringify({ + biddingPrice: newBiddingPrice, + memberPrice, + biddingAutoPrice, + }), + }); + + if (response.ok) { + // 성공적으로 입찰이 이루어졌을 때 모달을 닫습니다. + onClose(); + } else { + // 에러 처리 로직을 추가하세요. + console.error('입찰 실패:', response); + } + } catch (error) { + // 네트워크 오류 또는 기타 예외 처리 로직을 추가하세요. + console.error('네트워크 오류'); + } + }; + + return ( + + {/* 모달 내용 및 폼 */} + + setNewBiddingPrice(+e.target.value)} /> + + {/* 다른 입력 필드 및 버튼들은 이곳에 추가하세요. */} + + {warningMessage &&
{warningMessage}
} + + + + + {/* modalContent 표시 */} +
이전 낙찰 내역:{modalContent}
+
현재 잔고: {memberPrice}
+
+ ); +}; + +export default BiddingModal;