diff options
| author | Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> | 2024-07-10 21:27:31 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-10 21:27:31 +0300 |
| commit | 50f7bf57f45a26362376be37e89128bac9195edc (patch) | |
| tree | 150b82f74797512e2bd6970dfe702d447ffc256e | |
| parent | docs: update maps table ddl (#168) (diff) | |
| download | lphub-50f7bf57f45a26362376be37e89128bac9195edc.tar.gz lphub-50f7bf57f45a26362376be37e89128bac9195edc.tar.bz2 lphub-50f7bf57f45a26362376be37e89128bac9195edc.zip | |
feat: return portal counts for each cat in chapter select (#175)
| -rw-r--r-- | backend/handlers/map.go | 56 | ||||
| -rw-r--r-- | backend/models/models.go | 9 | ||||
| -rw-r--r-- | docs/docs.go | 28 | ||||
| -rw-r--r-- | docs/swagger.json | 28 | ||||
| -rw-r--r-- | docs/swagger.yaml | 19 |
5 files changed, 130 insertions, 10 deletions
diff --git a/backend/handlers/map.go b/backend/handlers/map.go index 8104243..3166d1d 100644 --- a/backend/handlers/map.go +++ b/backend/handlers/map.go | |||
| @@ -27,8 +27,8 @@ type ChaptersResponse struct { | |||
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | type ChapterMapsResponse struct { | 29 | type ChapterMapsResponse struct { |
| 30 | Chapter models.Chapter `json:"chapter"` | 30 | Chapter models.Chapter `json:"chapter"` |
| 31 | Maps []models.MapShort `json:"maps"` | 31 | Maps []models.MapSelect `json:"maps"` |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | type GameMapsResponse struct { | 34 | type GameMapsResponse struct { |
| @@ -479,20 +479,62 @@ func FetchChapterMaps(c *gin.Context) { | |||
| 479 | return | 479 | return |
| 480 | } | 480 | } |
| 481 | var response ChapterMapsResponse | 481 | var response ChapterMapsResponse |
| 482 | rows, err := database.DB.Query(`SELECT m.id, m.name, c.name, m.is_disabled, m.image, MIN(mh.score_count) FROM maps m INNER JOIN chapters c ON m.chapter_id = c.id INNER JOIN map_history mh ON m.id = mh.map_id WHERE chapter_id = $1 GROUP BY m.id, c.name ORDER BY m.id;`, chapterID) | 482 | rows, err := database.DB.Query(` |
| 483 | SELECT | ||
| 484 | m.id, | ||
| 485 | m.name AS map_name, | ||
| 486 | c.name AS chapter_name, | ||
| 487 | m.is_disabled, | ||
| 488 | m.image, | ||
| 489 | cat.id, | ||
| 490 | cat.name, | ||
| 491 | mh.min_score_count AS score_count | ||
| 492 | FROM | ||
| 493 | maps m | ||
| 494 | INNER JOIN | ||
| 495 | chapters c ON m.chapter_id = c.id | ||
| 496 | INNER JOIN | ||
| 497 | game_categories gc ON gc.game_id = c.game_id | ||
| 498 | INNER JOIN | ||
| 499 | categories cat ON cat.id = gc.category_id | ||
| 500 | INNER JOIN | ||
| 501 | ( | ||
| 502 | SELECT | ||
| 503 | map_id, | ||
| 504 | category_id, | ||
| 505 | MIN(score_count) AS min_score_count | ||
| 506 | FROM | ||
| 507 | map_history | ||
| 508 | GROUP BY | ||
| 509 | map_id, | ||
| 510 | category_id | ||
| 511 | ) mh ON m.id = mh.map_id AND gc.category_id = mh.category_id | ||
| 512 | WHERE | ||
| 513 | m.chapter_id = $1 | ||
| 514 | ORDER BY | ||
| 515 | m.id, gc.category_id, mh.min_score_count ASC; | ||
| 516 | `, chapterID) | ||
| 483 | if err != nil { | 517 | if err != nil { |
| 484 | c.JSON(http.StatusOK, models.ErrorResponse(err.Error())) | 518 | c.JSON(http.StatusOK, models.ErrorResponse(err.Error())) |
| 485 | return | 519 | return |
| 486 | } | 520 | } |
| 487 | var maps []models.MapShort | 521 | var maps []models.MapSelect |
| 488 | var chapterName string | 522 | var chapterName string |
| 523 | var lastMapID int | ||
| 489 | for rows.Next() { | 524 | for rows.Next() { |
| 490 | var mapShort models.MapShort | 525 | var mapShort models.MapSelect |
| 491 | if err := rows.Scan(&mapShort.ID, &mapShort.Name, &chapterName, &mapShort.IsDisabled, &mapShort.Image, &mapShort.PortalCount); err != nil { | 526 | var categoryPortal models.CategoryPortal |
| 527 | if err := rows.Scan(&mapShort.ID, &mapShort.Name, &chapterName, &mapShort.IsDisabled, &mapShort.Image, &categoryPortal.Category.ID, &categoryPortal.Category.Name, &categoryPortal.PortalCount); err != nil { | ||
| 492 | c.JSON(http.StatusOK, models.ErrorResponse(err.Error())) | 528 | c.JSON(http.StatusOK, models.ErrorResponse(err.Error())) |
| 493 | return | 529 | return |
| 494 | } | 530 | } |
| 495 | maps = append(maps, mapShort) | 531 | if mapShort.ID == lastMapID { |
| 532 | maps[len(maps)-1].CategoryPortals = append(maps[len(maps)-1].CategoryPortals, categoryPortal) | ||
| 533 | } else { | ||
| 534 | mapShort.CategoryPortals = append(mapShort.CategoryPortals, categoryPortal) | ||
| 535 | maps = append(maps, mapShort) | ||
| 536 | lastMapID = mapShort.ID | ||
| 537 | } | ||
| 496 | } | 538 | } |
| 497 | response.Chapter.ID = intID | 539 | response.Chapter.ID = intID |
| 498 | response.Chapter.Name = chapterName | 540 | response.Chapter.Name = chapterName |
diff --git a/backend/models/models.go b/backend/models/models.go index 64d90d1..a114f2c 100644 --- a/backend/models/models.go +++ b/backend/models/models.go | |||
| @@ -58,6 +58,15 @@ type MapShort struct { | |||
| 58 | Difficulty int `json:"difficulty"` | 58 | Difficulty int `json:"difficulty"` |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | type MapSelect struct { | ||
| 62 | ID int `json:"id"` | ||
| 63 | Name string `json:"name"` | ||
| 64 | Image string `json:"image"` | ||
| 65 | IsDisabled bool `json:"is_disabled"` | ||
| 66 | Difficulty int `json:"difficulty"` | ||
| 67 | CategoryPortals []CategoryPortal `json:"category_portals"` | ||
| 68 | } | ||
| 69 | |||
| 61 | type MapSummary struct { | 70 | type MapSummary struct { |
| 62 | Routes []MapRoute `json:"routes"` | 71 | Routes []MapRoute `json:"routes"` |
| 63 | } | 72 | } |
diff --git a/docs/docs.go b/docs/docs.go index 688d7ed..13f217d 100644 --- a/docs/docs.go +++ b/docs/docs.go | |||
| @@ -1367,7 +1367,7 @@ const docTemplate = `{ | |||
| 1367 | "maps": { | 1367 | "maps": { |
| 1368 | "type": "array", | 1368 | "type": "array", |
| 1369 | "items": { | 1369 | "items": { |
| 1370 | "$ref": "#/definitions/models.MapShort" | 1370 | "$ref": "#/definitions/models.MapSelect" |
| 1371 | } | 1371 | } |
| 1372 | } | 1372 | } |
| 1373 | } | 1373 | } |
| @@ -1999,6 +1999,32 @@ const docTemplate = `{ | |||
| 1999 | } | 1999 | } |
| 2000 | } | 2000 | } |
| 2001 | }, | 2001 | }, |
| 2002 | "models.MapSelect": { | ||
| 2003 | "type": "object", | ||
| 2004 | "properties": { | ||
| 2005 | "category_portals": { | ||
| 2006 | "type": "array", | ||
| 2007 | "items": { | ||
| 2008 | "$ref": "#/definitions/models.CategoryPortal" | ||
| 2009 | } | ||
| 2010 | }, | ||
| 2011 | "difficulty": { | ||
| 2012 | "type": "integer" | ||
| 2013 | }, | ||
| 2014 | "id": { | ||
| 2015 | "type": "integer" | ||
| 2016 | }, | ||
| 2017 | "image": { | ||
| 2018 | "type": "string" | ||
| 2019 | }, | ||
| 2020 | "is_disabled": { | ||
| 2021 | "type": "boolean" | ||
| 2022 | }, | ||
| 2023 | "name": { | ||
| 2024 | "type": "string" | ||
| 2025 | } | ||
| 2026 | } | ||
| 2027 | }, | ||
| 2002 | "models.MapShort": { | 2028 | "models.MapShort": { |
| 2003 | "type": "object", | 2029 | "type": "object", |
| 2004 | "properties": { | 2030 | "properties": { |
diff --git a/docs/swagger.json b/docs/swagger.json index 6fe6320..a773ac7 100644 --- a/docs/swagger.json +++ b/docs/swagger.json | |||
| @@ -1361,7 +1361,7 @@ | |||
| 1361 | "maps": { | 1361 | "maps": { |
| 1362 | "type": "array", | 1362 | "type": "array", |
| 1363 | "items": { | 1363 | "items": { |
| 1364 | "$ref": "#/definitions/models.MapShort" | 1364 | "$ref": "#/definitions/models.MapSelect" |
| 1365 | } | 1365 | } |
| 1366 | } | 1366 | } |
| 1367 | } | 1367 | } |
| @@ -1993,6 +1993,32 @@ | |||
| 1993 | } | 1993 | } |
| 1994 | } | 1994 | } |
| 1995 | }, | 1995 | }, |
| 1996 | "models.MapSelect": { | ||
| 1997 | "type": "object", | ||
| 1998 | "properties": { | ||
| 1999 | "category_portals": { | ||
| 2000 | "type": "array", | ||
| 2001 | "items": { | ||
| 2002 | "$ref": "#/definitions/models.CategoryPortal" | ||
| 2003 | } | ||
| 2004 | }, | ||
| 2005 | "difficulty": { | ||
| 2006 | "type": "integer" | ||
| 2007 | }, | ||
| 2008 | "id": { | ||
| 2009 | "type": "integer" | ||
| 2010 | }, | ||
| 2011 | "image": { | ||
| 2012 | "type": "string" | ||
| 2013 | }, | ||
| 2014 | "is_disabled": { | ||
| 2015 | "type": "boolean" | ||
| 2016 | }, | ||
| 2017 | "name": { | ||
| 2018 | "type": "string" | ||
| 2019 | } | ||
| 2020 | } | ||
| 2021 | }, | ||
| 1996 | "models.MapShort": { | 2022 | "models.MapShort": { |
| 1997 | "type": "object", | 2023 | "type": "object", |
| 1998 | "properties": { | 2024 | "properties": { |
diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 6041c1d..bdfed28 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml | |||
| @@ -6,7 +6,7 @@ definitions: | |||
| 6 | $ref: '#/definitions/models.Chapter' | 6 | $ref: '#/definitions/models.Chapter' |
| 7 | maps: | 7 | maps: |
| 8 | items: | 8 | items: |
| 9 | $ref: '#/definitions/models.MapShort' | 9 | $ref: '#/definitions/models.MapSelect' |
| 10 | type: array | 10 | type: array |
| 11 | type: object | 11 | type: object |
| 12 | handlers.ChaptersResponse: | 12 | handlers.ChaptersResponse: |
| @@ -419,6 +419,23 @@ definitions: | |||
| 419 | showcase: | 419 | showcase: |
| 420 | type: string | 420 | type: string |
| 421 | type: object | 421 | type: object |
| 422 | models.MapSelect: | ||
| 423 | properties: | ||
| 424 | category_portals: | ||
| 425 | items: | ||
| 426 | $ref: '#/definitions/models.CategoryPortal' | ||
| 427 | type: array | ||
| 428 | difficulty: | ||
| 429 | type: integer | ||
| 430 | id: | ||
| 431 | type: integer | ||
| 432 | image: | ||
| 433 | type: string | ||
| 434 | is_disabled: | ||
| 435 | type: boolean | ||
| 436 | name: | ||
| 437 | type: string | ||
| 438 | type: object | ||
| 422 | models.MapShort: | 439 | models.MapShort: |
| 423 | properties: | 440 | properties: |
| 424 | difficulty: | 441 | difficulty: |