126 lines
3.4 KiB
Go
126 lines
3.4 KiB
Go
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,
|
||
}
|
||
}
|