Skip to content

Commit

Permalink
Merge pull request #214 from JokerTrickster/feat/213/profile_image_api
Browse files Browse the repository at this point in the history
{feat} - 프로필 이미지 저장하기 api 구현 \n
  • Loading branch information
JokerTrickster authored Nov 14, 2024
2 parents 049c8dd + b4376b7 commit 293683f
Show file tree
Hide file tree
Showing 19 changed files with 359 additions and 1 deletion.
57 changes: 57 additions & 0 deletions src/docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -1061,6 +1061,49 @@ const docTemplate = `{
}
}
},
"/v0.1/users/profiles/image": {
"post": {
"description": "■ errCode with 400\nPARAM_BAD : 파라미터 오류\nUSER_NOT_FOUND : 유저가 존재하지 않음\n■ errCode with 401\nINVALID_AUTH_CODE : 인증 코드 검증 실패\nTOKEN_BAD : 잘못된 토큰\nINVALID_ACCESS_TOKEN : 잘못된 액세스 토큰\n\n■ errCode with 500\nINTERNAL_SERVER : 내부 로직 처리 실패\nINTERNAL_DB : DB 처리 실패\nPLAYER_STATE_CHANGE_FAILED : 플레이어 상태 변경 실패",
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "유저 프로필 이미지 저장하기",
"parameters": [
{
"type": "string",
"description": "accessToken",
"name": "tkn",
"in": "header",
"required": true
},
{
"type": "file",
"description": "프로필 이미지 파일",
"name": "image",
"in": "formData"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.ResUpdateProfileUser"
}
},
"400": {
"description": "Bad Request",
"schema": {}
},
"500": {
"description": "Internal Server Error",
"schema": {}
}
}
}
},
"/v0.1/users/{userID}": {
"get": {
"description": "■ errCode with 400\nPARAM_BAD : 파라미터 오류\nUSER_NOT_FOUND : 유저가 존재하지 않음\n■ errCode with 401\nINVALID_AUTH_CODE : 인증 코드 검증 실패\nTOKEN_BAD : 잘못된 토큰\nINVALID_ACCESS_TOKEN : 잘못된 액세스 토큰\n\n■ errCode with 500\nINTERNAL_SERVER : 내부 로직 처리 실패\nINTERNAL_DB : DB 처리 실패\nPLAYER_STATE_CHANGE_FAILED : 플레이어 상태 변경 실패",
Expand Down Expand Up @@ -1722,9 +1765,15 @@ const docTemplate = `{
"email": {
"type": "string"
},
"image": {
"type": "string"
},
"name": {
"type": "string"
},
"push": {
"type": "boolean"
},
"sex": {
"type": "string"
}
Expand Down Expand Up @@ -1866,6 +1915,14 @@ const docTemplate = `{
}
}
},
"response.ResUpdateProfileUser": {
"type": "object",
"properties": {
"image": {
"type": "string"
}
}
},
"response.ResV02GoogleOauth": {
"type": "object",
"properties": {
Expand Down
57 changes: 57 additions & 0 deletions src/docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -1050,6 +1050,49 @@
}
}
},
"/v0.1/users/profiles/image": {
"post": {
"description": "■ errCode with 400\nPARAM_BAD : 파라미터 오류\nUSER_NOT_FOUND : 유저가 존재하지 않음\n■ errCode with 401\nINVALID_AUTH_CODE : 인증 코드 검증 실패\nTOKEN_BAD : 잘못된 토큰\nINVALID_ACCESS_TOKEN : 잘못된 액세스 토큰\n\n■ errCode with 500\nINTERNAL_SERVER : 내부 로직 처리 실패\nINTERNAL_DB : DB 처리 실패\nPLAYER_STATE_CHANGE_FAILED : 플레이어 상태 변경 실패",
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "유저 프로필 이미지 저장하기",
"parameters": [
{
"type": "string",
"description": "accessToken",
"name": "tkn",
"in": "header",
"required": true
},
{
"type": "file",
"description": "프로필 이미지 파일",
"name": "image",
"in": "formData"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.ResUpdateProfileUser"
}
},
"400": {
"description": "Bad Request",
"schema": {}
},
"500": {
"description": "Internal Server Error",
"schema": {}
}
}
}
},
"/v0.1/users/{userID}": {
"get": {
"description": "■ errCode with 400\nPARAM_BAD : 파라미터 오류\nUSER_NOT_FOUND : 유저가 존재하지 않음\n■ errCode with 401\nINVALID_AUTH_CODE : 인증 코드 검증 실패\nTOKEN_BAD : 잘못된 토큰\nINVALID_ACCESS_TOKEN : 잘못된 액세스 토큰\n\n■ errCode with 500\nINTERNAL_SERVER : 내부 로직 처리 실패\nINTERNAL_DB : DB 처리 실패\nPLAYER_STATE_CHANGE_FAILED : 플레이어 상태 변경 실패",
Expand Down Expand Up @@ -1711,9 +1754,15 @@
"email": {
"type": "string"
},
"image": {
"type": "string"
},
"name": {
"type": "string"
},
"push": {
"type": "boolean"
},
"sex": {
"type": "string"
}
Expand Down Expand Up @@ -1855,6 +1904,14 @@
}
}
},
"response.ResUpdateProfileUser": {
"type": "object",
"properties": {
"image": {
"type": "string"
}
}
},
"response.ResV02GoogleOauth": {
"type": "object",
"properties": {
Expand Down
50 changes: 50 additions & 0 deletions src/docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -329,8 +329,12 @@ definitions:
type: string
email:
type: string
image:
type: string
name:
type: string
push:
type: boolean
sex:
type: string
type: object
Expand Down Expand Up @@ -421,6 +425,11 @@ definitions:
refreshToken:
type: string
type: object
response.ResUpdateProfileUser:
properties:
image:
type: string
type: object
response.ResV1RecommendFood:
properties:
foodNames:
Expand Down Expand Up @@ -1562,6 +1571,47 @@ paths:
summary: 유저 프로필 저장하기
tags:
- user
/v0.1/users/profiles/image:
post:
description: |-
■ errCode with 400
PARAM_BAD : 파라미터 오류
USER_NOT_FOUND : 유저가 존재하지 않음
■ errCode with 401
INVALID_AUTH_CODE : 인증 코드 검증 실패
TOKEN_BAD : 잘못된 토큰
INVALID_ACCESS_TOKEN : 잘못된 액세스 토큰
■ errCode with 500
INTERNAL_SERVER : 내부 로직 처리 실패
INTERNAL_DB : DB 처리 실패
PLAYER_STATE_CHANGE_FAILED : 플레이어 상태 변경 실패
parameters:
- description: accessToken
in: header
name: tkn
required: true
type: string
- description: 프로필 이미지 파일
in: formData
name: image
type: file
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/response.ResUpdateProfileUser'
"400":
description: Bad Request
schema: {}
"500":
description: Internal Server Error
schema: {}
summary: 유저 프로필 이미지 저장하기
tags:
- user
/v0.2/auth/google:
post:
description: |-
Expand Down
1 change: 1 addition & 0 deletions src/features/user/handler/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ func NewUserHandler(c *echo.Echo) {
NewUpdateUserHandler(c, usecase.NewUpdateUserUseCase(repository.NewUpdateUserRepository(mysql.GormMysqlDB), mysql.DBTimeOut))
NewDeleteUserHandler(c, usecase.NewDeleteUserUseCase(repository.NewDeleteUserRepository(mysql.GormMysqlDB), mysql.DBTimeOut))
NewMessageUserHandler(c, usecase.NewMessageUserUseCase(repository.NewMessageUserRepository(mysql.GormMysqlDB), mysql.DBTimeOut))
NewUpdateProfileUserHandler(c, usecase.NewUpdateProfileUserUseCase(repository.NewUpdateProfileUserRepository(mysql.GormMysqlDB), mysql.DBTimeOut))
}
65 changes: 65 additions & 0 deletions src/features/user/handler/updateProfileUserHandler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package handler

import (
"main/features/user/model/entity"
_interface "main/features/user/model/interface"

mw "main/middleware"
"main/utils"
"net/http"

"github.com/labstack/echo/v4"
)

type UpdateProfileUserHandler struct {
UseCase _interface.IUpdateProfileUserUseCase
}

func NewUpdateProfileUserHandler(c *echo.Echo, useCase _interface.IUpdateProfileUserUseCase) _interface.IUpdateProfileUserHandler {
handler := &UpdateProfileUserHandler{
UseCase: useCase,
}
c.POST("/v0.1/users/profiles/image", handler.UpdateProfile, mw.TokenChecker)
return handler
}

// 유저 프로필 이미지 저장하기
// @Router /v0.1/users/profiles/image [post]
// @Summary 유저 프로필 이미지 저장하기
// @Description
// @Description ■ errCode with 400
// @Description PARAM_BAD : 파라미터 오류
// @Description USER_NOT_FOUND : 유저가 존재하지 않음
// @Description ■ errCode with 401
// @Description INVALID_AUTH_CODE : 인증 코드 검증 실패
// @Description TOKEN_BAD : 잘못된 토큰
// @Description INVALID_ACCESS_TOKEN : 잘못된 액세스 토큰
// @Description
// @Description ■ errCode with 500
// @Description INTERNAL_SERVER : 내부 로직 처리 실패
// @Description INTERNAL_DB : DB 처리 실패
// @Description PLAYER_STATE_CHANGE_FAILED : 플레이어 상태 변경 실패
// @Param tkn header string true "accessToken"
// @Param image formData file false "프로필 이미지 파일"
// @Produce json
// @Success 200 {object} response.ResUpdateProfileUser
// @Failure 400 {object} error
// @Failure 500 {object} error
// @Tags user
func (d *UpdateProfileUserHandler) UpdateProfile(c echo.Context) error {
ctx, uID, _ := utils.CtxGenerate(c)
file, err := c.FormFile("image")
if err != nil {
return err
}
e := &entity.UpdateProfileUserEntity{
UserID: uID,
Image: file,
}
res, err := d.UseCase.UpdateProfile(ctx, e)
if err != nil {
return err
}

return c.JSON(http.StatusOK, res)
}
8 changes: 8 additions & 0 deletions src/features/user/model/entity/updateProfileUserEntity.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package entity

import "mime/multipart"

type UpdateProfileUserEntity struct {
Image *multipart.FileHeader `json:"image"`
UserID uint `json:"userID"`
}
4 changes: 4 additions & 0 deletions src/features/user/model/interface/IUserHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ type IDeleteUserHandler interface {
type IMessageUserHandler interface {
Message(c echo.Context) error
}

type IUpdateProfileUserHandler interface {
UpdateProfile(c echo.Context) error
}
4 changes: 4 additions & 0 deletions src/features/user/model/interface/IUserRepository.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ type IDeleteUserRepository interface {
type IMessageUserRepository interface {
FindOnePushToken(ctx context.Context, uID uint) (string, error)
}

type IUpdateProfileUserRepository interface {
UpdateProfileImage(ctx context.Context, uID uint, fileName string) error
}
4 changes: 4 additions & 0 deletions src/features/user/model/interface/IUserUseCase.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ type IDeleteUserUseCase interface {
type IMessageUserUseCase interface {
Message(c context.Context, uID uint, req *request.ReqMessageUser) error
}

type IUpdateProfileUserUseCase interface {
UpdateProfile(c context.Context, e *entity.UpdateProfileUserEntity) (response.ResUpdateProfileUser, error)
}
2 changes: 2 additions & 0 deletions src/features/user/model/response/getUser.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ type ResGetUser struct {
Birth string `json:"birth"`
Sex string `json:"sex"`
Email string `json:"email"`
Push *bool `json:"push"`
Image string `json:"image"`
}
5 changes: 5 additions & 0 deletions src/features/user/model/response/updateProfileUser.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package response

type ResUpdateProfileUser struct {
Image string `json:"image"`
}
4 changes: 4 additions & 0 deletions src/features/user/repository/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ type DeleteUserRepository struct {
type MessageUserRepository struct {
GormDB *gorm.DB
}

type UpdateProfileUserRepository struct {
GormDB *gorm.DB
}
27 changes: 27 additions & 0 deletions src/features/user/repository/updateProfileUserRepository.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package repository

import (
"context"
_errors "main/features/user/model/errors"
_interface "main/features/user/model/interface"
"main/utils"
"main/utils/db/mysql"

"gorm.io/gorm"
)

func NewUpdateProfileUserRepository(gormDB *gorm.DB) _interface.IUpdateProfileUserRepository {
return &UpdateProfileUserRepository{GormDB: gormDB}
}

func (d *UpdateProfileUserRepository) UpdateProfileImage(ctx context.Context, userID uint, filename string) error {
user := &mysql.Users{}
result := d.GormDB.Model(&user).Where("id = ?", userID).Update("image", filename)
if result.Error != nil {
return utils.ErrorMsg(ctx, utils.ErrInternalServer, utils.Trace(), utils.HandleError(result.Error.Error(), user), utils.ErrFromInternal)
}
if result.RowsAffected == 0 {
return utils.ErrorMsg(ctx, utils.ErrUserNotFound, utils.Trace(), utils.HandleError(_errors.ErrUserNotFound.Error(), user), utils.ErrFromClient)
}
return nil
}
Loading

0 comments on commit 293683f

Please sign in to comment.