Skip to content

Commit

Permalink
Merge pull request #102 from TEAM-MODDY/feat/#79
Browse files Browse the repository at this point in the history
[Feat/#79] 모델 지원서 작성 API
  • Loading branch information
hellozo0 authored Jan 12, 2024
2 parents 1836c8d + c672885 commit 4b43397
Show file tree
Hide file tree
Showing 16 changed files with 238 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ public enum ErrorCode {
INVALID_KAKAO_CODE_EXCEPTION(HttpStatus.BAD_REQUEST, "유효하지 않은 카카오 코드를 입력했습니다."),
NOT_MATCH_VERIFICATION_CODE_EXCEPTION(HttpStatus.BAD_REQUEST, "인증번호가 일치하지 않습니다."),
EXPIRE_VERIFICATION_CODE_EXCEPTION(HttpStatus.BAD_REQUEST, "만료된 인증 코드입니다."),
INVALID_HAIR_LENGTH_EXCEPTION(HttpStatus.BAD_REQUEST, "유효하지 않은 머리기장을 입력했습니다."),
INVALID_HAIR_SERVICE_RECORD_EXCEPTION(HttpStatus.BAD_REQUEST, "유효하지 않은 헤어시술을 입력했습니다."),
INVALID_HAIR_SERVICE_RECORD_TERM_EXCEPTION(HttpStatus.BAD_REQUEST, "유효하지 않은 헤어시술 이력기간을 입력했습니다."),
INVALID_HAIR_STYLE_EXCEPTION(HttpStatus.BAD_REQUEST, "유효하지 않은 헤어스타일을 입력했습니다."),

// 401
TOKEN_NOT_CONTAINED_EXCEPTION(HttpStatus.UNAUTHORIZED, "Access Token이 필요합니다."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public enum SuccessCode {
SEND_VERIFICATION_CODE_SUCCESS(HttpStatus.OK, "전화번호 인증 요청 성공입니다."),
FIND_REGION_LIST_SUCCESS(HttpStatus.OK, "희망 지역 리스트 조회 성공입니다."),
VERIFICATION_CODE_MATCH_SUCCESS(HttpStatus.OK, "전화번호 인증 성공입니다."),
LOGOUT_SUCCESS(HttpStatus.OK, "로그아웃 성공입니다.");
LOGOUT_SUCCESS(HttpStatus.OK, "로그아웃 성공입니다."),
CREATE_MODEL_APPLICATION_SUCCESS(HttpStatus.OK, "모델 지원서 생성 성공입니다.");

private final HttpStatus httpStatus;
private final String message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,5 @@ public record DesignerCreateRequest(
String introduction,
String kakaoOpenChatUrl,
List<DayOfWeek> dayOffs

) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import com.moddy.server.common.dto.SuccessResponse;
import com.moddy.server.common.exception.enums.SuccessCode;
import com.moddy.server.config.resolver.user.UserId;
import com.moddy.server.controller.model.dto.requestEditor.ListPropertyEditor;
import com.moddy.server.controller.model.dto.request.ModelApplicationRequest;
import com.moddy.server.controller.model.dto.request.ModelHairServiceRequest;
import com.moddy.server.controller.model.dto.response.DetailOfferResponse;
import com.moddy.server.controller.model.dto.response.ModelMainResponse;
import com.moddy.server.controller.model.dto.response.OpenChatResponse;
Expand All @@ -18,7 +21,10 @@
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import java.util.List;

@RestController
@Tag(name = "ModelController")
Expand Down Expand Up @@ -89,4 +95,25 @@ public SuccessNonDataResponse acceptOffer(

}

@Operation(summary = "[JWT] 모델 지원서 작성", description = "모델 지원서 작성 API입니다.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "모델 지원서 작성 성공"),
@ApiResponse(responseCode = "400", description = "인증 오류 입니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "500", description = "서버 내부 오류 입니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
})
@SecurityRequirement(name = "JWT Auth")
@PostMapping(value = "/model/application", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE})
public SuccessNonDataResponse submitModelApplication(
@Parameter(hidden = true) @UserId Long userId,
@ModelAttribute ModelApplicationRequest request
) {
modelService.createModelApplication(userId, request);
return SuccessNonDataResponse.success(SuccessCode.CREATE_MODEL_APPLICATION_SUCCESS);
}

@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(List.class, "hairServiceRecords", new ListPropertyEditor(ModelHairServiceRequest.class));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.moddy.server.controller.model.dto.request;

import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import io.swagger.v3.oas.annotations.media.Schema;

public record ModelApplicationRequest(
String hairLength,
List<String> preferHairStyles,
String hairDetail,
List<ModelHairServiceRequest> hairServiceRecords,
MultipartFile modelImgUrl,
String instagramId,
MultipartFile applicationCaptureImgUrl
) {

@Schema(description = "Hair service records in JSON array format", example = "[{\"hairService\": \"PERM\", \"hairServiceTerm\": \"UNDER_ONE\"}, {\"hairService\": \"BLACK\", \"hairServiceTerm\": \"ABOVE_TWELVE\"}]")
public List<ModelHairServiceRequest> getHairServiceRecords() {
return hairServiceRecords;
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.moddy.server.controller.model.dto.request;

public record ModelHairServiceRequest(
String hairService,
String hairServiceTerm
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.moddy.server.controller.model.dto.requestEditor;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.util.StringUtils;
import java.beans.PropertyEditorSupport;
import java.io.IOException;
import java.util.List;


public class ListPropertyEditor extends PropertyEditorSupport {

private final Class<?> elementType;
private final ObjectMapper objectMapper;

public ListPropertyEditor(Class<?> elementType) {
this.elementType = elementType;
this.objectMapper = new ObjectMapper();
}

@Override
public void setAsText(String text) throws IllegalArgumentException {
if (StringUtils.hasText(text)) {
try {
List<?> list = objectMapper.readValue(text, objectMapper.getTypeFactory().constructCollectionType(List.class, elementType));
setValue(list);
} catch (IOException e) {
throw new IllegalArgumentException("Failed to convert value to List: " + text, e);
}
} else {
setValue(null);
}
}

@Override
public String getAsText() {
Object value = getValue();
if (value == null) {
return "";
}
try {
return objectMapper.writeValueAsString(value);
} catch (IOException e) {
throw new IllegalArgumentException("Failed to convert value to JSON: " + value, e);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
package com.moddy.server.domain.hair_model_application;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.moddy.server.common.exception.enums.ErrorCode;
import com.moddy.server.common.exception.model.BadRequestException;
import com.moddy.server.domain.user.Gender;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.stream.Stream;

@AllArgsConstructor
@Getter
public enum HairLength {
SHORT("숏"), ABOVE_SHOULDER("단발"), UNDER_SHOULDER("어깨 아래"), UNDER_WAIST("허리 아래");

private final String value;

@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static HairLength findByHairLength(String hairLength) {
return Stream.of(HairLength.values())
.filter(c -> c.name().equals(hairLength))
.findFirst()
.orElseThrow(() -> new BadRequestException(ErrorCode.INVALID_HAIR_LENGTH_EXCEPTION));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@
import com.moddy.server.domain.user.User;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
public class HairModelApplication extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@
import com.moddy.server.domain.hair_model_application.HairModelApplication;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
public class HairServiceRecord extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
package com.moddy.server.domain.hair_service_record;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.moddy.server.common.exception.enums.ErrorCode;
import com.moddy.server.common.exception.model.BadRequestException;
import com.moddy.server.domain.hair_model_application.HairLength;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.stream.Stream;

@Getter
@AllArgsConstructor
public enum ServiceRecord {
PERM("펌"), DECOLOR("탈색"), BLACK("블랙 염색"), COLOR("컬러 염색");

private final String value;

@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static ServiceRecord findByServiceRecord(String serviceRecord) {
return Stream.of(ServiceRecord.values())
.filter(c -> c.name().equals(serviceRecord))
.findFirst()
.orElseThrow(() -> new BadRequestException(ErrorCode.INVALID_HAIR_SERVICE_RECORD_EXCEPTION));
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
package com.moddy.server.domain.hair_service_record;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.moddy.server.common.exception.enums.ErrorCode;
import com.moddy.server.common.exception.model.BadRequestException;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.stream.Stream;

@Getter
@AllArgsConstructor
public enum ServiceRecordTerm {
UNDER_ONE("1 개월 미만"), ONE_THREE("1 - 3 개월"), FOUR_SIX("4 - 6 개월"), SEVEN_TWELVE("7 - 12 개월"), ABOVE_TWELVE("12 개월 초과");

private final String value;

@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static ServiceRecordTerm findByServiceRecord(String serviceRecordTerm) {
return Stream.of(ServiceRecordTerm.values())
.filter(c -> c.name().equals(serviceRecordTerm))
.findFirst()
.orElseThrow(() -> new BadRequestException(ErrorCode.INVALID_HAIR_SERVICE_RECORD_TERM_EXCEPTION));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.moddy.server.domain.hair_service_record.repository;

import com.moddy.server.domain.hair_service_record.HairServiceRecord;
import org.springframework.data.jpa.repository.JpaRepository;

public interface HairServiceRecordJpaRepository extends JpaRepository<HairServiceRecord, Long> {
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
package com.moddy.server.domain.prefer_hair_style;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.moddy.server.common.exception.enums.ErrorCode;
import com.moddy.server.common.exception.model.BadRequestException;
import com.moddy.server.domain.hair_model_application.HairLength;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.stream.Stream;

@AllArgsConstructor
@Getter
public enum HairStyle {
NORMAL_CUT("일반 커트"), ALL_COLOR("전체 염색"), ALL_DECOLOR("전체 탈색"), SETTING_PERM("셋팅펌"), NORMAL_PERM("일반펌"), STRAIGHTENING("매직");

private final String value;

@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static HairStyle findByHairStyle(String hairStyle) {
return Stream.of(HairStyle.values())
.filter(c -> c.name().equals(hairStyle))
.findFirst()
.orElseThrow(() -> new BadRequestException(ErrorCode.INVALID_HAIR_STYLE_EXCEPTION));
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
import com.moddy.server.domain.hair_model_application.HairModelApplication;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.*;
import lombok.experimental.SuperBuilder;

@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
public class PreferHairStyle extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand Down
Loading

0 comments on commit 4b43397

Please sign in to comment.