Skip to content

Commit da328c2

Browse files
authored
Merge pull request #202 from OpenTreeHole/feat/delete_notification
feat(notification): 按楼层关联级联删除通知
2 parents 0c7ba2d + 9f03a27 commit da328c2

9 files changed

Lines changed: 278 additions & 63 deletions

File tree

apis/floor/apis.go

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"slices"
66
"time"
7+
"treehole_next/apis/message"
78
"treehole_next/utils/sensitive"
89

910
"github.com/opentreehole/go-common"
@@ -629,6 +630,11 @@ func DeleteFloor(c *fiber.Ctx) error {
629630

630631
floor.Deleted = true
631632
floor.Content = generateDeleteReason(body.Reason, user.ID == floor.UserID)
633+
err = message.DeleteMessageByRelatedFloorID(tx, floor.ID)
634+
if err != nil {
635+
return err
636+
}
637+
632638
return tx.Save(&floor).Error
633639
})
634640
if err != nil {
@@ -857,15 +863,15 @@ func GetPunishmentHistory(c *fiber.Ctx) error {
857863
// search DB for user punishment history
858864
punishments := make([]string, 0, 10)
859865
err = DB.Raw(
860-
`SELECT f.content
866+
`SELECT f.content
861867
FROM floor f
862868
WHERE f.id IN (
863-
SELECT distinct floor.id
864-
FROM floor
865-
JOIN floor_history ON floor.id = floor_history.floor_id
866-
WHERE floor.user_id <> floor_history.user_id
867-
AND floor.user_id = ?
868-
AND floor.deleted = true
869+
SELECT distinct floor.id
870+
FROM floor
871+
JOIN floor_history ON floor.id = floor_history.floor_id
872+
WHERE floor.user_id <> floor_history.user_id
873+
AND floor.user_id = ?
874+
AND floor.deleted = true
869875
)`, userID).Scan(&punishments).Error
870876
if err != nil {
871877
return err
@@ -1069,6 +1075,10 @@ func ModifyFloorSensitive(c *fiber.Ctx) (err error) {
10691075
if err != nil {
10701076
return err
10711077
}
1078+
err = message.DeleteMessageByRelatedFloorID(tx, floor.ID)
1079+
if err != nil {
1080+
return err
1081+
}
10721082

10731083
floor.Deleted = true
10741084
floor.Content = generateDeleteReason(reason, false)

apis/hole/apis.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"slices"
1212
"strconv"
1313
"time"
14+
"treehole_next/apis/message"
1415
"treehole_next/config"
1516
"treehole_next/utils/sensitive"
1617

@@ -859,6 +860,10 @@ func HideHole(c *fiber.Ctx) error {
859860
var floors Floors
860861
_ = DB.Where("hole_id = ?", hole.ID).Find(&floors)
861862
go BulkDelete(Models2IDSlice(floors))
863+
err = message.DeleteMessageByRelatedHoleID(DB, hole.ID)
864+
if err != nil {
865+
return err
866+
}
862867

863868
return c.Status(204).JSON(nil)
864869
}
@@ -949,6 +954,10 @@ func DeleteHole(c *fiber.Ctx) error {
949954
if err != nil {
950955
log.Err(err).Msg("DeleteHole: delete cache divisions")
951956
}
957+
err = message.DeleteMessageByRelatedHoleID(DB, hole.ID)
958+
if err != nil {
959+
return err
960+
}
952961

953962
return c.Status(204).JSON(nil)
954963
}

apis/message/apis.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package message
22

33
import (
44
"github.com/opentreehole/go-common"
5+
"gorm.io/gorm"
56

67
. "treehole_next/models"
78
. "treehole_next/utils"
@@ -154,3 +155,25 @@ func DeleteMessage(c *fiber.Ctx) error {
154155
}
155156
return c.Status(204).JSON(nil)
156157
}
158+
159+
func deleteMessagesByCondition(db *gorm.DB, condition string, value int) error {
160+
var messageIDs []int
161+
if err := db.Model(&Message{}).Where(condition, value).Pluck("id", &messageIDs).Error; err != nil {
162+
return err
163+
}
164+
if len(messageIDs) == 0 {
165+
return nil
166+
}
167+
if err := db.Where("message_id IN ?", messageIDs).Delete(&MessageUser{}).Error; err != nil {
168+
return err
169+
}
170+
return db.Where("id IN ?", messageIDs).Delete(&Message{}).Error
171+
}
172+
173+
func DeleteMessageByRelatedFloorID(db *gorm.DB, floorID int) error {
174+
return deleteMessagesByCondition(db, "related_floor_id = ?", floorID)
175+
}
176+
177+
func DeleteMessageByRelatedHoleID(db *gorm.DB, holeID int) error {
178+
return deleteMessagesByCondition(db, "related_hole_id = ?", holeID)
179+
}

apis/penalty/api.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,10 @@ func BanUser(c *fiber.Ctx) error {
115115
days,
116116
body.Reason,
117117
),
118-
Title: "处罚通知",
119-
Type: MessageTypePermission,
120-
URL: fmt.Sprintf("/api/floors/%d", floor.ID),
118+
Title: "处罚通知",
119+
Type: MessageTypePermission,
120+
URL: fmt.Sprintf("/api/floors/%d", floor.ID),
121+
RelatedFloorID: &floor.ID,
121122
}
122123

123124
// send
@@ -247,9 +248,10 @@ func BanUserForever(c *fiber.Ctx) error {
247248
days,
248249
body.Reason,
249250
),
250-
Title: "处罚通知",
251-
Type: MessageTypePermission,
252-
URL: fmt.Sprintf("/api/floors/%d", floor.ID),
251+
Title: "处罚通知",
252+
Type: MessageTypePermission,
253+
URL: fmt.Sprintf("/api/floors/%d", floor.ID),
254+
RelatedFloorID: &floor.ID,
253255
}
254256

255257
// send

apis/report/apis.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -256,9 +256,10 @@ func BanReporter(c *fiber.Ctx) error {
256256
days,
257257
body.Reason,
258258
),
259-
Title: "处罚通知",
260-
Type: MessageTypePermission,
261-
URL: fmt.Sprintf("/api/reports/%d", report.ID),
259+
Title: "处罚通知",
260+
Type: MessageTypePermission,
261+
URL: fmt.Sprintf("/api/reports/%d", report.ID),
262+
RelatedFloorID: &report.FloorID,
262263
}
263264

264265
// send

models/floor.go

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -503,12 +503,13 @@ func (floor *Floor) SendSubscription(tx *gorm.DB) Notification {
503503

504504
// Construct Notification
505505
message := Notification{
506-
Data: floor,
507-
Recipients: userIDs,
508-
Description: floor.Content,
509-
Title: "您关注的帖子有新回复",
510-
Type: MessageTypeFavorite,
511-
URL: fmt.Sprintf("/api/floors/%d", floor.ID),
506+
Data: floor,
507+
Recipients: userIDs,
508+
Description: floor.Content,
509+
Title: "您关注的帖子有新回复",
510+
Type: MessageTypeFavorite,
511+
URL: fmt.Sprintf("/api/floors/%d", floor.ID),
512+
RelatedFloorID: &floor.ID,
512513
}
513514

514515
return message
@@ -530,12 +531,13 @@ func (floor *Floor) SendReply(tx *gorm.DB) Notification {
530531

531532
// construct message
532533
message := Notification{
533-
Data: floor,
534-
Recipients: userIDs,
535-
Description: floor.Content,
536-
Title: "您的内容有新回复",
537-
Type: MessageTypeReply,
538-
URL: fmt.Sprintf("/api/floors/%d", floor.ID),
534+
Data: floor,
535+
Recipients: userIDs,
536+
Description: floor.Content,
537+
Title: "您的内容有新回复",
538+
Type: MessageTypeReply,
539+
URL: fmt.Sprintf("/api/floors/%d", floor.ID),
540+
RelatedFloorID: &floor.ID,
539541
}
540542

541543
return message
@@ -555,12 +557,13 @@ func (floor *Floor) SendMention(_ *gorm.DB) Notification {
555557

556558
// construct message
557559
message := Notification{
558-
Data: floor,
559-
Recipients: userIDs,
560-
Description: floor.Content,
561-
Title: "您的内容被引用了",
562-
Type: MessageTypeMention,
563-
URL: fmt.Sprintf("/api/floors/%d", floor.ID),
560+
Data: floor,
561+
Recipients: userIDs,
562+
Description: floor.Content,
563+
Title: "您的内容被引用了",
564+
Type: MessageTypeMention,
565+
URL: fmt.Sprintf("/api/floors/%d", floor.ID),
566+
RelatedFloorID: &floor.ID,
564567
}
565568

566569
return message
@@ -572,12 +575,13 @@ func (floor *Floor) SendModify(_ *gorm.DB) error {
572575

573576
// construct message
574577
message := Notification{
575-
Data: floor,
576-
Recipients: userIDs,
577-
Description: floor.Content,
578-
Title: "您的内容被管理员修改了",
579-
Type: MessageTypeModify,
580-
URL: fmt.Sprintf("/api/floors/%d", floor.ID),
578+
Data: floor,
579+
Recipients: userIDs,
580+
Description: floor.Content,
581+
Title: "您的内容被管理员修改了",
582+
Type: MessageTypeModify,
583+
URL: fmt.Sprintf("/api/floors/%d", floor.ID),
584+
RelatedFloorID: &floor.ID,
581585
}
582586

583587
// send
@@ -598,12 +602,13 @@ func (floor *Floor) SendSensitive(_ *gorm.DB) error {
598602
// construct message
599603
desc := "您有待审核的内容"
600604
message := Notification{
601-
Data: floor,
602-
Recipients: userIDs,
603-
Description: desc,
604-
Title: desc,
605-
Type: MessageTypeSensitive,
606-
URL: fmt.Sprintf("/api/floors/%d", floor.ID),
605+
Data: floor,
606+
Recipients: userIDs,
607+
Description: desc,
608+
Title: desc,
609+
Type: MessageTypeSensitive,
610+
URL: fmt.Sprintf("/api/floors/%d", floor.ID),
611+
RelatedFloorID: &floor.ID,
607612
}
608613
_, err := message.Send()
609614
utils.Notify(utils.NotificationTargetFeishuAdmin, desc+fmt.Sprintf("\n##%d\n\n%s\n\n%s", floor.ID, floor.Content, floor.SensitiveDetail))

models/message.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ type Message struct {
1919
Description string `json:"description" gorm:"size:65536;not null"`
2020
Data any `json:"data" gorm:"serializer:json" `
2121
Type MessageType `json:"code" gorm:"size:16;not null"`
22-
URL string `json:"url" gorm:"size:64;default:'';not null"`
23-
Recipients []int `json:"-" gorm:"-:all" `
24-
MessageID int `json:"message_id" gorm:"-:all"` // 兼容旧版 id
25-
HasRead bool `json:"has_read" gorm:"default:false"` // 兼容旧版, 永远为false,以MessageUser的HasRead为准
26-
Users Users `json:"-" gorm:"many2many:message_user;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
22+
URL string `json:"url" gorm:"size:64;default:'';not null"`
23+
RelatedFloorID *int `json:"related_floor_id,omitempty" gorm:"index"`
24+
RelatedHoleID *int `json:"related_hole_id,omitempty" gorm:"index"`
25+
Recipients []int `json:"-" gorm:"-:all" `
26+
MessageID int `json:"message_id" gorm:"-:all"` // 兼容旧版 id
27+
HasRead bool `json:"has_read" gorm:"default:false"` // 兼容旧版, 永远为false,以MessageUser的HasRead为准
28+
Users Users `json:"-" gorm:"many2many:message_user;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
2729
}
2830

2931
type MessageUser struct {

models/notification.go

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,14 @@ type Notifications []Notification
3434

3535
type Notification struct {
3636
// Should be same as CrateModel in notification project
37-
Title string `json:"message"`
38-
Description string `json:"description"`
39-
Data any `json:"data"`
40-
Type MessageType `json:"code"`
41-
URL string `json:"url"`
42-
Recipients []int `json:"recipients"`
37+
Title string `json:"message"`
38+
Description string `json:"description"`
39+
Data any `json:"data"`
40+
Type MessageType `json:"code"`
41+
URL string `json:"url"`
42+
Recipients []int `json:"recipients"`
43+
RelatedFloorID *int `json:"related_floor_id,omitempty"`
44+
RelatedHoleID *int `json:"related_hole_id,omitempty"`
4345
}
4446

4547
func readRespNotification(body io.ReadCloser) Notification {
@@ -140,12 +142,14 @@ func (message Notification) Send() (Message, error) {
140142

141143
// save to database first
142144
body := Message{
143-
Type: message.Type,
144-
Title: message.Title,
145-
Description: message.Description,
146-
Data: message.Data,
147-
URL: message.URL,
148-
Recipients: message.Recipients,
145+
Type: message.Type,
146+
Title: message.Title,
147+
Description: message.Description,
148+
Data: message.Data,
149+
URL: message.URL,
150+
Recipients: message.Recipients,
151+
RelatedFloorID: message.RelatedFloorID,
152+
RelatedHoleID: message.RelatedHoleID,
149153
}
150154
err = DB.Omit(clause.Associations).Create(&body).Error
151155
if err != nil {

0 commit comments

Comments
 (0)