From 1a1d2a68411e9cfd7dc2e5dec8473b7657f8b60c Mon Sep 17 00:00:00 2001 From: Ke Chen Date: Wed, 31 Jul 2024 20:27:40 +0800 Subject: [PATCH] feat: admin log for hole and division now show diff; ModifyDivision partially updates --- apis/division/apis.go | 54 ++++++++++++++++++++++++++++++---------- apis/division/schemas.go | 7 +++--- apis/hole/apis.go | 21 +++++++++++++--- docs/docs.go | 6 ++--- docs/swagger.json | 6 ++--- docs/swagger.yaml | 6 ++--- 6 files changed, 71 insertions(+), 29 deletions(-) diff --git a/apis/division/apis.go b/apis/division/apis.go index 0c6bd88..4d3ef09 100644 --- a/apis/division/apis.go +++ b/apis/division/apis.go @@ -1,6 +1,8 @@ package division import ( + "gorm.io/gorm" + "gorm.io/gorm/clause" "strconv" "github.com/opentreehole/go-common" @@ -9,7 +11,6 @@ import ( . "treehole_next/utils" "github.com/gofiber/fiber/v2" - "gorm.io/gorm" ) // AddDivision @@ -104,16 +105,17 @@ func GetDivision(c *fiber.Ctx) error { // @Router /divisions/{id} [put] // @Router /divisions/{id}/_modify [patch] // @Param id path int true "id" -// @Param json body ModifyModel true "json" +// @Param json body ModifyDivisionModel true "json" // @Success 200 {object} models.Division // @Failure 404 {object} MessageModel func ModifyDivision(c *fiber.Ctx) error { // validate body - var body ModifyModel + var body ModifyDivisionModel err := common.ValidateBody(c, &body) if err != nil { return err } + id, err := c.ParamsInt("id") if err != nil { return err @@ -130,21 +132,47 @@ func ModifyDivision(c *fiber.Ctx) error { return common.Forbidden() } - division := Division{ - Name: body.Name, - Description: body.Description, - Pinned: body.Pinned, + var division Division + err = DB.Transaction(func(tx *gorm.DB) error { + err = tx.Clauses(clause.Locking{Strength: "UPDATE"}).First(&division, id).Error + if err != nil { + return err + } + + modifyData := make(map[string]any) + if body.Name != nil { + modifyData["name"] = *body.Name + } + if body.Description != nil { + modifyData["description"] = *body.Description + } + if body.Pinned != nil { + modifyData["pinned"] = body.Pinned + } + + if len(modifyData) == 0 { + return common.BadRequest("No data to modify.") + } + + return tx.Model(&division).Updates(modifyData).Error + }) + if err != nil { + return err } - division.ID = id - result := DB.Model(&division).Updates(division) - // nothing updated, means that the record does not exist - if result.RowsAffected == 0 { - return gorm.ErrRecordNotFound + + var newDivision Division + err = DB.First(&newDivision, id).Error + if err != nil { + return err } MyLog("Division", "Modify", division.ID, user.ID, RoleAdmin) - CreateAdminLog(DB, AdminLogTypeDivision, user.ID, body) + CreateAdminLog(DB, AdminLogTypeDivision, user.ID, map[string]any{ + "division_id": division.ID, + "before": division, + "after": newDivision, + }) // refresh cache. here should not use `go refreshCache` err = refreshCache(c) diff --git a/apis/division/schemas.go b/apis/division/schemas.go index 26ec82f..82c69ef 100644 --- a/apis/division/schemas.go +++ b/apis/division/schemas.go @@ -11,7 +11,8 @@ type CreateModel struct { Description string `json:"description"` } -type ModifyModel struct { - CreateModel - Pinned []int `json:"pinned"` +type ModifyDivisionModel struct { + Name *string `json:"name"` + Description *string `json:"description"` + Pinned []int `json:"pinned"` } diff --git a/apis/hole/apis.go b/apis/hole/apis.go index ddd7f40..aaf60b2 100644 --- a/apis/hole/apis.go +++ b/apis/hole/apis.go @@ -566,11 +566,18 @@ func ModifyHole(c *fiber.Ctx) error { if user.IsAdmin { CreateAdminLog(tx, AdminLogTypeHole, user.ID, struct { - HoleID int `json:"hole_id"` - Body ModifyModel `json:"body"` + HoleID int `json:"hole_id"` + Before map[string]any `json:"before"` + Modify ModifyModel `json:"modify"` }{ HoleID: holeID, - Body: body, + Before: map[string]any{ + "division_id": hole.DivisionID, + "hidden": hole.Hidden, + "locked": hole.Locked, + "tags": hole.Tags, + }, + Modify: body, }) } } @@ -628,7 +635,13 @@ func HideHole(c *fiber.Ctx) error { // log MyLog("Hole", "Hide", holeID, user.ID, RoleAdmin) - CreateAdminLog(DB, AdminLogTypeHideHole, user.ID, hole) + CreateAdminLog(DB, AdminLogTypeHideHole, user.ID, struct { + HoleID int `json:"hole_id"` + Hidden bool `json:"hidden"` + }{ + HoleID: holeID, + Hidden: true, + }) // find hole and update cache diff --git a/docs/docs.go b/docs/docs.go index 92e18d8..ffccd1f 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -278,7 +278,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/division.ModifyModel" + "$ref": "#/definitions/division.ModifyDivisionModel" } } ], @@ -360,7 +360,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/division.ModifyModel" + "$ref": "#/definitions/division.ModifyDivisionModel" } } ], @@ -3065,7 +3065,7 @@ const docTemplate = `{ } } }, - "division.ModifyModel": { + "division.ModifyDivisionModel": { "type": "object", "properties": { "description": { diff --git a/docs/swagger.json b/docs/swagger.json index 9c034b4..8f6518b 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -271,7 +271,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/division.ModifyModel" + "$ref": "#/definitions/division.ModifyDivisionModel" } } ], @@ -353,7 +353,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/division.ModifyModel" + "$ref": "#/definitions/division.ModifyDivisionModel" } } ], @@ -3058,7 +3058,7 @@ } } }, - "division.ModifyModel": { + "division.ModifyDivisionModel": { "type": "object", "properties": { "description": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 81e1950..4323293 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -41,7 +41,7 @@ definitions: ID of the target division that all the deleted division's holes will be moved to type: integer type: object - division.ModifyModel: + division.ModifyDivisionModel: properties: description: type: string @@ -1031,7 +1031,7 @@ paths: name: json required: true schema: - $ref: '#/definitions/division.ModifyModel' + $ref: '#/definitions/division.ModifyDivisionModel' produces: - application/json responses: @@ -1059,7 +1059,7 @@ paths: name: json required: true schema: - $ref: '#/definitions/division.ModifyModel' + $ref: '#/definitions/division.ModifyDivisionModel' produces: - application/json responses: