diff --git a/scratch_user.http b/scratch_user.http index 07b0810..d1ca49d 100644 --- a/scratch_user.http +++ b/scratch_user.http @@ -1,4 +1,4 @@ -### 회원 가입 ( 유저 ) +### 회원 가입 ( 유저1 ) POST http://localhost:8080/sign-up/user Content-Type: application/json @@ -11,7 +11,21 @@ Content-Type: application/json "userId": "user" } -### 로그인 ( 유저 ) + +### 회원 가입 ( 유저2 ) +POST http://localhost:8080/sign-up/user +Content-Type: application/json + +{ + "email": "second@naver.com", + "name": "name", + "nickName": "nickname", + "password": 1, + "phone": "010-8888-8888", + "userId": "second" +} + +### 로그인 ( 유저1 ) POST http://localhost:8080/sign-in/user Content-Type: application/json @@ -20,15 +34,24 @@ Content-Type: application/json "userId": "user" } +### 로그인 ( 유저2 ) +POST http://localhost:8080/sign-in/user +Content-Type: application/json + +{ + "password": 1, + "userId": "second" +} + ### 회원 정보 조회 ( 유저 ) GET http://localhost:8080/user/get-info Content-Type: application/json -X-AUTH-TOKEN: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkNFdqdHRxUzZteHEzYmF5Qm1paldBPT0iLCJqdGkiOiJDbVlEdjVNSzVZVXlpazhLR05Ed293PT0iLCJyb2xlcyI6IkNVU1RPTUVSIiwiaWF0IjoxNjg0NzgwODc4LCJleHAiOjE2ODQ4NjcyNzh9.RRmPsfyOTOaNAhDmj46My2N4g5hRB8iM8c3ynxPCJoQ +X-AUTH-TOKEN: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkNFdqdHRxUzZteHEzYmF5Qm1paldBPT0iLCJqdGkiOiJDbVlEdjVNSzVZVXlpazhLR05Ed293PT0iLCJyb2xlcyI6IkNVU1RPTUVSIiwiaWF0IjoxNjg1ODg3MTU1LCJleHAiOjE2ODU5NzM1NTV9.-1tGp4hFzX6WCEEhv-mC2QCeCXcozaK56rGj0Grw5Bg ### 잔액 변경 ( 유저 ) POST http://localhost:8080/user/balance Content-Type: application/json -X-AUTH-TOKEN: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkNFdqdHRxUzZteHEzYmF5Qm1paldBPT0iLCJqdGkiOiJDbVlEdjVNSzVZVXlpazhLR05Ed293PT0iLCJyb2xlcyI6IkNVU1RPTUVSIiwiaWF0IjoxNjg0NzgwMTA4LCJleHAiOjE2ODQ4NjY1MDh9.Hxl9-D34o91lcmQC40lbbQrghovwkp_24-EU6Sf78yQ +X-AUTH-TOKEN: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkNFdqdHRxUzZteHEzYmF5Qm1paldBPT0iLCJqdGkiOiJDbVlEdjVNSzVZVXlpazhLR05Ed293PT0iLCJyb2xlcyI6IkNVU1RPTUVSIiwiaWF0IjoxNjg1ODg3MTU1LCJleHAiOjE2ODU5NzM1NTV9.-1tGp4hFzX6WCEEhv-mC2QCeCXcozaK56rGj0Grw5Bg { "from": "admin", @@ -36,20 +59,88 @@ X-AUTH-TOKEN: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkNFdqdHRxUzZteHEzYmF5Qm1paldBPT0iL "money": 1000 } +### 회원 정보수정 (유저) +PUT http://localhost:8080/user/ +Content-Type: application/json +X-AUTH-TOKEN: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkNFdqdHRxUzZteHEzYmF5Qm1paldBPT0iLCJqdGkiOiJDbVlEdjVNSzVZVXlpazhLR05Ed293PT0iLCJyb2xlcyI6IkNVU1RPTUVSIiwiaWF0IjoxNjg1ODg3MTU1LCJleHAiOjE2ODU5NzM1NTV9.-1tGp4hFzX6WCEEhv-mC2QCeCXcozaK56rGj0Grw5Bg + +{ + "email": "string", + "name": "string", + "nickName": "string", + "password": "string", + "phone": "string", + "profile": "string" +} + + + +### 회원 삭제 ( 유저 ) +DELETE http://localhost:8080/user/ +Content-Type: application/json +X-AUTH-TOKEN: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkNFdqdHRxUzZteHEzYmF5Qm1paldBPT0iLCJqdGkiOiJDbVlEdjVNSzVZVXlpazhLR05Ed293PT0iLCJyb2xlcyI6IkNVU1RPTUVSIiwiaWF0IjoxNjg1ODkwMDIyLCJleHAiOjE2ODU5NzY0MjJ9.XYJETzVqfSAEy1lo_FGunAF7pzrJMnByo19cTcy94Z4 + ### 역옥션 등록( 유저 ) POST http://localhost:8080/auction Content-Type: application/json -X-AUTH-TOKEN:eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkNFdqdHRxUzZteHEzYmF5Qm1paldBPT0iLCJqdGkiOiJDbVlEdjVNSzVZVXlpazhLR05Ed293PT0iLCJyb2xlcyI6IkNVU1RPTUVSIiwiaWF0IjoxNjg0OTU3MTE5LCJleHAiOjE2ODUwNDM1MTl9.jWJ4Qi0W3HKnlw5kLRyjFQLekuC98aVNCdbAiaO0Imc +X-AUTH-TOKEN: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkNFdqdHRxUzZteHEzYmF5Qm1paldBPT0iLCJqdGkiOiJDbVlEdjVNSzVZVXlpazhLR05Ed293PT0iLCJyb2xlcyI6IkNVU1RPTUVSIiwiaWF0IjoxNjg1OTAzOTU1LCJleHAiOjE2ODU5OTAzNTV9.AGXRkXQLTS3yJC8RoforQi9zAQbdzTIJxq_AY3bsmOM + +{ + "auctionCategory": "BAGS", + "auctionDescription": "string", + "auctionPrice": 1000, + "auctionQty": 10, + "auctionTitle": "켈비클라인가방" +} + +### 역옥션 수정( 유저 ) +PUT http://localhost:8080/auction +Content-Type: application/json +X-AUTH-TOKEN: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkNFdqdHRxUzZteHEzYmF5Qm1paldBPT0iLCJqdGkiOiJDbVlEdjVNSzVZVXlpazhLR05Ed293PT0iLCJyb2xlcyI6IkNVU1RPTUVSIiwiaWF0IjoxNjg1OTAzOTU1LCJleHAiOjE2ODU5OTAzNTV9.AGXRkXQLTS3yJC8RoforQi9zAQbdzTIJxq_AY3bsmOM { "auctionCategory": "BAGS", - "auction_description": "string", - "auction_price": 1000, - "auction_qty": 1, - "auction_title": "켈빈클라인 가방" + "auctionNumber": 1, + "auctionDescription": "string", + "auctionPrice": 10000, + "auctionQty": 10, + "auctionTitle": "string" +} + +### 역옥션 삭제( 유저 ) +DELETE http://localhost:8080/auction +Content-Type: application/json +X-AUTH-TOKEN: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkNFdqdHRxUzZteHEzYmF5Qm1paldBPT0iLCJqdGkiOiJDbVlEdjVNSzVZVXlpazhLR05Ed293PT0iLCJyb2xlcyI6IkNVU1RPTUVSIiwiaWF0IjoxNjg1ODU5Nzc1LCJleHAiOjE2ODU5NDYxNzV9.1NH1T33X5iX0B4J054mVOTXWcZhhWi7KSS4A2JMVg2s + +{ + "auctionNumber": 1 +} + + +### 입찰 ( 유저 ) + +< {% + request.variables.set("number", "1") +%} + +POST http://localhost:8080/bid/auction/{{number}} +Content-Type: application/json +X-AUTH-TOKEN: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkNFdqdHRxUzZteHEzYmF5Qm1paldBPT0iLCJqdGkiOiJDbVlEdjVNSzVZVXlpazhLR05Ed293PT0iLCJyb2xlcyI6IkNVU1RPTUVSIiwiaWF0IjoxNjg1OTAzOTU1LCJleHAiOjE2ODU5OTAzNTV9.AGXRkXQLTS3yJC8RoforQi9zAQbdzTIJxq_AY3bsmOM + +{ + "bid_record": 999999, + "conditions": "NEW", + "description": "새거입니다." } +### 입찰 취소( 유저 ) +DELETE http://localhost:8080/bid/ +Content-Type: application/json +X-AUTH-TOKEN: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ6Q0diclhScGJ3cmU1MFU5eVNmM2VBPT0iLCJqdGkiOiJTdWJIZUtVUlJyZVFZK1dTT25Ca3RnPT0iLCJyb2xlcyI6IkNVU1RPTUVSIiwiaWF0IjoxNjg1OTA0NDE4LCJleHAiOjE2ODU5OTA4MTh9.8F1fuLZvVaJt9KT6JVXS7E88CGEeZj4_rlALnfrk12o +{ + "id": 6 +} ##################################### \ No newline at end of file diff --git a/src/main/java/com/example/wantedmarket/config/JwtAuthenticationProvider.java b/src/main/java/com/example/wantedmarket/config/JwtAuthenticationProvider.java index 0c1b84c..c131d36 100644 --- a/src/main/java/com/example/wantedmarket/config/JwtAuthenticationProvider.java +++ b/src/main/java/com/example/wantedmarket/config/JwtAuthenticationProvider.java @@ -1,7 +1,12 @@ package com.example.wantedmarket.config; +import static com.example.wantedmarket.exception.ErrorCode.NOT_FOUND_USER; + +import com.example.wantedmarket.exception.CustomException; import com.example.wantedmarket.user.domain.common.UserVo; import com.example.wantedmarket.user.domain.common.UserType; +import com.example.wantedmarket.user.domain.model.User; +import com.example.wantedmarket.user.domain.service.UserService; import com.example.wantedmarket.util.Aes256Util; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jws; @@ -9,11 +14,19 @@ import io.jsonwebtoken.SignatureAlgorithm; import java.util.Date; import java.util.Objects; +import org.springframework.beans.factory.annotation.Autowired; public class JwtAuthenticationProvider { private String secretKey = "secretKey"; private long tokenValidTime = 1000L * 60 * 60 * 24; + private UserService userService; + + @Autowired + public void setUserService(UserService userService){ + this.userService = userService; + } + public String createToken(String userPk, Long id, UserType userType){ Claims claims = Jwts.claims().setSubject(Aes256Util.encrypt(userPk)) @@ -40,8 +53,14 @@ public boolean validateToken(String jwtToken){ public UserVo getUserVo(String token){ Claims c = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token) .getBody(); - return new UserVo(Long.valueOf(Objects.requireNonNull(Aes256Util + UserVo userVo = new UserVo(Long.valueOf(Objects.requireNonNull(Aes256Util .decrypt(c.getId()))), Aes256Util.decrypt(c.getSubject())); + + if(!userService.validUser(userVo.getUserId()).getActive()){ + throw new CustomException(NOT_FOUND_USER); + } + + return userVo; } } diff --git a/src/main/java/com/example/wantedmarket/exception/ErrorCode.java b/src/main/java/com/example/wantedmarket/exception/ErrorCode.java index 9191792..e39f156 100644 --- a/src/main/java/com/example/wantedmarket/exception/ErrorCode.java +++ b/src/main/java/com/example/wantedmarket/exception/ErrorCode.java @@ -18,7 +18,15 @@ public enum ErrorCode { NOT_ENOUGH_BALANCE(HttpStatus.BAD_REQUEST, "잔액이 부족합니다."), // auction - NOT_FOUND_AUCTION(HttpStatus.BAD_REQUEST,"입찰 실패 : 해당 역경매 글이 존재하지 않습니다."); + + NOT_ENOUGH_QTY(HttpStatus.BAD_REQUEST, "등록 실패 : 수량은 1개 이상부터 등록이 가능합니다."), + NOT_ENOUGH_PRICE(HttpStatus.BAD_REQUEST, "등록 실패 : 가격은 0원 이상부터 등록이 가능합니다."), + + // bid + NOT_FOUND_AUCTION(HttpStatus.BAD_REQUEST,"입찰 실패 : 해당 역경매 글이 존재하지 않습니다."), + HIGH_BID_PRICE(HttpStatus.BAD_REQUEST,"입찰 실패 : 요청 입찰 가격이 현재 최저 입찰가보다 높습니다."), + NOT_FOUND_BID(HttpStatus.BAD_REQUEST,"삭제 실패 : 입찰 가격 삭제가 실패하였습니다."); + private final HttpStatus httpStatus; private final String detail; } diff --git a/src/main/java/com/example/wantedmarket/order/domain/common/AuctionCategory.java b/src/main/java/com/example/wantedmarket/order/domain/common/AuctionCategory.java index 5f8e2d2..c63731e 100644 --- a/src/main/java/com/example/wantedmarket/order/domain/common/AuctionCategory.java +++ b/src/main/java/com/example/wantedmarket/order/domain/common/AuctionCategory.java @@ -2,6 +2,6 @@ public enum AuctionCategory { CLOTHES, SHOES, ELECTRONICS, BAGS, COMPUTERS, COSMETICS, BOOKS, FURNITURE, - INFORMATION, Education, FOODS, TIME, CAMPING, CARS, BICYCLES, WATCHES, + INFORMATION, EDUCATION, FOODS, TIME, CAMPING, CARS, BICYCLES, WATCHES, MEDICINES, STATIONARY; } diff --git a/src/main/java/com/example/wantedmarket/order/domain/common/Conditions.java b/src/main/java/com/example/wantedmarket/order/domain/common/Conditions.java new file mode 100644 index 0000000..f7f1fba --- /dev/null +++ b/src/main/java/com/example/wantedmarket/order/domain/common/Conditions.java @@ -0,0 +1,5 @@ +package com.example.wantedmarket.order.domain.common; + +public enum Conditions { + NEW, USED_LIKE_NEW, USED_VERY_GOOD, USED_GOOD, USED_ACCEPTABLE, USED_DAMAGED; +} diff --git a/src/main/java/com/example/wantedmarket/order/domain/controller/AuctionController.java b/src/main/java/com/example/wantedmarket/order/domain/controller/AuctionController.java index aa158e7..0f98f34 100644 --- a/src/main/java/com/example/wantedmarket/order/domain/controller/AuctionController.java +++ b/src/main/java/com/example/wantedmarket/order/domain/controller/AuctionController.java @@ -2,16 +2,19 @@ import com.example.wantedmarket.config.JwtAuthenticationProvider; import com.example.wantedmarket.order.domain.controller.dto.AuctionDto; -import com.example.wantedmarket.order.domain.model.Auction; +import com.example.wantedmarket.order.domain.controller.dto.DeleteAuctionForm; +import com.example.wantedmarket.order.domain.controller.dto.UpdateAuctionForm; import com.example.wantedmarket.order.domain.service.AuctionService; import com.example.wantedmarket.user.domain.common.UserVo; -import com.example.wantedmarket.user.domain.user.ChangeBalanceForm; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RequestMapping("/auction") @@ -28,4 +31,19 @@ public ResponseEntity post(@RequestHeader(name = "X-AUTH-TOKEN") Str UserVo vo = provider.getUserVo(token); return ResponseEntity.ok(AuctionDto.from(auctionService.postAuction(vo.getUserId(),dto))); } + + @PutMapping + public ResponseEntity put(@RequestHeader(name = "X-AUTH-TOKEN") String token, + @RequestBody UpdateAuctionForm dto){ + UserVo vo = provider.getUserVo(token); + return ResponseEntity.ok(AuctionDto.from(auctionService.modifyAuction(vo.getUserId(), dto))); + } + + @DeleteMapping + public ResponseEntity delete(@RequestHeader(name = "X-AUTH-TOKEN") String token, + @RequestBody DeleteAuctionForm dto){ + UserVo vo = provider.getUserVo(token); + auctionService.deleteAuction(vo.getUserId(), dto); + return ResponseEntity.ok().build(); + } } diff --git a/src/main/java/com/example/wantedmarket/order/domain/controller/BidContorller.java b/src/main/java/com/example/wantedmarket/order/domain/controller/BidContorller.java index dd04e5f..6e5bbe5 100644 --- a/src/main/java/com/example/wantedmarket/order/domain/controller/BidContorller.java +++ b/src/main/java/com/example/wantedmarket/order/domain/controller/BidContorller.java @@ -2,11 +2,15 @@ import com.example.wantedmarket.config.JwtAuthenticationProvider; import com.example.wantedmarket.order.domain.controller.dto.BidDto; +import com.example.wantedmarket.order.domain.controller.dto.BidForm; +import com.example.wantedmarket.order.domain.controller.dto.DeleteAuctionForm; +import com.example.wantedmarket.order.domain.controller.dto.DeleteBidForm; import com.example.wantedmarket.order.domain.model.Bid; import com.example.wantedmarket.order.domain.service.BidService; import com.example.wantedmarket.user.domain.common.UserVo; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -26,9 +30,16 @@ public class BidContorller { @PostMapping("/auction/{number}") public ResponseEntity bidding(@RequestHeader(name = "X-AUTH-TOKEN") String token, @PathVariable Long number, - @RequestParam(value = "bidding price")Long bid) { + @RequestBody BidForm dto) { UserVo vo = provider.getUserVo(token); - return ResponseEntity.ok(BidDto.from(bidService.bidSave(vo.getUserId(), number, bid))); + return ResponseEntity.ok(BidDto.from(bidService.bidSave(vo.getUserId(), number, dto.toService()))); + } + + @DeleteMapping + public void deleteBid(@RequestHeader(name = "X-AUTH-TOKEN") String token, + @RequestBody DeleteBidForm form){ + UserVo vo = provider.getUserVo(token); + bidService.bidDelete(vo.getUserId(), form); } diff --git a/src/main/java/com/example/wantedmarket/order/domain/controller/dto/AuctionDto.java b/src/main/java/com/example/wantedmarket/order/domain/controller/dto/AuctionDto.java index 00b1845..1148063 100644 --- a/src/main/java/com/example/wantedmarket/order/domain/controller/dto/AuctionDto.java +++ b/src/main/java/com/example/wantedmarket/order/domain/controller/dto/AuctionDto.java @@ -15,21 +15,17 @@ @Builder public class AuctionDto { @ApiModelProperty(hidden = true) - private String user_id; + private String userId; private AuctionCategory auctionCategory; - private Long auction_price; - private String auction_title; - private Long auction_qty; - private String auction_description; + private Long auctionPrice; + private String auctionTitle; + private Long auctionQty; + private String auctionDescription; public static AuctionDto from(Auction auction){ - return new AuctionDto(auction.getUser_id(), auction.getAuctionCategory(), - auction.getAuction_price(), auction.getAuction_title(), - auction.getAuction_qty(), auction.getAuction_description()); + return new AuctionDto(auction.getUserId(), auction.getAuctionCategory(), + auction.getAuctionPrice(), auction.getAuctionTitle(), + auction.getAuctionQty(), auction.getAuctionDescription()); } - - - - } diff --git a/src/main/java/com/example/wantedmarket/order/domain/controller/dto/BidDto.java b/src/main/java/com/example/wantedmarket/order/domain/controller/dto/BidDto.java index 9b9af71..462612c 100644 --- a/src/main/java/com/example/wantedmarket/order/domain/controller/dto/BidDto.java +++ b/src/main/java/com/example/wantedmarket/order/domain/controller/dto/BidDto.java @@ -1,27 +1,30 @@ package com.example.wantedmarket.order.domain.controller.dto; +import com.example.wantedmarket.order.domain.common.Conditions; import com.example.wantedmarket.order.domain.model.Auction; import com.example.wantedmarket.order.domain.model.Bid; -import com.example.wantedmarket.user.domain.model.User; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.Setter; @Builder -@Setter @Getter @AllArgsConstructor @NoArgsConstructor public class BidDto { + private Long auctionId; private Long bid_record; - private User user; - private Auction auction; + private Conditions conditions; + private String description; public static BidDto from(Bid bid){ - return new BidDto(bid.getBid_record(), bid.getUser(), bid.getAuction()); + return BidDto.builder() + .auctionId(bid.getAuction().getAuctionNumber()) + .bid_record(bid.getBid_record()) + .conditions(bid.getConditions()) + .description(bid.getDescription()) + .build(); } - } diff --git a/src/main/java/com/example/wantedmarket/order/domain/controller/dto/BidForm.java b/src/main/java/com/example/wantedmarket/order/domain/controller/dto/BidForm.java new file mode 100644 index 0000000..69ac971 --- /dev/null +++ b/src/main/java/com/example/wantedmarket/order/domain/controller/dto/BidForm.java @@ -0,0 +1,21 @@ +package com.example.wantedmarket.order.domain.controller.dto; + +import com.example.wantedmarket.order.domain.common.Conditions; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Builder +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class BidForm { + private Long bid_record; + private Conditions conditions; + private String description; + + public BidForm toService(){ + return new BidForm(bid_record, conditions, description); + } +} diff --git a/src/main/java/com/example/wantedmarket/order/domain/controller/dto/DeleteAuctionForm.java b/src/main/java/com/example/wantedmarket/order/domain/controller/dto/DeleteAuctionForm.java new file mode 100644 index 0000000..29fd541 --- /dev/null +++ b/src/main/java/com/example/wantedmarket/order/domain/controller/dto/DeleteAuctionForm.java @@ -0,0 +1,14 @@ +package com.example.wantedmarket.order.domain.controller.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DeleteAuctionForm { + private Long auctionNumber; +} diff --git a/src/main/java/com/example/wantedmarket/order/domain/controller/dto/DeleteBidForm.java b/src/main/java/com/example/wantedmarket/order/domain/controller/dto/DeleteBidForm.java new file mode 100644 index 0000000..04245d0 --- /dev/null +++ b/src/main/java/com/example/wantedmarket/order/domain/controller/dto/DeleteBidForm.java @@ -0,0 +1,14 @@ +package com.example.wantedmarket.order.domain.controller.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DeleteBidForm { + private Long id; +} diff --git a/src/main/java/com/example/wantedmarket/order/domain/controller/dto/UpdateAuctionForm.java b/src/main/java/com/example/wantedmarket/order/domain/controller/dto/UpdateAuctionForm.java new file mode 100644 index 0000000..fbe22a1 --- /dev/null +++ b/src/main/java/com/example/wantedmarket/order/domain/controller/dto/UpdateAuctionForm.java @@ -0,0 +1,20 @@ +package com.example.wantedmarket.order.domain.controller.dto; + +import com.example.wantedmarket.order.domain.common.AuctionCategory; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class UpdateAuctionForm { + private Long auctionNumber; + private AuctionCategory auctionCategory; + private Long auctionPrice; + private String auctionTitle; + private Long auctionQty; + private String auctionDescription; +} diff --git a/src/main/java/com/example/wantedmarket/order/domain/model/Auction.java b/src/main/java/com/example/wantedmarket/order/domain/model/Auction.java index 13fb023..f61ac0b 100644 --- a/src/main/java/com/example/wantedmarket/order/domain/model/Auction.java +++ b/src/main/java/com/example/wantedmarket/order/domain/model/Auction.java @@ -2,11 +2,11 @@ import com.example.wantedmarket.order.domain.common.AuctionCategory; import com.example.wantedmarket.order.domain.controller.dto.AuctionDto; -import com.example.wantedmarket.user.domain.controller.dto.SignUpForm; -import com.example.wantedmarket.user.domain.model.User; +import com.example.wantedmarket.util.BooleanToYNConverter; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; +import javax.persistence.Convert; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; @@ -21,6 +21,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.hibernate.annotations.ColumnDefault; import org.hibernate.envers.AuditOverride; import org.hibernate.envers.Audited; @@ -35,28 +36,35 @@ public class Auction extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long auction_number; - private String user_id; + @Column(name ="auction_number", unique = true) + private Long auctionNumber; + + private String userId; + @Enumerated(value = EnumType.STRING) private AuctionCategory auctionCategory; - private Long auction_price; - private String auction_title; - private Long auction_qty; - private String auction_description; + private Long auctionPrice; + private String auctionTitle; + private Long auctionQty; + private String auctionDescription; + + @Convert(converter = BooleanToYNConverter.class) + private Boolean auctionActive; @OneToMany(mappedBy = "auction", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE) @OrderBy("bid_record asc") // 가격 정렬 - private List bid; + private List bids; public static Auction from(String userId, AuctionDto dto) { return Auction.builder() - .user_id(userId) + .userId(userId) .auctionCategory(dto.getAuctionCategory()) - .auction_price(dto.getAuction_price()) - .auction_title(dto.getAuction_title()) - .auction_qty(dto.getAuction_qty()) - .auction_description(dto.getAuction_description()) + .auctionPrice(dto.getAuctionPrice()) + .auctionTitle(dto.getAuctionTitle()) + .auctionQty(dto.getAuctionQty()) + .auctionDescription(dto.getAuctionDescription()) + .auctionActive(true) .build(); } } diff --git a/src/main/java/com/example/wantedmarket/order/domain/model/Bid.java b/src/main/java/com/example/wantedmarket/order/domain/model/Bid.java index 3628923..157b097 100644 --- a/src/main/java/com/example/wantedmarket/order/domain/model/Bid.java +++ b/src/main/java/com/example/wantedmarket/order/domain/model/Bid.java @@ -1,14 +1,19 @@ package com.example.wantedmarket.order.domain.model; +import com.example.wantedmarket.order.domain.common.Conditions; import com.example.wantedmarket.order.domain.controller.dto.BidDto; +import com.example.wantedmarket.order.domain.controller.dto.BidForm; import com.example.wantedmarket.user.domain.model.User; import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; +import javax.persistence.Table; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -17,12 +22,13 @@ import org.hibernate.envers.AuditOverride; import org.hibernate.envers.Audited; -@Entity @Setter @Getter @Builder @NoArgsConstructor @AllArgsConstructor +@Table(name = "bids") +@Entity @Audited @AuditOverride(forClass = BaseEntity.class) public class Bid extends BaseEntity{ @@ -31,7 +37,7 @@ public class Bid extends BaseEntity{ private Long id; @ManyToOne - @JoinColumn(name = "auction_id") + @JoinColumn(name = "auction_number") private Auction auction; @ManyToOne(fetch = FetchType.LAZY) @@ -39,12 +45,18 @@ public class Bid extends BaseEntity{ private User user; private Long bid_record; + private String description; + + @Enumerated(value = EnumType.STRING) + private Conditions conditions; - public static Bid from(BidDto dto){ + public static Bid of(Auction auction, User user, BidForm dto){ return Bid.builder() - .auction(dto.getAuction()) - .user(dto.getUser()) + .auction(auction) + .user(user) .bid_record(dto.getBid_record()) + .description(dto.getDescription()) + .conditions(dto.getConditions()) .build(); } } diff --git a/src/main/java/com/example/wantedmarket/order/domain/repository/AuctionRepository.java b/src/main/java/com/example/wantedmarket/order/domain/repository/AuctionRepository.java index f8c4283..6052b7c 100644 --- a/src/main/java/com/example/wantedmarket/order/domain/repository/AuctionRepository.java +++ b/src/main/java/com/example/wantedmarket/order/domain/repository/AuctionRepository.java @@ -1,9 +1,11 @@ package com.example.wantedmarket.order.domain.repository; import com.example.wantedmarket.order.domain.model.Auction; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface AuctionRepository extends JpaRepository { + Optional findByUserIdAndAuctionNumber(String userId, Long auctionNumber); } diff --git a/src/main/java/com/example/wantedmarket/order/domain/repository/BidRepository.java b/src/main/java/com/example/wantedmarket/order/domain/repository/BidRepository.java index 32e806b..7ff9c9c 100644 --- a/src/main/java/com/example/wantedmarket/order/domain/repository/BidRepository.java +++ b/src/main/java/com/example/wantedmarket/order/domain/repository/BidRepository.java @@ -1,10 +1,12 @@ package com.example.wantedmarket.order.domain.repository; import com.example.wantedmarket.order.domain.model.Bid; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface BidRepository extends JpaRepository { + Optional findByUser_UserIdAndId(String UserId, Long Id); } diff --git a/src/main/java/com/example/wantedmarket/order/domain/service/AuctionService.java b/src/main/java/com/example/wantedmarket/order/domain/service/AuctionService.java index 68894d7..40d70fb 100644 --- a/src/main/java/com/example/wantedmarket/order/domain/service/AuctionService.java +++ b/src/main/java/com/example/wantedmarket/order/domain/service/AuctionService.java @@ -1,6 +1,13 @@ package com.example.wantedmarket.order.domain.service; +import static com.example.wantedmarket.exception.ErrorCode.NOT_ENOUGH_PRICE; +import static com.example.wantedmarket.exception.ErrorCode.NOT_ENOUGH_QTY; +import static com.example.wantedmarket.exception.ErrorCode.NOT_FOUND_AUCTION; + +import com.example.wantedmarket.exception.CustomException; import com.example.wantedmarket.order.domain.controller.dto.AuctionDto; +import com.example.wantedmarket.order.domain.controller.dto.DeleteAuctionForm; +import com.example.wantedmarket.order.domain.controller.dto.UpdateAuctionForm; import com.example.wantedmarket.order.domain.model.Auction; import com.example.wantedmarket.order.domain.repository.AuctionRepository; import com.example.wantedmarket.user.domain.repository.UserRepository; @@ -16,6 +23,59 @@ public class AuctionService { @Transactional public Auction postAuction(String userId, AuctionDto dto){ + // 수량은 1개 이상 + if(dto.getAuctionQty() <1){ + throw new CustomException(NOT_ENOUGH_QTY); + } + + // 최저 등록 가능 금액은 0 원 + if(dto.getAuctionPrice() < 0){ + throw new CustomException(NOT_ENOUGH_PRICE); + } return auctionRepository.save(Auction.from(userId,dto)); } + + @Transactional + public Auction modifyAuction(String userId, UpdateAuctionForm dto){ + // 수량은 1개 이상 + if(dto.getAuctionQty() <1){ + throw new CustomException(NOT_ENOUGH_QTY); + } + + // 최저 등록 가능 금액은 0 원 + if(dto.getAuctionPrice() < 0){ + throw new CustomException(NOT_ENOUGH_PRICE); + } + + Auction auction = auctionRepository.findByUserIdAndAuctionNumber( + userId, dto.getAuctionNumber()).orElseThrow( + () -> new CustomException(NOT_FOUND_AUCTION)); + + // 역경매가 삭제되었거나 정상적인 상태가 아님. + if(auction.getAuctionActive().equals(false)){ + throw new CustomException(NOT_FOUND_AUCTION); + } + + auction.setAuctionCategory(dto.getAuctionCategory()); + auction.setAuctionTitle(dto.getAuctionTitle()); + auction.setAuctionDescription(dto.getAuctionDescription()); + auction.setAuctionPrice(dto.getAuctionPrice()); + auction.setAuctionQty(dto.getAuctionQty()); + return auction; + } + + @Transactional + public void deleteAuction(String userId, DeleteAuctionForm dto){ + Auction auction = auctionRepository.findByUserIdAndAuctionNumber( + userId, dto.getAuctionNumber()).orElseThrow( + () -> new CustomException(NOT_FOUND_AUCTION)); + + // 역경매가 삭제되었거나 정상적인 상태가 아님. + if(auction.getAuctionActive().equals(false)){ + throw new CustomException(NOT_FOUND_AUCTION); + } + + auction.setAuctionActive(false); + } + } diff --git a/src/main/java/com/example/wantedmarket/order/domain/service/BidService.java b/src/main/java/com/example/wantedmarket/order/domain/service/BidService.java index e39156b..0ed748e 100644 --- a/src/main/java/com/example/wantedmarket/order/domain/service/BidService.java +++ b/src/main/java/com/example/wantedmarket/order/domain/service/BidService.java @@ -1,10 +1,14 @@ package com.example.wantedmarket.order.domain.service; +import static com.example.wantedmarket.exception.ErrorCode.HIGH_BID_PRICE; import static com.example.wantedmarket.exception.ErrorCode.NOT_FOUND_AUCTION; +import static com.example.wantedmarket.exception.ErrorCode.NOT_FOUND_BID; import static com.example.wantedmarket.exception.ErrorCode.NOT_FOUND_USER; import com.example.wantedmarket.exception.CustomException; import com.example.wantedmarket.order.domain.controller.dto.BidDto; +import com.example.wantedmarket.order.domain.controller.dto.BidForm; +import com.example.wantedmarket.order.domain.controller.dto.DeleteBidForm; import com.example.wantedmarket.order.domain.model.Auction; import com.example.wantedmarket.order.domain.model.Bid; import com.example.wantedmarket.order.domain.repository.AuctionRepository; @@ -23,18 +27,25 @@ public class BidService { private final AuctionRepository auctionRepository; @Transactional - public Bid bidSave(String userId, Long auction_number, Long bidPrice){ + public Bid bidSave(String userId, Long auction_number, BidForm dto){ User user = userRepository.findByUserId(userId).orElseThrow( () -> new CustomException(NOT_FOUND_USER)); Auction auction = auctionRepository.findById(auction_number).orElseThrow( () -> new CustomException(NOT_FOUND_AUCTION)); - BidDto dto = new BidDto(); - dto.setUser(user); - dto.setAuction(auction); - dto.setBid_record(bidPrice); + // 역경매가 삭제되었거나 정상적인 상태가 아님. + if(auction.getAuctionActive().equals(false)){ + throw new CustomException(NOT_FOUND_AUCTION); + } - return bidRepository.save(Bid.from(dto)); + return bidRepository.save(Bid.of(auction, user, dto)); + } + + @Transactional + public void bidDelete(String userId, DeleteBidForm form){ + Bid bid = bidRepository.findByUser_UserIdAndId(userId,form.getId()) + .orElseThrow(() -> new CustomException(NOT_FOUND_BID)); + bidRepository.delete(bid); } } diff --git a/src/main/java/com/example/wantedmarket/user/domain/application/SignInApplication.java b/src/main/java/com/example/wantedmarket/user/domain/application/SignInApplication.java index fe3d7b7..ef1a629 100644 --- a/src/main/java/com/example/wantedmarket/user/domain/application/SignInApplication.java +++ b/src/main/java/com/example/wantedmarket/user/domain/application/SignInApplication.java @@ -1,5 +1,8 @@ package com.example.wantedmarket.user.domain.application; +import static com.example.wantedmarket.exception.ErrorCode.NOT_FOUND_AUCTION; +import static com.example.wantedmarket.exception.ErrorCode.NOT_FOUND_USER; + import com.example.wantedmarket.config.JwtAuthenticationProvider; import com.example.wantedmarket.exception.CustomException; import com.example.wantedmarket.exception.ErrorCode; @@ -18,10 +21,14 @@ public class SignInApplication { private final JwtAuthenticationProvider provider; - public String userloginToken(SignInForm form){ + public String userLoginToken(SignInForm form){ // 1. 로그인 가능 여부 User u = userService.findValidUser(form.getUserId(), form.getPassword()) .orElseThrow(()-> new CustomException(ErrorCode.LOGIN_CHECK_FAIL)); + // 비활성화 중이면 로그인 불가 + if(u.getActive().equals(false)){ + throw new CustomException(NOT_FOUND_USER); + } // 2. 토큰을 발행하고 // 3. 토큰을 response한다. return provider.createToken(u.getUserId(), u.getId(), UserType.CUSTOMER); diff --git a/src/main/java/com/example/wantedmarket/user/domain/controller/UserController.java b/src/main/java/com/example/wantedmarket/user/domain/controller/UserController.java index 61a1175..0c1fc37 100644 --- a/src/main/java/com/example/wantedmarket/user/domain/controller/UserController.java +++ b/src/main/java/com/example/wantedmarket/user/domain/controller/UserController.java @@ -5,15 +5,18 @@ import com.example.wantedmarket.exception.CustomException; import com.example.wantedmarket.exception.ErrorCode; import com.example.wantedmarket.user.domain.common.UserVo; +import com.example.wantedmarket.user.domain.controller.dto.UpdateUserForm; import com.example.wantedmarket.user.domain.model.User; import com.example.wantedmarket.user.domain.service.UserBalanceService; import com.example.wantedmarket.user.domain.service.UserService; -import com.example.wantedmarket.user.domain.user.ChangeBalanceForm; -import com.example.wantedmarket.user.domain.user.UserDto; +import com.example.wantedmarket.user.domain.controller.dto.ChangeBalanceForm; +import com.example.wantedmarket.user.domain.controller.dto.UserDto; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; @@ -40,9 +43,23 @@ public ResponseEntity getInfo(@RequestHeader(name = "X-AUTH-TOKEN") Str @PostMapping("/balance") public ResponseEntity changeBalance(@RequestHeader(name = "X-AUTH-TOKEN") String token, @RequestBody ChangeBalanceForm form){ - UserVo vo = provider.getUserVo(token); + UserVo vo = provider.getUserVo(token); - return ResponseEntity.ok( + return ResponseEntity.ok( userBalanceService.changeBalance(vo.getUserId(), form).getCurrentMoney()); } + + @PutMapping + public ResponseEntity modifyUser(@RequestHeader(name = "X-AUTH-TOKEN") String token, + @RequestBody UpdateUserForm form){ + UserVo vo = provider.getUserVo(token); + return ResponseEntity.ok(userService.modifyUser(vo.getUserId(), form)); + } + + @DeleteMapping + public void deactivateUser(@RequestHeader(name = "X-AUTH-TOKEN") String token){ + UserVo vo = provider.getUserVo(token); + userService.deactivateId(vo.getUserId()); + } + } diff --git a/src/main/java/com/example/wantedmarket/user/domain/controller/dto/UpdateUserForm.java b/src/main/java/com/example/wantedmarket/user/domain/controller/dto/UpdateUserForm.java new file mode 100644 index 0000000..2ae636e --- /dev/null +++ b/src/main/java/com/example/wantedmarket/user/domain/controller/dto/UpdateUserForm.java @@ -0,0 +1,19 @@ +package com.example.wantedmarket.user.domain.controller.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class UpdateUserForm { + private String password; + private String name; + private String nickName; + private String phone; + private String email; + private String profile; +} diff --git a/src/main/java/com/example/wantedmarket/user/domain/model/User.java b/src/main/java/com/example/wantedmarket/user/domain/model/User.java index 75d3c01..82de9ee 100644 --- a/src/main/java/com/example/wantedmarket/user/domain/model/User.java +++ b/src/main/java/com/example/wantedmarket/user/domain/model/User.java @@ -1,23 +1,33 @@ package com.example.wantedmarket.user.domain.model; +import com.example.wantedmarket.order.domain.model.Bid; import com.example.wantedmarket.user.domain.controller.dto.SignUpForm; +import com.example.wantedmarket.util.BooleanToYNConverter; +import java.util.List; import java.util.Locale; +import javax.persistence.CascadeType; import javax.persistence.Column; +import javax.persistence.Convert; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.OrderBy; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import org.hibernate.envers.AuditOverride; +import org.hibernate.envers.Audited; @Entity @Getter @Setter @Builder +@Audited @NoArgsConstructor @AllArgsConstructor @AuditOverride(forClass = BaseEntity.class) @@ -35,9 +45,16 @@ public class User extends BaseEntity{ private String email; private String profile; + @Convert(converter = BooleanToYNConverter.class) + private Boolean active; + @Column(columnDefinition = "int default 0") private Integer balance; + @OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE) + @OrderBy("bid_record asc") // 댓글 정렬 + private List bids; + public static User from(SignUpForm form){ return User.builder() .userId(form.getUserId().toLowerCase(Locale.ROOT)) @@ -47,6 +64,7 @@ public static User from(SignUpForm form){ .phone(form.getPhone()) .email(form.getEmail().toLowerCase(Locale.ROOT)) .profile("default.png") + .active(true) .build(); } diff --git a/src/main/java/com/example/wantedmarket/user/domain/repository/UserRepository.java b/src/main/java/com/example/wantedmarket/user/domain/repository/UserRepository.java index b53e70b..8c623fe 100644 --- a/src/main/java/com/example/wantedmarket/user/domain/repository/UserRepository.java +++ b/src/main/java/com/example/wantedmarket/user/domain/repository/UserRepository.java @@ -10,4 +10,5 @@ public interface UserRepository extends JpaRepository { Optional findByUserId(String userId); Optional findByEmail(String email); + Optional findByUserIdAndActive(String userId, Boolean active); } diff --git a/src/main/java/com/example/wantedmarket/user/domain/service/UserService.java b/src/main/java/com/example/wantedmarket/user/domain/service/UserService.java index c87cf25..6e94955 100644 --- a/src/main/java/com/example/wantedmarket/user/domain/service/UserService.java +++ b/src/main/java/com/example/wantedmarket/user/domain/service/UserService.java @@ -1,22 +1,27 @@ package com.example.wantedmarket.user.domain.service; +import static com.example.wantedmarket.exception.ErrorCode.NOT_FOUND_USER; + +import com.example.wantedmarket.exception.CustomException; +import com.example.wantedmarket.user.domain.controller.dto.UpdateUserForm; import com.example.wantedmarket.user.domain.model.User; import com.example.wantedmarket.user.domain.repository.UserRepository; import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor public class UserService { private final UserRepository userRepository; - public Optional findByIdAndUserId(Long id, String userId){ return userRepository.findById(id) .stream().filter(user->user.getUserId().equals(userId)) .findFirst(); } + public Optional findValidUser(String userId, String password){ return userRepository.findByUserId(userId).stream().filter( user -> user.getPassword().equals(password)) @@ -26,4 +31,29 @@ public Optional findValidUser(String userId, String password){ public Optional findById(Long id) { return userRepository.findById(id); } + + public User validUser(String userId){ + User user = userRepository.findByUserIdAndActive(userId, true) + .orElseThrow(() -> new CustomException(NOT_FOUND_USER)); + return user; + } + + @Transactional + public void deactivateId(String userId){ + User user = validUser(userId); + user.setActive(false); + } + + @Transactional + public User modifyUser(String userId, UpdateUserForm dto){ + User user = validUser(userId); + user.setPassword(dto.getPassword()); + user.setName(dto.getName()); + user.setNickName(dto.getNickName()); + user.setPhone(dto.getPhone()); + user.setEmail(dto.getEmail()); + user.setProfile(dto.getProfile()); + return user; + } + } diff --git a/src/main/java/com/example/wantedmarket/util/BooleanToYNConverter.java b/src/main/java/com/example/wantedmarket/util/BooleanToYNConverter.java new file mode 100644 index 0000000..c40a0cf --- /dev/null +++ b/src/main/java/com/example/wantedmarket/util/BooleanToYNConverter.java @@ -0,0 +1,18 @@ +package com.example.wantedmarket.util; + +import javax.persistence.AttributeConverter; +import javax.persistence.Converter; + +@Converter +public class BooleanToYNConverter implements AttributeConverter { + + @Override + public String convertToDatabaseColumn(Boolean attribute) { + return (attribute != null&& attribute) ? "Y" : "N"; + } + + @Override + public Boolean convertToEntityAttribute(String yn) { + return "Y".equalsIgnoreCase(yn); + } +}