feat(privacy): add user privacy settings and account deletion system
Add privacy settings allowing users to control visibility of their followers, following, posts, and favorites lists with three visibility levels: everyone, following, and self. Also implement account deletion workflow with 30-day cooldown period. - Add PrivacySettings model with visibility levels - Add DTOs for privacy settings and account deletion - Add repository methods for privacy settings and deletion - Add service methods to check visibility permissions - Add handlers for get/update privacy settings and account deletion - Add new routes for privacy settings and account management - Add account cleanup service for hard-deleting expired accounts - Modify login to cancel deletion when user logs in BREAKING CHANGE: Users with pending_deletion status can no longer log in; logging in now automatically cancels deletion requests.
This commit is contained in:
@@ -3,6 +3,7 @@ package repository
|
||||
import (
|
||||
"carrot_bbs/internal/model"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
@@ -43,6 +44,16 @@ type UserRepository interface {
|
||||
AdminList(page, pageSize int, keyword, status string) ([]*model.User, int64, error)
|
||||
GetCommentsCount(userID string) (int64, error)
|
||||
UpdateStatus(userID string, status model.UserStatus) error
|
||||
|
||||
// 隐私设置
|
||||
UpdatePrivacySettings(userID string, settings *model.PrivacySettings) error
|
||||
GetPrivacySettings(userID string) (*model.PrivacySettings, error)
|
||||
|
||||
// 账号注销
|
||||
RequestDeletion(userID string) error
|
||||
CancelDeletion(userID string) error
|
||||
GetPendingDeletionUsers(beforeTime time.Time) ([]*model.User, error)
|
||||
HardDeleteUser(userID string) error
|
||||
}
|
||||
|
||||
// userRepository 用户仓储实现
|
||||
@@ -544,3 +555,54 @@ func (r *userRepository) GetCommentsCount(userID string) (int64, error) {
|
||||
func (r *userRepository) UpdateStatus(userID string, status model.UserStatus) error {
|
||||
return r.db.Model(&model.User{}).Where("id = ?", userID).Update("status", status).Error
|
||||
}
|
||||
|
||||
// UpdatePrivacySettings 更新隐私设置
|
||||
func (r *userRepository) UpdatePrivacySettings(userID string, settings *model.PrivacySettings) error {
|
||||
return r.db.Model(&model.User{}).Where("id = ?", userID).Updates(map[string]interface{}{
|
||||
"privacy_followers_visibility": settings.FollowersVisibility,
|
||||
"privacy_following_visibility": settings.FollowingVisibility,
|
||||
"privacy_posts_visibility": settings.PostsVisibility,
|
||||
"privacy_favorites_visibility": settings.FavoritesVisibility,
|
||||
}).Error
|
||||
}
|
||||
|
||||
// GetPrivacySettings 获取隐私设置
|
||||
func (r *userRepository) GetPrivacySettings(userID string) (*model.PrivacySettings, error) {
|
||||
var user model.User
|
||||
err := r.db.Select("privacy_followers_visibility, privacy_following_visibility, privacy_posts_visibility, privacy_favorites_visibility").
|
||||
First(&user, "id = ?", userID).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user.PrivacySettings, nil
|
||||
}
|
||||
|
||||
// RequestDeletion 申请注销账号
|
||||
func (r *userRepository) RequestDeletion(userID string) error {
|
||||
now := time.Now()
|
||||
return r.db.Model(&model.User{}).Where("id = ?", userID).Updates(map[string]interface{}{
|
||||
"deletion_requested_at": &now,
|
||||
"status": model.UserStatusPendingDeletion,
|
||||
}).Error
|
||||
}
|
||||
|
||||
// CancelDeletion 取消注销
|
||||
func (r *userRepository) CancelDeletion(userID string) error {
|
||||
return r.db.Model(&model.User{}).Where("id = ?", userID).Updates(map[string]interface{}{
|
||||
"deletion_requested_at": nil,
|
||||
"status": model.UserStatusActive,
|
||||
}).Error
|
||||
}
|
||||
|
||||
// GetPendingDeletionUsers 获取待删除的用户列表(注销申请时间早于指定时间)
|
||||
func (r *userRepository) GetPendingDeletionUsers(beforeTime time.Time) ([]*model.User, error) {
|
||||
var users []*model.User
|
||||
err := r.db.Where("deletion_requested_at IS NOT NULL AND deletion_requested_at < ?", beforeTime).
|
||||
Find(&users).Error
|
||||
return users, err
|
||||
}
|
||||
|
||||
// HardDeleteUser 硬删除用户(永久删除)
|
||||
func (r *userRepository) HardDeleteUser(userID string) error {
|
||||
return r.db.Unscoped().Delete(&model.User{}, "id = ?", userID).Error
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user