package model import ( "crawler/config" "crawler/service" "database/sql" "encoding/json" "fmt" "reflect" ) type G2AProductModel struct { G2AProductParams G2AProductResult G2AProduct } // 검색 변수들 type G2AProductParams struct { Page int `json:"page"` ID string `json:"id"` MinQty int `json:"minQty"` MinPriceFrom int `json:"minPriceFrom"` MinPriceTo int `json:"minPriceTo"` IncludeOutOfStock string `json:"includeOutOfStock"` UpdatedAtFrom string `json:"updatedAtFrom"` UpdatedAtTo string `json:"updatedAtTo"` } // G2A 상품 조회 결과 type G2AProductResult struct { Total int `json:"total"` Page int `json:"page"` Docs []G2AProduct `json:"docs"` } // G2A 상품 정보 type G2AProduct struct { ID string `json:"id"` Name string `json:"name"` IsTest int Type string `json:"type"` Slug string `json:"slug"` Qty int `json:"qty"` MinPrice float64 `json:"minPrice"` RetailMinPrice float64 `json:"retail_min_price"` RetailMinBasePrice float64 `json:"retailMinBasePrice"` Thumbnail string `json:"thumbnail"` SmallImage string `json:"smallImage"` CoverImage string `json:"coverImage"` Images []string `json:"images"` UpdatedAt string `json:"updated_at"` ReleaseDate string `json:"release_date"` Region string `json:"region"` Developer string `json:"developer"` Publisher string `json:"publisher"` Platform string `json:"platform"` PriceLimit PriceLimit `json:"priceLimit"` Restrictions Restrictions `json:"restrictions"` Requirements Requirements `json:"requirements"` Videos []Videos `json:"videos"` Categories []Categories `json:"categories"` } type PriceLimit struct { Min float64 `json:"min"` Max float64 `json:"max"` } type Restrictions struct { PegiViolence bool `json:"pegi_violence"` PegiProfanity bool `json:"pegi_profanity"` PegiDiscrimination bool `json:"pegi_discrimination"` PegiDrugs bool `json:"pegi_drugs"` PegiFear bool `json:"pegi_fear"` PegiGambling bool `json:"pegi_gambling"` PegiOnline bool `json:"pegi_online"` PegiSex bool `json:"pegi_sex"` } type Requirements struct { Minimal Spec `json:"minimal"` Recommended Spec `json:"recommended"` } type Spec struct { ReqProcessor string `json:"reqprocessor"` ReqGraphics string `json:"reqgraphics"` ReqMemory string `json:"reqmemory"` ReqDiskSpace string `json:"reqdiskspace"` ReqSystem string `json:"reqsystem"` ReqOther string `json:"reqother"` } type Videos struct { Type string `json:"type"` Url string `json:"url"` } type Categories struct { ID int `json:"id"` Name string `json:"name"` } func (this *G2AProductModel) IsExists(id string) bool { var ( db = service.DB_PLAYR conn = db.SQLDB query = "SELECT IF(COUNT(*) <= 0, 0, 1) AS `exists` FROM tb_g2a_product WHERE id = ?;" exists = false ) err := conn.QueryRow(query, id).Scan(&exists) if err != nil { db.SetErrorLog(err, query) return exists } db.SetGeneralLog(config.GL_ACTION_SELECT, query, "select exists g2a") return exists } func (this *G2AProductModel) Insert(list []G2AProduct) error { if len(list) == 0 { return fmt.Errorf("Product 상품이 존재하지 않습니다.") } var ( db = service.DB_PLAYR conn = db.SQLDB query = ` INSERT INTO tb_g2a_product ( id, name, is_test, type, slug, qty, min_price, retail_min_price, retail_min_base_price, thumbnail, small_image, cover_image, images, updated_at, release_date, region, developer, publisher, platform, price_limit, restrictions, requirements, videos, categories, created_at ) VALUES ` vals = []interface{}{} dup string ) for _, row := range list { query += `(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW()),` data := this.DataFilter(row) vals = append(vals, data["id"], data["name"], data["IsTest"], data["type"], data["slug"], data["qty"], data["minPrice"], data["retail_min_price"], data["retailMinBasePrice"], data["thumbnail"], data["smallImage"], data["coverImage"], data["images"], data["updated_at"], data["release_date"], data["region"], data["developer"], data["publisher"], data["platform"], data["priceLimit"], data["restrictions"], data["requirements"], data["videos"], data["categories"], ) dup += `name = VALUES(name), is_test = VALUES(is_test), type = VALUES(type), slug = VALUES(slug), qty = VALUES(qty), min_price = VALUES(min_price), retail_min_price = VALUES(retail_min_price), retail_min_base_price = VALUES(retail_min_base_price), thumbnail = VALUES(thumbnail), small_image = VALUES(small_image), cover_image = VALUES(cover_image), images = VALUES(images), updated_at = VALUES(updated_at), release_date = VALUES(release_date), region = VALUES(region), developer = VALUES(developer), publisher = VALUES(publisher), platform = VALUES(platform), price_limit = VALUES(price_limit), restrictions = VALUES(restrictions), requirements = VALUES(requirements), videos = VALUES(videos), categories = VALUES(categories),` } query = query[0 : len(query)-1] dup = dup[0 : len(dup)-1] query += `ON DUPLICATE KEY UPDATE ` + dup stmt, err := conn.Prepare(query) if err != nil { db.SetErrorLog(err, query) return err } defer stmt.Close() _, err = stmt.Exec(vals...) if err != nil { db.SetErrorLog(err, query) return err } db.SetGeneralLog(config.GL_ACTION_WRITE, query, "insert g2a products") return nil } func (this *G2AProductModel) Update(row G2AProduct) error { var ( db = service.DB_PLAYR conn = db.SQLDB query = ` UPDATE tb_g2a_product SET name = ?, is_test = ?, type = ?, slug = ?, qty = ?, min_price = ?, retail_min_price = ?, retail_min_base_price = ?, thumbnail = ?, small_image = ?, cover_image = ?, images = ?, updated_at = ?, release_date = ?, region = ?, developer = ?, publisher = ?, platform = ?, price_limit = ?, restrictions = ?, requirements = ?, videos = ?, categories = ?, created_at = NOW() WHERE id = ?; ` data = this.DataFilter(row) ) _, err := conn.Exec(query, data["name"], data["IsTest"], data["type"], data["slug"], data["qty"], data["minPrice"], data["retail_min_price"], data["retailMinBasePrice"], data["thumbnail"], data["smallImage"], data["coverImage"], data["images"], data["updated_at"], data["release_date"], data["region"], data["developer"], data["publisher"], data["platform"], data["priceLimit"], data["restrictions"], data["requirements"], data["videos"], data["categories"], data["id"]) if err != nil { db.SetErrorLog(err, query) return err } db.SetGeneralLog(config.GL_ACTION_MODIFY, query, "update g2a product info") return nil } func (this *G2AProductModel) Info(id int) (G2AProduct, error) { var ( db = service.DB_PLAYR conn = db.SQLDB query = `SELECT id, name, qty, min_price, retail_min_price, retail_min_base_price FROM tb_g2a_product WHERE id = ?;` info G2AProduct ) err := conn.QueryRow(query, id).Scan( &info.ID, &info.Name, &info.Qty, &info.MinPrice, &info.RetailMinPrice, &info.RetailMinBasePrice, ) if err != nil && err != sql.ErrNoRows { db.SetErrorLog(err, query) return info, err } db.SetGeneralLog(config.GL_ACTION_SELECT, query, "select g2a product info") return info, nil } func (this *G2AProductModel) DataFilter(product G2AProduct) map[string]interface{} { var row = map[string]any{} data, _ := json.Marshal(product) _ = json.Unmarshal(data, &row) for k, v := range row { switch c := v.(type) { case string: if c == "" { row[k] = nil } case int, int32, int64: if c == 0 { row[k] = 0 } case float32, float64: if c == 0 || c == nil || c == "" { row[k] = 0.0 } case []string: if len(c) == 0 { row[k] = nil } else { s, _ := json.Marshal(c) row[k] = string(s) } case nil: row[k] = nil case []interface{}: if c == nil || len(c) == 0 { row[k] = nil } else { s, _ := json.Marshal(c) row[k] = string(s) } case map[string]interface{}: if c == nil || len(c) == 0 { row[k] = nil } else { s, _ := json.Marshal(c) row[k] = string(s) } default: fmt.Println(k) fmt.Println(reflect.TypeOf(c)) } } return row }