refactor(plugins): restructure admin and message_gateway into standard layered sub-packages

This commit is contained in:
ryan
2026-08-28 22:33:26 +08:00
parent 85b383a4e0
commit f4975d6732
128 changed files with 12050 additions and 9901 deletions
+164
View File
@@ -188,3 +188,167 @@ func ListUsernamesMatchingBase(ctx context.Context, base string) ([]string, erro
}
return usernames, nil
}
// adminUserColumns 后台用户查询显式列清单
const adminUserColumns = "id, username, nickname, email, avatar_url, is_active, is_admin, bio, phone, gender, website, location, last_login_at, created_at, updated_at"
// updateUserColumns 按列局部更新指定用户行
func updateUserColumns(ctx context.Context, id uint64, updates map[string]any) error {
return getDB(ctx).Model(&User{}).Where("id = ?", id).Updates(updates).Error
}
// setUserAdminFlag 更新指定用户的管理员标记列
func setUserAdminFlag(ctx context.Context, id uint64, admin bool) error {
return getDB(ctx).Model(&User{}).Where("id = ?", id).Update("is_admin", admin).Error
}
// setUserActiveColumn 后台启用/禁用用户,沿用无 schema 的按表直写语义
// (与导出函数 UpdateUserActive 不同,后者经由 Model 会额外刷新 updated_at)
func setUserActiveColumn(ctx context.Context, id uint64, active bool) error {
return getDB(ctx).Table("w_users").Where("id = ?", id).Update("is_active", active).Error
}
// countAllUsers 统计用户总数
func countAllUsers(ctx context.Context) (int64, error) {
var count int64
err := getDB(ctx).Model(&User{}).Count(&count).Error
return count, err
}
// countActiveUsers 统计激活状态用户数
func countActiveUsers(ctx context.Context) (int64, error) {
var count int64
err := getDB(ctx).Model(&User{}).Where("is_active = ?", true).Count(&count).Error
return count, err
}
// countUsersByUsername 统计同名用户数量
func countUsersByUsername(ctx context.Context, username string) (int64, error) {
var count int64
err := getDB(ctx).Table("w_users").Where("username = ?", username).Count(&count).Error
return count, err
}
// countUsersByEmail 统计同邮箱用户数量
func countUsersByEmail(ctx context.Context, email string) (int64, error) {
var count int64
err := getDB(ctx).Table("w_users").Where("email = ?", email).Count(&count).Error
return count, err
}
// countOtherUsersByEmail 统计除指定用户外的同邮箱数量
func countOtherUsersByEmail(ctx context.Context, email string, id uint64) (int64, error) {
var count int64
err := getDB(ctx).Table("w_users").Where("email = ? AND id != ?", email, id).Count(&count).Error
return count, err
}
// adminListUserRows 后台条件分页查询用户
func adminListUserRows(ctx context.Context, filter contracts.AdminListUsersFilter) (int64, []*contracts.UserDTO, error) {
query := getDB(ctx).Table("w_users")
if filter.UserID != nil {
query = query.Where("id = ?", *filter.UserID)
}
if filter.Username != "" {
query = query.Where("username LIKE ? ESCAPE '\\'", util.EscapeLike(filter.Username)+"%")
}
if filter.Email != "" {
query = query.Where("email LIKE ? ESCAPE '\\'", util.EscapeLike(filter.Email)+"%")
}
var total int64
if err := query.Count(&total).Error; err != nil {
return 0, nil, err
}
var users []*contracts.UserDTO
offset := (filter.Page - 1) * filter.PageSize
if err := query.
Select(adminUserColumns).
Order("id ASC").
Offset(offset).
Limit(filter.PageSize).
Find(&users).Error; err != nil {
return 0, nil, err
}
return total, users, nil
}
// adminGetUserRow 后台按 ID 读取用户视图
func adminGetUserRow(ctx context.Context, id uint64) (*contracts.UserDTO, error) {
var user contracts.UserDTO
if err := getDB(ctx).Table("w_users").
Select(adminUserColumns).
Where("id = ?", id).
First(&user).Error; err != nil {
return nil, err
}
return &user, nil
}
// getUserRow 按 ID 整行读取用户视图
func getUserRow(ctx context.Context, id uint64) (*contracts.UserDTO, error) {
var user contracts.UserDTO
if err := getDB(ctx).Table("w_users").Where("id = ?", id).First(&user).Error; err != nil {
return nil, err
}
return &user, nil
}
// insertUserRow 以显式列映射写入用户行
func insertUserRow(ctx context.Context, row map[string]any) error {
return getDB(ctx).Table("w_users").Create(row).Error
}
// getUserAdminFlags 读取指定用户的管理员标记
func getUserAdminFlags(ctx context.Context, id uint64) (userAdminFlags, error) {
var flags userAdminFlags
if err := getDB(ctx).Table("w_users").Select("id, is_admin").Where("id = ?", id).First(&flags).Error; err != nil {
return userAdminFlags{}, err
}
return flags, nil
}
// deleteUserCascadeAdmin 在事务中删除用户的访问令牌、外部账号绑定与用户行
func deleteUserCascadeAdmin(ctx context.Context, id uint64) error {
return getDB(ctx).Transaction(func(tx *gorm.DB) error {
if err := tx.Table("w_access_tokens").Where("user_id = ?", id).Delete(map[string]any{}).Error; err != nil {
return err
}
if err := tx.Table("w_external_accounts").Where("user_id = ?", id).Delete(map[string]any{}).Error; err != nil {
return err
}
return tx.Table("w_users").Where("id = ?", id).Delete(map[string]any{}).Error
})
}
// listAccessTokensByUser 列出指定用户的访问令牌
func listAccessTokensByUser(ctx context.Context, userID uint64) ([]AccessToken, error) {
var tokens []AccessToken
err := getDB(ctx).Where("user_id = ?", userID).Find(&tokens).Error
return tokens, err
}
// getAccessTokenOfUser 按 ID 与所属用户读取访问令牌
func getAccessTokenOfUser(ctx context.Context, id, userID uint64) (*AccessToken, error) {
var token AccessToken
if err := getDB(ctx).Where("id = ? AND user_id = ?", id, userID).First(&token).Error; err != nil {
return nil, err
}
return &token, nil
}
// createAccessTokenRow 写入访问令牌记录
func createAccessTokenRow(ctx context.Context, token *AccessToken) error {
return getDB(ctx).Create(token).Error
}
// saveAccessTokenRow 全量保存访问令牌记录
func saveAccessTokenRow(ctx context.Context, token *AccessToken) error {
return getDB(ctx).Save(token).Error
}
// deleteAccessTokenRow 删除访问令牌记录
func deleteAccessTokenRow(ctx context.Context, token *AccessToken) error {
return getDB(ctx).Delete(token).Error
}