增加站内信未读提醒和后台通知中心+txt 校验

This commit is contained in:
yml2213
2026-06-19 15:24:15 +08:00
parent 8d5094a8d0
commit a4cdc3e806
30 changed files with 1836 additions and 53 deletions
@@ -0,0 +1,125 @@
package adminnotification
import (
"context"
"hfb_sys/backend/internal/model"
"gorm.io/gorm"
)
type Repository struct {
db *gorm.DB
}
func NewRepository(db *gorm.DB) *Repository {
return &Repository{db: db}
}
func (r *Repository) List(ctx context.Context, query Query) (*PaginatedResult, error) {
db := r.db.WithContext(ctx).Model(&model.AdminNotification{}).
Where("admin_user_id = ?", query.AdminUserID)
countDB := r.db.WithContext(ctx).Model(&model.AdminNotification{}).
Where("admin_user_id = ?", query.AdminUserID)
if query.OnlyUnread {
db = db.Where("is_read = ?", false)
countDB = countDB.Where("is_read = ?", false)
}
var total int64
if err := countDB.Count(&total).Error; err != nil {
return nil, err
}
offset := (query.Page - 1) * query.PageSize
var rows []model.AdminNotification
if err := db.Order("id DESC").Offset(offset).Limit(query.PageSize).Find(&rows).Error; err != nil {
return nil, err
}
items := make([]NotificationDTO, 0, len(rows))
for _, row := range rows {
items = append(items, toDTO(row))
}
return &PaginatedResult{Items: items, Total: total, Page: query.Page, PageSize: query.PageSize}, nil
}
func (r *Repository) UnreadCount(ctx context.Context, adminUserID uint64) (int64, error) {
var total int64
err := r.db.WithContext(ctx).Model(&model.AdminNotification{}).
Where("admin_user_id = ? AND is_read = ?", adminUserID, false).
Count(&total).Error
return total, err
}
func (r *Repository) MarkRead(ctx context.Context, adminUserID uint64, id uint64) error {
result := r.db.WithContext(ctx).Model(&model.AdminNotification{}).
Where("id = ? AND admin_user_id = ?", id, adminUserID).
Update("is_read", true)
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
var total int64
if err := r.db.WithContext(ctx).Model(&model.AdminNotification{}).
Where("id = ? AND admin_user_id = ?", id, adminUserID).
Count(&total).Error; err != nil {
return err
}
if total == 0 {
return ErrNotificationNotFound
}
}
return nil
}
func (r *Repository) MarkAllRead(ctx context.Context, adminUserID uint64) (int64, error) {
result := r.db.WithContext(ctx).Model(&model.AdminNotification{}).
Where("admin_user_id = ? AND is_read = ?", adminUserID, false).
Update("is_read", true)
return result.RowsAffected, result.Error
}
// Entry 描述一条待写入的管理员通知。
type Entry struct {
AdminUserID uint64
Type string
Title string
Content string
}
// Append 在事务中批量写入管理员通知。
// 典型用法:在业务事务内调用 adminnotification.Append(tx, entries...)
// 确保通知与业务数据在同一事务中提交或回滚。
func Append(tx *gorm.DB, entries ...Entry) error {
for _, entry := range entries {
if entry.AdminUserID == 0 || entry.Title == "" {
continue
}
row := model.AdminNotification{
AdminUserID: entry.AdminUserID,
Type: entry.Type,
Title: entry.Title,
Content: entry.Content,
}
if row.Type == "" {
row.Type = "system"
}
if err := tx.Create(&row).Error; err != nil {
return err
}
}
return nil
}
func toDTO(row model.AdminNotification) NotificationDTO {
return NotificationDTO{
ID: row.ID,
AdminUserID: row.AdminUserID,
Type: row.Type,
Title: row.Title,
Content: row.Content,
IsRead: row.IsRead,
CreatedAt: row.CreatedAt,
UpdatedAt: row.UpdatedAt,
}
}