package view import ( "errors" "time" "github.com/metarare/metarare_api/common" "github.com/metarare/metarare_api/models" "gorm.io/gorm" ) type CollectionInfo struct { ID uint64 `json:"id"` Name string `json:"name"` Symbol string `json:"symbol"` Description string `json:"description"` ContractAddress string `json:"contract_address"` ThumbnailImage string `json:"thumbnail_image"` CoverImage string `json:"cover_image"` IsOfficial bool `json:"is_official"` Status string `json:"status"` CuratingNumber int `json:"curating_number"` UserName string `json:"user_name"` Items int64 `json:"items"` HighestSalePrice float64 `json:"highest_sale_price"` MarketCap float64 `json:"market_cap"` TotalVolume float64 `json:"total_volume"` TotalLikeCount uint32 `json:"total_like_count"` RecentTradingDay time.Time `json:"recent_trading_day"` IsOwner bool `json:"is_owner"` } func GetCollectionInfomation(db *gorm.DB, ids []uint64, ownerID uint64) ([]CollectionInfo, error) { _res := []CollectionInfo{} _err := GetCollectionInfo(db, ownerID).Where("collection.id in (?) AND collection.status = 'visible'", ids).Order("collection.id desc").Find(&_res).Error if errors.Is(_err, gorm.ErrRecordNotFound) { return nil, _err } err, _currency := common.UpdateCurrency(db) if err != nil { return nil, err } for idx, item := range _res { _res[idx].Items = GetCollectionItemCount(db, item.ID) _res[idx].HighestSalePrice = GetHighestPrice(db, _currency, item.ID) _res[idx].MarketCap = GetMarketCap(db, _currency, item.ID) _res[idx].TotalVolume = GetTotalVolume(db, _currency, item.ID) } return _res, nil } func GetCollectionInfo(db *gorm.DB, userID uint64) *gorm.DB { querySet := db.Select(`collection.id, collection.status, collection.symbol, collection_profile.name, collection_profile.thumbnail_image, collection_profile.cover_image, collection.is_official, user_profile.name AS user_name, collection.curating_number, collection_profile.description, collection.contract_address, IF(user_profile.user_id = ?, true, false) AS is_owner`, userID).Table("collection"). Joins("INNER JOIN collection_profile ON collection_profile.collection_id = collection.id"). Joins("INNER JOIN user_wallet ON user_wallet.address = collection.owner_address"). Joins("INNER JOIN user_profile ON user_profile.user_id = user_wallet.user_id") return querySet } func GetCollectionItemCount(db *gorm.DB, collectionID uint64) int64 { var count int64 db.Table("collection"). Joins("INNER JOIN token ON token.collection_id = collection.id"). Where("token.deleted_at IS NULL AND collection_id = ?", collectionID).Count(&count) return count } func TokenBaseCollectionQuery(db *gorm.DB, id uint64) *gorm.DB { querySet := db.Select("token.*").Table("collection"). Joins("INNER JOIN token ON token.collection_id = collection.id"). Where("token.lastest_price IS NOT NULL AND token.lastest_currency IS NOT NULL AND collection.id = ?", id) return querySet } func GetHighestPrice(db *gorm.DB, currencyPrice models.CurrencyPrice, collectionID uint64) float64 { token := []models.Token{} if err := TokenBaseCollectionQuery(db, collectionID).Find(&token).Error; err != nil { return 0 } else if len(token) == 0 { return 0 } highestPrice := 0.0 for _, item := range token { _compare := 0.0 if item.LastestCurrency.String == "eth" { _compare = currencyPrice.Eth } else if item.LastestCurrency.String == "mf" { _compare = currencyPrice.Mf } else if item.LastestCurrency.String == "mr" { _compare = currencyPrice.Mr } if highestPrice < (item.LastestPrice.Float64 * _compare) { highestPrice = (item.LastestPrice.Float64 * _compare) } } return highestPrice } func GetMarketCap(db *gorm.DB, currencyPrice models.CurrencyPrice, collectionID uint64) float64 { token := []models.Token{} if err := TokenBaseCollectionQuery(db, collectionID).Find(&token).Error; err != nil { return 0 } else if len(token) == 0 { return 0 } highestPrice := 0.0 for _, item := range token { _compare := 0.0 if item.LastestCurrency.String == "eth" { _compare = currencyPrice.Eth } else if item.LastestCurrency.String == "mf" { _compare = currencyPrice.Mf } else if item.LastestCurrency.String == "mr" { _compare = currencyPrice.Mr } highestPrice += (item.LastestPrice.Float64 * _compare) } return highestPrice } func GetTotalVolume(db *gorm.DB, currencyPrice models.CurrencyPrice, collectionID uint64) float64 { sale := []models.Sale{} if err := db.Select("sale.*").Table("collection"). Joins("INNER JOIN token ON token.collection_id = collection.id"). Joins("INNER JOIN sale ON sale.token_id = token.id"). Where("collection.id = ? AND collection.status != 'cancel'", collectionID).Find(&sale).Error; err != nil { return 0 } else if len(sale) == 0 { return 0 } highestPrice := 0.0 for _, item := range sale { _compare := 0.0 if item.Currency == "eth" { _compare = currencyPrice.Eth } else if item.Currency == "mf" { _compare = currencyPrice.Mf } else if item.Currency == "mr" { _compare = currencyPrice.Mr } highestPrice += (item.Price.Float64 * _compare) } return highestPrice } func GetRecentTradingDate(db *gorm.DB, collectionID uint64) time.Time { _t := models.Token{} token := []models.Token{} //NOTE x update_at이 바뀌는건 판매 후 최근 가격에 값일 들어갈 때. err := db.Where("collection_id = ? AND lastest_price IS NOT NULL", collectionID).Find(&token).Error if errors.Is(err, gorm.ErrRecordNotFound) { return _t.CreatedAt } else if len(token) == 0 { return _t.CreatedAt } res := time.Date(2019, 1, 12, 0, 0, 0, 0, time.UTC) for idx, item := range token { if idx == 0 { res = item.UpdatedAt } else if res.Before(item.UpdatedAt) { res = item.UpdatedAt } } return res } func GetTotalLikeCount(db *gorm.DB, collectionID uint64) uint32 { token := []models.Token{} err := db.Where("collection_id = ?", collectionID).Find(&token).Error if errors.Is(err, gorm.ErrRecordNotFound) { return 0 } else if len(token) == 0 { return 0 } var totalCount uint32 for _, item := range token { totalCount += item.LikeCount } return totalCount }