From 8445215f2f631de00b8ec005158f51900fe7a2ef Mon Sep 17 00:00:00 2001 From: JokerTrickster Date: Sat, 30 Nov 2024 22:59:26 +0900 Subject: [PATCH] =?UTF-8?q?{improvement}=20-=20=ED=85=8C=EC=9D=B4=EB=B8=94?= =?UTF-8?q?=20=EC=88=98=EC=A0=95\n=20=20#237?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/docs.go | 12 -- src/docs/swagger.json | 12 -- src/docs/swagger.yaml | 46 ++-- .../food/model/interface/IFoodRepository.go | 4 +- .../food/model/response/historyFood.go | 8 +- .../food/repository/historyFoodRepository.go | 4 +- .../repository/recommendFoodRepository.go | 2 +- .../food/repository/saveFoodRepository.go | 2 +- .../food/repository/selectFoodRepository.go | 2 +- .../repository/v1RecommendFoodRepository.go | 2 +- .../food/usecase/dailyRecommendFoodUseCase.go | 2 +- .../food/usecase/historyFoodUseCase.go | 29 +-- src/features/food/usecase/usecase.go | 197 ++++-------------- .../food/usecase/v1.2RecommendFoodUseCase.go | 2 +- .../food/usecase/v1RecommendFoodUseCase.go | 4 +- src/utils/db/mysql/gormDB.go | 44 ++-- src/utils/db/mysql/table.sql | 134 +++++++----- 17 files changed, 184 insertions(+), 322 deletions(-) diff --git a/src/docs/docs.go b/src/docs/docs.go index 18b68c2..45fb5cb 100644 --- a/src/docs/docs.go +++ b/src/docs/docs.go @@ -1795,18 +1795,6 @@ const docTemplate = `{ }, "name": { "type": "string" - }, - "scenario": { - "type": "string" - }, - "theme": { - "type": "string" - }, - "time": { - "type": "string" - }, - "type": { - "type": "string" } } }, diff --git a/src/docs/swagger.json b/src/docs/swagger.json index 511daa9..ab249be 100644 --- a/src/docs/swagger.json +++ b/src/docs/swagger.json @@ -1784,18 +1784,6 @@ }, "name": { "type": "string" - }, - "scenario": { - "type": "string" - }, - "theme": { - "type": "string" - }, - "time": { - "type": "string" - }, - "type": { - "type": "string" } } }, diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index d6a22fb..004e8f9 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -172,6 +172,11 @@ definitions: sex: type: string type: object + request.ReqV02GoogleOauth: + properties: + token: + type: string + type: object request.ReqV12RecommendFood: properties: previousAnswer: @@ -208,11 +213,6 @@ definitions: example: 한식 type: string type: object - request.ReqV02GoogleOauth: - properties: - token: - type: string - type: object request.ReqValidatePassword: properties: code: @@ -281,14 +281,6 @@ definitions: type: string name: type: string - scenario: - type: string - theme: - type: string - time: - type: string - type: - type: string type: object response.MetaData: properties: @@ -444,6 +436,20 @@ definitions: image: type: string type: object + response.ResV12RecommendFood: + properties: + foodNames: + items: + $ref: '#/definitions/response.V12RecommendFood' + type: array + type: object + response.ResV1RecommendFood: + properties: + foodNames: + items: + $ref: '#/definitions/response.V1RecommendFood' + type: array + type: object response.ResV02GoogleOauth: properties: accessToken: @@ -462,20 +468,6 @@ definitions: userID: type: integer type: object - response.ResV12RecommendFood: - properties: - foodNames: - items: - $ref: '#/definitions/response.V12RecommendFood' - type: array - type: object - response.ResV1RecommendFood: - properties: - foodNames: - items: - $ref: '#/definitions/response.V1RecommendFood' - type: array - type: object response.V12RecommendFood: properties: amount: diff --git a/src/features/food/model/interface/IFoodRepository.go b/src/features/food/model/interface/IFoodRepository.go index a9f605b..ae73268 100644 --- a/src/features/food/model/interface/IFoodRepository.go +++ b/src/features/food/model/interface/IFoodRepository.go @@ -13,11 +13,11 @@ type IRecommendFoodRepository interface { type ISelectFoodRepository interface { FindOneFood(ctx context.Context, foodDTO *mysql.Foods) (uint, error) - InsertOneFoodHistory(ctx context.Context, foodHistoryDTO *mysql.FoodHistory) error + InsertOneFoodHistory(ctx context.Context, foodHistoryDTO *mysql.FoodHistories) error IncrementFoodRanking(ctx context.Context, foodName string, score float64) error } type IHistoryFoodRepository interface { - FindAllFoodHistory(ctx context.Context, userID uint) ([]mysql.FoodHistory, error) + FindAllFoodHistory(ctx context.Context, userID uint) ([]mysql.FoodHistories, error) FindOneFood(ctx context.Context, foodID uint) (*mysql.Foods, error) } diff --git a/src/features/food/model/response/historyFood.go b/src/features/food/model/response/historyFood.go index 09b442f..bab24f7 100644 --- a/src/features/food/model/response/historyFood.go +++ b/src/features/food/model/response/historyFood.go @@ -5,10 +5,6 @@ type ResHistoryFood struct { } type HistoryFood struct { - Name string `json:"name"` - Type string `json:"type"` - Time string `json:"time"` - Scenario string `json:"scenario"` - Theme string `json:"theme"` - Created string `json:"created"` + Name string `json:"name"` + Created string `json:"created"` } diff --git a/src/features/food/repository/historyFoodRepository.go b/src/features/food/repository/historyFoodRepository.go index 223e41a..e3ead15 100644 --- a/src/features/food/repository/historyFoodRepository.go +++ b/src/features/food/repository/historyFoodRepository.go @@ -22,8 +22,8 @@ func (g *HistoryFoodRepository) FindOneFood(ctx context.Context, foodID uint) (* return &food, nil } -func (g *HistoryFoodRepository) FindAllFoodHistory(ctx context.Context, userID uint) ([]mysql.FoodHistory, error) { - foodHistoryList := []mysql.FoodHistory{} +func (g *HistoryFoodRepository) FindAllFoodHistory(ctx context.Context, userID uint) ([]mysql.FoodHistories, error) { + foodHistoryList := []mysql.FoodHistories{} if err := g.GormDB.WithContext(ctx).Where("user_id = ?", userID).Find(&foodHistoryList).Error; err != nil { return nil, utils.ErrorMsg(ctx, utils.ErrInternalDB, utils.Trace(), utils.HandleError(_errors.ErrServerError.Error()+err.Error(), userID), utils.ErrFromMysqlDB) } diff --git a/src/features/food/repository/recommendFoodRepository.go b/src/features/food/repository/recommendFoodRepository.go index 3b7b0ec..46c0ce9 100644 --- a/src/features/food/repository/recommendFoodRepository.go +++ b/src/features/food/repository/recommendFoodRepository.go @@ -27,7 +27,7 @@ func (d *RecommendFoodRepository) FindOneUser(ctx context.Context, uID uint) (*m func (d *RecommendFoodRepository) SaveRecommendFood(ctx context.Context, foodDTO *mysql.Foods) (*mysql.Foods, error) { foods := mysql.Foods{} // 존재 여부 확인 - err := d.GormDB.WithContext(ctx).Model(&foods).Where("name = ? AND time_id = ? AND type_id = ? AND scenario_id = ? and theme_id = ? ", foodDTO.Name, foodDTO.TimeID, foodDTO.TypeID, foodDTO.ScenarioID, foodDTO.ThemeID).First(&foods).Error + err := d.GormDB.WithContext(ctx).Model(&foods).Where("name = ? ", foodDTO.Name).First(&foods).Error if err == nil { // 데이터가 이미 존재함 diff --git a/src/features/food/repository/saveFoodRepository.go b/src/features/food/repository/saveFoodRepository.go index b62aae2..d4aa35b 100644 --- a/src/features/food/repository/saveFoodRepository.go +++ b/src/features/food/repository/saveFoodRepository.go @@ -18,7 +18,7 @@ func NewSaveFoodRepository(gormDB *gorm.DB) _interface.ISaveFoodRepository { func (d *SaveFoodRepository) SaveFood(ctx context.Context, foodDTO *mysql.Foods) error { foods := mysql.Foods{} // 존재 여부 확인 - err := d.GormDB.WithContext(ctx).Model(&foods).Where("name = ? AND time_id = ? AND type_id = ? AND scenario_id = ? and theme_id = ? ", foodDTO.Name, foodDTO.TimeID, foodDTO.TypeID, foodDTO.ScenarioID, foodDTO.ThemeID).First(&foods).Error + err := d.GormDB.WithContext(ctx).Model(&foods).Where("name = ? ", foodDTO.Name).First(&foods).Error if err == nil { // 데이터가 이미 존재함 diff --git a/src/features/food/repository/selectFoodRepository.go b/src/features/food/repository/selectFoodRepository.go index fea0ce7..050576f 100644 --- a/src/features/food/repository/selectFoodRepository.go +++ b/src/features/food/repository/selectFoodRepository.go @@ -23,7 +23,7 @@ func (g *SelectFoodRepository) FindOneFood(ctx context.Context, foodDTO *mysql.F } return food.ID, nil } -func (g *SelectFoodRepository) InsertOneFoodHistory(ctx context.Context, foodHistoryDTO *mysql.FoodHistory) error { +func (g *SelectFoodRepository) InsertOneFoodHistory(ctx context.Context, foodHistoryDTO *mysql.FoodHistories) error { if err := g.GormDB.WithContext(ctx).Create(&foodHistoryDTO).Error; err != nil { return utils.ErrorMsg(ctx, utils.ErrInternalDB, utils.Trace(), utils.HandleError(_errors.ErrServerError.Error()+err.Error(), foodHistoryDTO), utils.ErrFromMysqlDB) } diff --git a/src/features/food/repository/v1RecommendFoodRepository.go b/src/features/food/repository/v1RecommendFoodRepository.go index c046096..790bcb1 100644 --- a/src/features/food/repository/v1RecommendFoodRepository.go +++ b/src/features/food/repository/v1RecommendFoodRepository.go @@ -36,7 +36,7 @@ func (d *V1RecommendFoodRepository) FindOneV1RecommendFood(ctx context.Context, func (d *V1RecommendFoodRepository) SaveRecommendFood(ctx context.Context, foodDTO *mysql.Foods) (*mysql.Foods, error) { foods := mysql.Foods{} // 존재 여부 확인 - err := d.GormDB.WithContext(ctx).Model(&foods).Where("name = ? AND time_id = ? AND type_id = ? AND scenario_id = ? and theme_id = ? ", foodDTO.Name, foodDTO.TimeID, foodDTO.TypeID, foodDTO.ScenarioID, foodDTO.ThemeID).First(&foods).Error + err := d.GormDB.WithContext(ctx).Model(&foods).Where("name = ? ", foodDTO.Name).First(&foods).Error if err == nil { // 데이터가 이미 존재함 diff --git a/src/features/food/usecase/dailyRecommendFoodUseCase.go b/src/features/food/usecase/dailyRecommendFoodUseCase.go index a7e99f6..16ae1eb 100644 --- a/src/features/food/usecase/dailyRecommendFoodUseCase.go +++ b/src/features/food/usecase/dailyRecommendFoodUseCase.go @@ -30,7 +30,7 @@ func (d *DailyRecommendFoodUseCase) DailyRecommend(c context.Context) (response. res := response.ResDailyRecommendFood{} for _, food := range foods { // 음식 이미지를 가져온다. - foodImage, err := d.Repository.FindOneFoodImage(ctx, food.FoodImageID) + foodImage, err := d.Repository.FindOneFoodImage(ctx, food.ImageID) if err != nil { return response.ResDailyRecommendFood{}, err } diff --git a/src/features/food/usecase/historyFoodUseCase.go b/src/features/food/usecase/historyFoodUseCase.go index e398e36..13d423f 100644 --- a/src/features/food/usecase/historyFoodUseCase.go +++ b/src/features/food/usecase/historyFoodUseCase.go @@ -3,11 +3,8 @@ package usecase import ( "context" - _errors "main/features/food/model/errors" _interface "main/features/food/model/interface" "main/features/food/model/response" - "main/utils" - "main/utils/db/mysql" "time" ) @@ -34,34 +31,14 @@ func (d *HistoryFoodUseCase) History(c context.Context, userID uint) (response.R foods := make([]response.HistoryFood, 0) //TODO 추후 성능 처리 개선 필요 for _, foodHistory := range foodHistoryList { - foodDTO, err := d.Repository.FindOneFood(ctx, foodHistory.FoodID) + foodDTO, err := d.Repository.FindOneFood(ctx, uint(foodHistory.FoodID)) if err != nil { return response.ResHistoryFood{}, err } - timeID, ok := mysql.GetTimeKey(foodDTO.TimeID) - if !ok { - return response.ResHistoryFood{}, utils.ErrorMsg(ctx, utils.ErrInternalServer, utils.Trace(), _errors.ErrServerError.Error()+" timeID is not valid", utils.ErrFromInternal) - } - typeID, ok := mysql.GetTypeKey(foodDTO.TypeID) - if !ok { - return response.ResHistoryFood{}, utils.ErrorMsg(ctx, utils.ErrInternalServer, utils.Trace(), _errors.ErrServerError.Error()+" typeID is not valid", utils.ErrFromInternal) - } - scenarioID, ok := mysql.GetScenarioKey(foodDTO.ScenarioID) - if !ok { - return response.ResHistoryFood{}, utils.ErrorMsg(ctx, utils.ErrInternalServer, utils.Trace(), _errors.ErrServerError.Error()+" scenarioID is not valid", utils.ErrFromInternal) - } - themeID, ok := mysql.GetThemeKey(foodDTO.ThemeID) - if !ok { - return response.ResHistoryFood{}, utils.ErrorMsg(ctx, utils.ErrInternalServer, utils.Trace(), _errors.ErrServerError.Error()+" themeID is not valid", utils.ErrFromInternal) - } food := response.HistoryFood{ - Name: foodDTO.Name, - Type: typeID, - Time: timeID, - Scenario: scenarioID, - Theme: themeID, - Created: foodHistory.CreatedAt.Format("2006-01-02 15:04:05"), + Name: foodDTO.Name, + Created: foodHistory.CreatedAt.Format("2006-01-02 15:04:05"), } foods = append(foods, food) } diff --git a/src/features/food/usecase/usecase.go b/src/features/food/usecase/usecase.go index c2373d6..0521098 100644 --- a/src/features/food/usecase/usecase.go +++ b/src/features/food/usecase/usecase.go @@ -108,92 +108,21 @@ func CreateResMetaData(typeDTO []mysql.Types, timeDTO []mysql.Times, scenarioDTO } func CreateSelectFoodDTO(entity entity.SelectFoodEntity) *mysql.Foods { - var err error - typeID := 0 - timeID := 0 - secnarioID := 0 - themeID := 0 - - if entity.Types != "" { - typeID, err = mysql.GetTypeID(entity.Types) - if err != nil { - fmt.Println(err) - } - } - if entity.Times != "" { - timeID, err = mysql.GetTimeID(entity.Times) - if err != nil { - fmt.Println(err) - } - } - if entity.Scenarios != "" { - secnarioID, err = mysql.GetScenarioID(entity.Scenarios) - if err != nil { - fmt.Println(err) - } - } - if entity.Themes != "" { - themeID, err = mysql.GetThemeID(entity.Themes) - if err != nil { - fmt.Println(err) - } - } - return &mysql.Foods{ - TypeID: typeID, - TimeID: timeID, - ScenarioID: secnarioID, - ThemeID: themeID, - Name: entity.Name, + Name: entity.Name, } } -func CreateFoodHistoryDTO(foodID, userID uint, name string) *mysql.FoodHistory { - return &mysql.FoodHistory{ - FoodID: foodID, - UserID: userID, - Name: name, +func CreateFoodHistoryDTO(foodID, userID uint, name string) *mysql.FoodHistories { + return &mysql.FoodHistories{ + FoodID: int(foodID), + UserID: int(userID), } } func CreateRecommendFoodDTO(entity entity.RecommendFoodEntity, foodName string, foodImageID int) *mysql.Foods { - var err error - typeID := 0 - timeID := 0 - secnarioID := 0 - themeID := 0 - - if entity.Types != "" { - typeID, err = mysql.GetTypeID(entity.Types) - if err != nil { - fmt.Println(err) - } - } - if entity.Times != "" { - timeID, err = mysql.GetTimeID(entity.Times) - if err != nil { - fmt.Println(err) - } - } - if entity.Scenarios != "" { - secnarioID, err = mysql.GetScenarioID(entity.Scenarios) - if err != nil { - fmt.Println(err) - } - } - if entity.Themes != "" { - themeID, err = mysql.GetThemeID(entity.Themes) - if err != nil { - fmt.Println(err) - } - } - return &mysql.Foods{ - TypeID: typeID, - TimeID: timeID, - ScenarioID: secnarioID, - ThemeID: themeID, - Name: foodName, - FoodImageID: foodImageID, + Name: foodName, + ImageID: foodImageID, } } @@ -264,44 +193,9 @@ func CreateSaveFoodImageDTO(food request.SaveFood) *mysql.FoodImages { } func CreateSaveFoodDTO(food request.SaveFood, foodImageID int) *mysql.Foods { - var err error - typeID := 0 - timeID := 0 - secnarioID := 0 - themeID := 0 - - if food.Types != "" { - typeID, err = mysql.GetTypeID(food.Types) - if err != nil { - fmt.Println(err) - } - } - if food.Times != "" { - timeID, err = mysql.GetTimeID(food.Times) - if err != nil { - fmt.Println(err) - } - } - if food.Scenarios != "" { - secnarioID, err = mysql.GetScenarioID(food.Scenarios) - if err != nil { - fmt.Println(err) - } - } - if food.Themes != "" { - themeID, err = mysql.GetThemeID(food.Themes) - if err != nil { - fmt.Println(err) - } - } - return &mysql.Foods{ - TypeID: typeID, - TimeID: timeID, - ScenarioID: secnarioID, - ThemeID: themeID, - Name: food.Name, - FoodImageID: foodImageID, + Name: food.Name, + ImageID: foodImageID, } } @@ -405,21 +299,39 @@ func CreateRecommendQuery(entity entity.V1RecommendFoodEntity) string { return query } func CreateV12RecommendQuery(entity entity.V12RecommendFoodEntity) string { - var query string = "SELECT * FROM foods WHERE " + // Base query + query := ` + SELECT DISTINCT f.name + FROM foods f + JOIN food_categories fc ON f.id = fc.food_id + JOIN categories c ON fc.category_id = c.id + WHERE 1=1` + + // 조건 추가 if entity.Types != "" { - query += fmt.Sprintf("type_id = (SELECT id FROM types WHERE name = '%s') AND ", entity.Types) - } - if entity.Times != "" { - query += fmt.Sprintf("time_id = (SELECT id FROM times WHERE name = '%s') AND ", entity.Times) + query += " AND c.name = '" + entity.Types + "' AND c.type_id = (SELECT id FROM category_types WHERE name = 'type')" } + if entity.Scenarios != "" { - query += fmt.Sprintf("scenario_id = (SELECT id FROM scenarios WHERE name = '%s') AND ", entity.Scenarios) + query += " AND c.name = '" + entity.Scenarios + "' AND c.type_id = (SELECT id FROM category_types WHERE name = 'scenario')" + } + + if entity.Times != "" { + query += " AND c.name = '" + entity.Times + "' AND c.type_id = (SELECT id FROM category_types WHERE name = 'time')" } + if entity.Themes != "" { - query += fmt.Sprintf("theme_id = (SELECT id FROM themes WHERE name = '%s') AND ", entity.Themes) + query += " AND c.name = '" + entity.Themes + "' AND c.type_id = (SELECT id FROM category_types WHERE name = 'theme')" } - query = strings.TrimSuffix(query, " AND ") + if entity.PreviousAnswer != "" { + previous := "'" + strings.Join(strings.Split(entity.PreviousAnswer, " "), "','") + "'" + query += " AND f.name NOT IN (" + previous + ")" + } + + // 랜덤 정렬 및 결과 제한 + query += " ORDER BY RAND() LIMIT 1" + return query } @@ -432,44 +344,9 @@ func CreateV1RecommendFoodImageDTO(entity entity.V1RecommendFoodEntity, foodName } func CreateV1RecommendFoodDTO(entity entity.V1RecommendFoodEntity, foodName string, foodImageID int) *mysql.Foods { - var err error - typeID := 0 - timeID := 0 - secnarioID := 0 - themeID := 0 - - if entity.Types != "" { - typeID, err = mysql.GetTypeID(entity.Types) - if err != nil { - fmt.Println(err) - } - } - if entity.Times != "" { - timeID, err = mysql.GetTimeID(entity.Times) - if err != nil { - fmt.Println(err) - } - } - if entity.Scenarios != "" { - secnarioID, err = mysql.GetScenarioID(entity.Scenarios) - if err != nil { - fmt.Println(err) - } - } - if entity.Themes != "" { - themeID, err = mysql.GetThemeID(entity.Themes) - if err != nil { - fmt.Println(err) - } - } - return &mysql.Foods{ - TypeID: typeID, - TimeID: timeID, - ScenarioID: secnarioID, - ThemeID: themeID, - Name: foodName, - FoodImageID: foodImageID, + Name: foodName, + ImageID: foodImageID, } } diff --git a/src/features/food/usecase/v1.2RecommendFoodUseCase.go b/src/features/food/usecase/v1.2RecommendFoodUseCase.go index 0edbd5a..401de8b 100644 --- a/src/features/food/usecase/v1.2RecommendFoodUseCase.go +++ b/src/features/food/usecase/v1.2RecommendFoodUseCase.go @@ -30,7 +30,7 @@ func (d *V12RecommendFoodUseCase) V12Recommend(c context.Context, e entity.V12Re return response.ResV12RecommendFood{}, err } //food image ID로 이미지 URL을 가져온다. - image, err := d.Repository.FindOneFoodImage(ctx, food.FoodImageID) + image, err := d.Repository.FindOneFoodImage(ctx, food.ImageID) if err != nil { return response.ResV12RecommendFood{}, err } diff --git a/src/features/food/usecase/v1RecommendFoodUseCase.go b/src/features/food/usecase/v1RecommendFoodUseCase.go index cd3a796..0ff6d19 100644 --- a/src/features/food/usecase/v1RecommendFoodUseCase.go +++ b/src/features/food/usecase/v1RecommendFoodUseCase.go @@ -2,7 +2,6 @@ package usecase import ( "context" - "fmt" "main/features/food/model/entity" _errors "main/features/food/model/errors" "main/features/food/model/response" @@ -92,7 +91,6 @@ func (d *V1RecommendFoodUseCase) V1Recommend(c context.Context, e entity.V1Recom if err != nil { return response.ResV1RecommendFood{}, err } - fmt.Println(foodName, nutrition) foodImageDTO := CreateV1RecommendFoodImageDTO(e, foodName) foodImage, err := d.Repository.FindOneOrCreateFoodImage(ctx, foodImageDTO) @@ -131,7 +129,7 @@ func (d *V1RecommendFoodUseCase) V1Recommend(c context.Context, e entity.V1Recom return response.ResV1RecommendFood{}, err } //food image ID로 이미지 URL을 가져온다. - image, err := d.Repository.FindOneFoodImage(ctx, food.FoodImageID) + image, err := d.Repository.FindOneFoodImage(ctx, food.ImageID) if err != nil { return response.ResV1RecommendFood{}, err } diff --git a/src/utils/db/mysql/gormDB.go b/src/utils/db/mysql/gormDB.go index fb0ab37..92b54ee 100644 --- a/src/utils/db/mysql/gormDB.go +++ b/src/utils/db/mysql/gormDB.go @@ -115,22 +115,6 @@ type Users struct { Image string `json:"image" gorm:"column:image"` } -type Foods struct { - gorm.Model - Name string `json:"name" gorm:"column:name"` - FoodImageID int `json:"foodImageID" gorm:"column:food_image_id"` - ScenarioID int `json:"scenarioID" gorm:"column:scenario_id"` - TimeID int `json:"timeID" gorm:"column:time_id"` - TypeID int `json:"typeID" gorm:"column:type_id"` - ThemeID int `json:"themeID" gorm:"column:theme_id"` -} -type FoodHistory struct { - gorm.Model - UserID uint `json:"userID" gorm:"column:user_id"` - FoodID uint `json:"foodID" gorm:"column:food_id"` - Name string `json:"name" gorm:"column:name"` -} - type MetaTables struct { gorm.Model TableName string `json:"tableName" gorm:"column:table_name"` @@ -199,3 +183,31 @@ type UserTokens struct { UserID uint `json:"userID" gorm:"column:user_id"` Token string `json:"token" gorm:"column:token"` } + +type Foods struct { + gorm.Model + Name string `json:"name" gorm:"column:name"` + ImageID int `json:"imageID" gorm:"column:image_id"` +} +type CategoryTypes struct { + gorm.Model + Name string `json:"name" gorm:"column:name"` +} + +type Categories struct { + gorm.Model + Name string `json:"name" gorm:"column:name"` + TypeID int `json:"typeID" gorm:"column:type_id"` +} + +type FoodCategories struct { + gorm.Model + FoodID int `json:"foodID" gorm:"column:food_id"` + CategoryID int `json:"categoryID" gorm:"column:category_id"` +} + +type FoodHistories struct { + gorm.Model + UserID int `json:"userID" gorm:"column:user_id"` + FoodID int `json:"foodID" gorm:"column:food_id"` +} diff --git a/src/utils/db/mysql/table.sql b/src/utils/db/mysql/table.sql index 94809d3..1f5e423 100644 --- a/src/utils/db/mysql/table.sql +++ b/src/utils/db/mysql/table.sql @@ -46,16 +46,6 @@ CREATE TABLE user_auths ( ); -CREATE TABLE food_images ( - id INT AUTO_INCREMENT PRIMARY KEY, - name VARCHAR(255) NOT NULL UNIQUE, -- 음식 이름으로 이미지 참조 - image VARCHAR(255) DEFAULT 'food_default.png', - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - deleted_at TIMESTAMP NULL DEFAULT NULL -); - - -- 메타 데이터 테이블 CREATE TABLE meta_tables ( id INT AUTO_INCREMENT PRIMARY KEY, @@ -112,47 +102,8 @@ CREATE TABLE themes( description VARCHAR(255) ); --- 음식 선택했을 때 저장해야 된다. user_id = 1, time_id = 1, type_id = 1, scenario_id = 1, name = '김치찌개' -CREATE TABLE foods ( - id INT AUTO_INCREMENT PRIMARY KEY, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - deleted_at TIMESTAMP NULL DEFAULT NULL, - name VARCHAR(255) NOT NULL, - food_image_id INT, - time_id INT, - type_id INT, - scenario_id INT, - theme_id INT, - FOREIGN KEY (food_image_id) REFERENCES food_images(id) -); --- 영양소 테이블 용량, 칼로리, 탄수화물, 단백질, 지방 -create table nutrients ( - id INT AUTO_INCREMENT PRIMARY KEY, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - deleted_at TIMESTAMP NULL DEFAULT NULL, - food_name varchar(255) UNIQUE, - amount varchar(255), - kcal DECIMAL(10, 2), - carbohydrate DECIMAL(10, 2), - protein DECIMAL(10, 2), - fat DECIMAL(10, 2) -); --- 유저에게 추천된 음식을 저장해야 된다. -CREATE TABLE food_histories ( - id INT AUTO_INCREMENT PRIMARY KEY, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - deleted_at TIMESTAMP NULL DEFAULT NULL, - food_id INT, - user_id INT, - name varchar(255), - FOREIGN KEY (food_id) REFERENCES foods(id), - FOREIGN KEY (user_id) REFERENCES users(id) -); -- 신고 테이블 CREATE TABLE reports ( @@ -182,7 +133,6 @@ INSERT INTO scenarios (name, description,image) VALUES ('연인', '연인','scen -- themes 테이블에 스트레스 해소, 피로 회복, 기분 전환, 제철 음식, 영양식, 특별한 날 순으로 저장하는 sql 문 만들어줘 INSERT INTO themes (name, description,image) VALUES ('스트레스 해소', '스트레스 해소','themes/stress.png'), ('해장', '해장','themes/hangover.png'),('피로 회복', '피로 회복','themes/fatigue recovery.png'), ('다이어트', '다이어트','themes/diet.png'), ('제철 음식', '제철 음식','themes/seasonal food.png'); - CREATE TABLE user_tokens ( id INT AUTO_INCREMENT PRIMARY KEY, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, @@ -192,3 +142,87 @@ CREATE TABLE user_tokens ( token varchar(1000), FOREIGN KEY (user_id) REFERENCES users(id) ); + + + + + + +-- 영양소 테이블 용량, 칼로리, 탄수화물, 단백질, 지방 +create table nutrients ( + id INT AUTO_INCREMENT PRIMARY KEY, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + deleted_at TIMESTAMP NULL DEFAULT NULL, + food_name varchar(255) UNIQUE, + amount varchar(255), + kcal DECIMAL(10, 2), + carbohydrate DECIMAL(10, 2), + protein DECIMAL(10, 2), + fat DECIMAL(10, 2) +); + +CREATE TABLE food_images ( + id INT AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(255) NOT NULL UNIQUE, -- 음식 이름으로 이미지 참조 + image VARCHAR(255) DEFAULT 'food_default.png', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + deleted_at TIMESTAMP NULL DEFAULT NULL +); + +-- 음식 선택 개선 + +CREATE TABLE foods ( + id INT AUTO_INCREMENT PRIMARY KEY, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + deleted_at TIMESTAMP NULL DEFAULT NULL, + name VARCHAR(255) NOT NULL, + image_id INT, + FOREIGN KEY (image_id) REFERENCES food_images(id) +); +-- INSERT INTO foods (name, food_image_id) VALUES ('김치찌개', NULL); + +CREATE TABLE category_types ( + id INT AUTO_INCREMENT PRIMARY KEY, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + deleted_at TIMESTAMP NULL DEFAULT NULL, + name VARCHAR(50) NOT NULL UNIQUE COMMENT '카테고리 유형' +); +-- INSERT INTO category_types (name) VALUES ('time'), ('type'), ('scenario'), ('theme'); + +CREATE TABLE categories ( + id INT AUTO_INCREMENT PRIMARY KEY, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + deleted_at TIMESTAMP NULL DEFAULT NULL, + name VARCHAR(255) NOT NULL UNIQUE, + type_id INT NOT NULL, + FOREIGN KEY (type_id) REFERENCES category_types(id) +); +-- INSERT INTO categories (name, type_id) VALUES ('아침', 1), ('한식', 2); + + +CREATE TABLE food_categories ( + id INT AUTO_INCREMENT PRIMARY KEY, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + deleted_at TIMESTAMP NULL DEFAULT NULL, + food_id INT NOT NULL, + category_id INT NOT NULL, + FOREIGN KEY (food_id) REFERENCES foods(id) ON DELETE CASCADE, + FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE CASCADE +); +-- INSERT INTO food_categories (food_id, category_id) VALUES (1, 1), -- 김치찌개는 아침 (1, 2), -- 김치찌개는 한식 (1, 3); -- 김치찌개는 가족 + +CREATE TABLE food_histories ( + id INT AUTO_INCREMENT PRIMARY KEY, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + deleted_at TIMESTAMP NULL DEFAULT NULL, + user_id INT NOT NULL, -- 선택한 유저 ID + food_id INT NOT NULL, -- 선택된 음식 ID + FOREIGN KEY (food_id) REFERENCES foods(id) ON DELETE CASCADE +); \ No newline at end of file