Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions apis/floor/apis.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,55 @@ func GetFloor(c *fiber.Ctx) (err error) {
return Serialize(c, &floor)
}

// GetFloorSurroundings
//
// @Summary Get Surrounding Floors
// @Description 获取指定楼层前后各 size 个楼层,用于跳转定位
// @Tags Floor
// @Produce application/json
// @Router /floors/{id}/surroundings [get]
// @Param id path int true "floor id"
// @Param size query int false "上下各加载的楼层数" default(10)
// @Success 200 {array} Floor
func GetFloorSurroundings(c *fiber.Ctx) error {
floorID, err := c.ParamsInt("id")
if err != nil {
return err
}

var query SurroundingModel
err = common.ValidateQuery(c, &query)
if err != nil {
return err
}

// get target floor's hole_id and ranking
var target Floor
err = DB.Select("hole_id", "ranking").First(&target, floorID).Error
if err != nil {
return err
}

// load floors within ranking range
var floors Floors
querySet, err := MakeFloorQuerySet(c)
if err != nil {
return err
}
err = querySet.
Where("hole_id = ? AND ranking BETWEEN ? AND ?",
target.HoleID,
target.Ranking-query.Size,
target.Ranking+query.Size).
Order("ranking ASC").
Find(&floors).Error
if err != nil {
return err
}

return Serialize(c, &floors)
}

// CreateFloor
//
// @Summary Create A Floor
Expand Down
1 change: 1 addition & 0 deletions apis/floor/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ func RegisterRoutes(app fiber.Router) {
app.Get("/holes/:id<int>/floors", ListFloorsInAHole)
app.Get("/floors", ListFloorsOld)
app.Get("/floors/:id<int>", GetFloor)
app.Get("/floors/:id<int>/surroundings", GetFloorSurroundings)
app.Post("/holes/:id<int>/floors", utils.MiddlewareHasAnsweredQuestions, CreateFloor)
app.Post("/floors", utils.MiddlewareHasAnsweredQuestions, CreateFloorOld)
app.Put("/floors/:id<int>", ModifyFloor)
Expand Down
4 changes: 4 additions & 0 deletions apis/floor/schemas.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ type ListOldModel struct {
Search string `query:"s" json:"s"`
}

type SurroundingModel struct {
Size int `json:"size" query:"size" default:"10" validate:"min=1,max=50"`
}

type CreateModel struct {
Content string `json:"content" validate:"required"`
// Admin and Operator only
Expand Down
29 changes: 29 additions & 0 deletions tests/floor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,32 @@ func TestDeleteFloor(t *testing.T) {
DB.Where("hole_id = ?", hole.ID).Offset(1).First(&floor)
testAPI(t, "delete", "/api/floors/"+strconv.Itoa(floor.ID), 200, data)
}

func TestGetFloorSurroundings(t *testing.T) {
// division 7 的第一个 hole 有 50 个 floor (ranking 0-49)
var hole Hole
DB.Where("division_id = ?", 7).First(&hole)

// 取中间位置的 floor
var midFloor Floor
DB.Where("hole_id = ? AND ranking = ?", hole.ID, 25).First(&midFloor)

// 默认 size=10,应返回 ranking 15-35 共 21 个
var floors Floors
testAPIModel(t, "get", "/api/floors/"+strconv.Itoa(midFloor.ID)+"/surroundings", 200, &floors)
assert.EqualValues(t, 21, len(floors))

// 自定义 size=5,应返回 ranking 20-30 共 11 个
data := Map{"size": 5}
testAPIModelWithQuery(t, "get", "/api/floors/"+strconv.Itoa(midFloor.ID)+"/surroundings", 200, &floors, data)
assert.EqualValues(t, 11, len(floors))

// 边界:第一个 floor (ranking=0), size=10 → ranking 0-10 共 11 个
var firstFloor Floor
DB.Where("hole_id = ? AND ranking = ?", hole.ID, 0).First(&firstFloor)
testAPIModel(t, "get", "/api/floors/"+strconv.Itoa(firstFloor.ID)+"/surroundings", 200, &floors)
assert.EqualValues(t, 11, len(floors))

// 404
testCommon(t, "get", "/api/floors/"+strconv.Itoa(largeInt)+"/surroundings", 404)
}